Layout
Everything in the kit is a Box underneath. The layout components are thin,
named intentions on top of it — which is worth more than it sounds, because
<Group> says "these sit side by side with a gap" and a bare flexDirection
does not.
The decision tree
| You want | Use |
|---|---|
| A generic styled container | Box |
| Explicit flex control | Flex |
| Vertical rhythm | Stack |
| Horizontal row with gap | Group |
| A real grid with spans | Grid |
| Equal columns, responsive | SimpleGrid |
| Centred, max-width page body | Container |
| One thing dead centre | Center |
| Fixed aspect box | AspectRatio |
| A surface with padding and elevation | Paper |
| Deliberate empty space | Spacer |
Flex defaults differ from the web
<Box> {/* column */}
<Group> {/* row, gap, wraps */}
<Stack gap="$md">{/* column, gap */}Gap, not margins
Prefer gap on the parent to margins on children. It composes, it collapses
correctly when a child is conditional, and it is a token.
<Stack gap="$md">
<TextInput label="Email" />
{showPassword ? <PasswordInput label="Password" /> : null}
<Button>Continue</Button>
</Stack>Scrolling
Use ScrollArea, not a bare
ScrollView — it carries the kit's scrollbar chrome, keyboard scrolling, and the
reach callbacks (onReachEnd, onReachTop) that pagination hangs off.
For long lists, VirtualList windows
rows and keeps a mounted pool, which is what you want past a few hundred items.
Responsive layout
Every style prop takes breakpoint objects, and useMedia() gives you the same
information in JS:
<SimpleGrid cols={{ xxs: 1, sm: 2, lg: 3 }} gap="$md" />See Responsive.
Safe areas and the keyboard
KeyboardAvoidingView and KeyboardAwareScrollView are in the kit and handle the
native keyboard through the platform Keyboard API — no third-party controller is
needed or used.