AppFrame
Organism
The app's root frame and its scrolling screens. AppFrame mounts the safe-area context and the app-root overlay host, pads all four safe-area edges over the theme background, renders the app's top chrome in a banner region and lets its body (a router's Stack) fill the height left. Page is one screen inside it: the main region, a scroller with page gutters whose content is capped and centered at a step of the width scale.
Playground
Every control sets a real prop of AppFrameProps. The JSX below updates as you go.
Web
iOS
Android
JSX · AppFrameProps
Variants
3 examples from src/organisms/app-frame/app-frame.md, each rendered live from its own JSX.
Anatomy
1
Frame
2
Header
3
Body
Dimmed parts appear only in some states or variants.
Props
3 props on AppFrameProps, grouped as they are declared in source. Required props are marked *.
Accessibility and keyboard
Keyboard
Not focusable. It has no interaction of its own and takes the semantics of what it wraps.
Semantics
Roles
banner
main
From the docs
The header renders inside a role="banner" region and each Page is the screen's role="main" region, so assistive technology can jump between the app's chrome and its content. The page scroller keeps taps on its controls while the software keyboard is up (keyboardShouldPersistTaps="handled"), so a field's submit button works on the first tap. The frame adds no focus stops of its own.
Platform skins
The playground's props on each platform: same tree, native shapes, type and touch sizes.
Usage
The examples below render the frame inside the docs stage, where its parent is the stage instead of the window: the header, the body and the page measure behave as they do at an app's root, and the safe-area insets are 0.
Mount AppFrame once, inside ThemeProvider, at the root of the app. It is the app-root OverlayProvider itself, so menus, sheets and toasts render above the whole window and keep clear of the status bar, the Dynamic Island and the home indicator; do not mount a second root host around it. The safe-area context comes from react-native-safe-area-context when the app installs it (Expo Router apps already do); without it the frame keeps its layout and the insets resolve to 0.
Each screen renders a Page. Its content stacks at the loose rhythm and is capped at widest (1152) by default, the reading width of an app page on a desktop window; below the cap it fills the window between its gutters, which is all a phone is. A measure step (xxxs through page) narrows or widens it, start pins it to the leading edge, and fluid removes the cap. The page is also an overlay host of its own, so an anchored menu opened in it is framed by the page.
Tokens
Read from the playground render. Values follow the scheme and the ion hue.
--bg
--f-dp
--fd
--ft
--gl
--ln
--ln2
--sf2