orn-ui
Organism

Screen

Requires <UIProvider> — Getting Started →

Installation

Install just this component (copies the source into your project, no npm dependency)

npx orn-ui add screen

Or install the whole package and import it

pnpm add orn-ui
import { Screen } from 'orn-ui/screen';
Depends on:core (theme + icons)

Usage

  • when to use — The root of every screen: it applies safe area, scroll and keyboard handling in one place.
  • edges — `['top','bottom']` by default. Drop `bottom` when a tab bar already covers it.
  • scrollable — Off when the content is a list — nesting a list inside a scroll breaks virtualization.
  • keyboardAvoiding — Off when the content already handles the keyboard (List, SearchList, Wizard): the two offsets add up.
Demo clip not recorded yet — see MEDIA.md

Variants

A typical screen — scrolls, respects the top safe area

<View style={{ height: 160, borderRadius: 12, overflow: 'hidden' }}>
  <Screen edges={['top']}>
    <View style={{ gap: 8 }}>
      <Subtitle>Recent activity</Subtitle>
      <Body>Invoice #4821 was paid.</Body>
      <Body>Invoice #4820 is due in 3 days.</Body>
      <Body>Invoice #4819 was paid.</Body>
    </View>
  </Screen>
</View>

scrollable={false} — for content that brings its own list

<View style={{ height: 80, borderRadius: 12, overflow: 'hidden' }}>
  <Screen scrollable={false} edges={[]}>
    <Body>Turn scrolling off so it doesn’t fight with a nested List or Wizard.</Body>
  </Screen>
</View>
Full demo source
const variants: VariantDef[] = [
  {
    label: 'A typical screen — scrolls, respects the top safe area',
    content: (
      <View style={{ height: 160, borderRadius: 12, overflow: 'hidden' }}>
        <Screen edges={['top']}>
          <View style={{ gap: 8 }}>
            <Subtitle>Recent activity</Subtitle>
            <Body>Invoice #4821 was paid.</Body>
            <Body>Invoice #4820 is due in 3 days.</Body>
            <Body>Invoice #4819 was paid.</Body>
          </View>
        </Screen>
      </View>
    ),
  },
  {
    label: 'scrollable={false} — for content that brings its own list',
    content: (
      <View style={{ height: 80, borderRadius: 12, overflow: 'hidden' }}>
        <Screen scrollable={false} edges={[]}>
          <Body>Turn scrolling off so it doesn’t fight with a nested List or Wizard.</Body>
        </Screen>
      </View>
    ),
  },
];
return <VariantList variants={variants} />;

Props

NameTypeDefaultDescription
style?ViewStyle
scrollable?booleantrue
contentContainerStyle?ViewStyle
edges?ScreenEdge[]['top', 'bottom']Which safe area insets to apply.
keyboardAvoiding?booleantrueOffsets the keyboard with a KeyboardAvoidingView. Set it to false when the content already brings its own scroller that handles the keyboard (Wizard, List, SearchList): both offsets add up and the focused field ends up pushed off screen.