Screen
The unit of routing — and the place where mobile-app primitives live
<Screen> is what each route renders. It's a fixed-position container with slots for app bars,
navigation bars, and safe-area aware status bars — the same vocabulary you'd use building a
native app.
Anatomy
Status Bar
App Bar
Navigation Bar
System Navigation Bar
- Status Bar
Top safe area. Reserves space for the notch and dynamic island.
statusBarHeightstatusBarColorhideStatusBar- App Bar
Top bar — set per-screen, or as a shared bar that stays mounted across transitions.
appBarsharedAppBar- Children
The screen body. Scrolls by default — disable it only when you bring your own scroll container.
contentScrollable- Navigation Bar
Bottom bar. Same per-screen and shared options as App Bar.
navigationBarsharedNavigationBar- System Navigation Bar
Bottom safe area. Reserves space for Android's system navigation bar.
systemNavigationBarHeightsystemNavigationBarColorhideSystemNavigationBar
Per-screen vs shared
App bar and navigation bar can be set in two ways. They mount at different times and behave differently across transitions.
appBar/navigationBar— the bar belongs to that one screen. It mounts and unmounts with the screen. Use this for headers and actions that change page-by-page.sharedAppBar/sharedNavigationBar— the bar persists across screens. It stays put during push and pop transitions, so it never re-animates. Use this for global UI like a bottom tab bar or a fixed header. Pass the same node from each screen and flemo bridges it through the transition.
Minimum
<Screen>
<h1>Hello</h1>
</Screen>The content area scrolls by default. Background is white unless you change it.
App bar and navigation bar
Two slots, two flavors each: per-screen (appBar, navigationBar) and shared
(sharedAppBar, sharedNavigationBar).
The shared variants stay mounted across screen transitions, so the bar doesn't re-animate every push. Use them for global UI like a bottom tab bar.
<Screen
appBar={<TopBar title="Inbox" />}
navigationBar={<BottomActions />}
sharedNavigationBar={<TabBar />}
>
<MailList />
</Screen>Safe areas
<Screen
statusBarHeight="env(safe-area-inset-top)"
statusBarColor="#000"
systemNavigationBarHeight="env(safe-area-inset-bottom)"
systemNavigationBarColor="#000"
>
…
</Screen>Pass hideStatusBar or hideSystemNavigationBar to collapse the area when you don't want it
reserved (e.g., a full-bleed media screen).
Background
<Screen backgroundColor="#0b0b0c">…</Screen>Defaults to "white". Any CSS color value works.
Disabling content scroll
If you're rendering your own scroll container, opt out of the built-in one:
<Screen contentScrollable={false}>
<CustomScrollArea />
</Screen>All Screen props
| Prop | Type | Default | Notes |
|---|---|---|---|
appBar | ReactNode | — | Per-screen top bar |
navigationBar | ReactNode | — | Per-screen bottom bar |
sharedAppBar | ReactNode | — | Top bar that survives transitions |
sharedNavigationBar | ReactNode | — | Bottom bar that survives transitions |
backgroundColor | string | "white" | CSS color |
statusBarHeight | string | — | CSS length, usually env(safe-area-inset-top) |
statusBarColor | string | — | CSS color |
hideStatusBar | boolean | false | Don't reserve the top safe area |
systemNavigationBarHeight | string | — | CSS length, usually env(safe-area-inset-bottom) |
systemNavigationBarColor | string | — | CSS color |
hideSystemNavigationBar | boolean | false | Don't reserve the bottom safe area |
contentScrollable | boolean | true | Whether the children area scrolls |
Shared-element morphs
When a thumbnail in a list should visually unfold into the hero image on the next screen,
reach for <LayoutScreen> — a <Screen> replacement from @flemo/react-layout that pairs elements
across the navigation via motion's layout engine. See the dedicated
LayoutScreen page for the full walkthrough.