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.

Overview

Revenue
$48,250 this week
Props
header
string
JSX · AppFrameProps
<AppFrame header={<Typography>Workspace</Typography>} />

Variants

3 examples from src/organisms/app-frame/app-frame.md, each rendered live from its own JSX.

Profile

Display name
Narrower measure
A form or a settings screen reads better at a narrower step; the page centers it.
<AppFrame header={<Navbar bordered brand="Acme" />}>
<Page md>
<Typography h2>Profile</Typography>
<Input label="Display name" defaultValue="Rachel Chen" />
<Button primary>Save</Button>
</Page>
</AppFrame>

Notifications

Email digest
A daily summary of your projects.
Pinned to the start
<AppFrame header={<Navbar bordered brand="Acme" />}>
<Page md start>
<Typography h2>Notifications</Typography>
<Switch defaultChecked description="A daily summary of your projects.">Email digest</Switch>
</Page>
</AppFrame>

Billing

Plan
Overlays in an enclosing viewport host
A screen whose modals must center in the visible viewport, not in the page's full scrolled content, wraps the page in a viewport-measured OverlayProvider and passes inheritOverlays, so the page is a plain content box and its overlays go to that host.
<OverlayProvider viewport>
<Page inheritOverlays>
<Typography h2>Billing</Typography>
<Select label="Plan" options={["Starter", "Team", "Enterprise"]} />
</Page>
</OverlayProvider>

Anatomy

Overview

Revenue
$48,250 this week
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 *.
Prop
Type
Default
Description
Props
3 props
header
ReactNode
–
The app's top chrome (a Navbar), rendered in a role="banner" region above the body.
children
ReactNode
–
The body, typically a router's Stack: it fills the height the header leaves.
testID
string
–
E2E hook forwarded to the frame.

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.

Overview

Revenue
$48,250 this week
Web
control 10 · field 10 · card 16 · Instrument Sans

Overview

Revenue
$48,250 this week
iOS
capsule controls · field 8 · card 12 · SF Pro · 44 pt

Overview

Revenue
$48,250 this week
Android
Material 3 stadium · field 4 · card 12 · Roboto · 48 dp

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.
<AppFrame header={<Navbar bordered brand="Acme" links={["Overview", "Reports"]} />}>
<Page>
<Typography h2>Overview</Typography>
<Card title="Revenue" description="$48,250 this week" />
</Page>
</AppFrame>
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

Related components

Canvas v4.0.0 · component detail · props and examples read from bnannier/canvas
MIT licensed