AppBar
Mobile top bar made of plain parts: a surface, a row of controls and an optional block for a large title.
Installation
npx axiom add app-barpnpm dlx axiom add app-baryarn dlx axiom add app-barbun x axiom add app-barAlso copies: text, title and their dependencies. Installs react-native-safe-area-context.
Colors come from appBar.default in the component tokens. The controls are yours: IconButton, Avatar, SearchBar or anything else.
Usage
import { AppBar } from "@/components/ui/app-bar";
<AppBar>
<AppBar.Row>
<IconButton
icon="arrow-left"
accessibilityLabel="Back"
onPress={goBack}
/>
<AppBar.Center>
<AppBar.Title>Inbox</AppBar.Title>
<AppBar.Subtitle>3 unread</AppBar.Subtitle>
</AppBar.Center>
<IconButton
icon="search"
accessibilityLabel="Search"
onPress={openSearch}
/>
</AppBar.Row>
</AppBar>;Every part is a plain View or text that renders its children where you write them. The bar doesn’t look for a title or sort its children: the row shows what you put in it, in that order. To change the structure, change what you write, not the bar.
| Part | What it is |
|---|---|
AppBar | The surface: background, top safe-area inset and an optional hairline. |
AppBar.Row | The 64pt row of controls. |
AppBar.Center | Fills the row between the controls. Empty, it pushes the controls after it to the end. |
AppBar.Expanded | The block under the row, for a medium or large title. |
AppBar.Title, AppBar.Subtitle | Text in the bar colors, at the small, medium or large size. |
Variants
Search
AppBar.Center holds anything, not only a title: here a search field between the navigation and the avatar.
<AppBar bordered>
<AppBar.Row>
<IconButton
icon="arrow-left"
accessibilityLabel="Back"
onPress={goBack}
/>
<AppBar.Center>
<SearchBar
value={query}
onChangeText={setQuery}
placeholder="Search product"
size="sm"
/>
</AppBar.Center>
<Avatar name="Ada Lovelace" size="sm" />
</AppBar.Row>
</AppBar>Small
The title and its subtitle sit in the row, after the navigation. Use it for most screens.
<AppBar bordered>
<AppBar.Row>
<IconButton
icon="arrow-left"
accessibilityLabel="Back"
onPress={goBack}
/>
<AppBar.Center>
<AppBar.Title>Headline</AppBar.Title>
<AppBar.Subtitle>Subtitle</AppBar.Subtitle>
</AppBar.Center>
<IconButton
icon="search"
accessibilityLabel="Search"
onPress={openSearch}
/>
<IconButton
icon="calendar"
accessibilityLabel="Pick a date"
onPress={pickDate}
/>
</AppBar.Row>
</AppBar>Without a control before it, give the center inset so the title lines up with the screen margin:
<AppBar>
<AppBar.Row>
<AppBar.Center inset>
<AppBar.Title>Settings</AppBar.Title>
</AppBar.Center>
</AppBar.Row>
</AppBar>Medium
The title moves to its own line under the row, in AppBar.Expanded, and can wrap to two lines. An empty AppBar.Center keeps the actions at the end of the row.
<AppBar bordered>
<AppBar.Row>
<IconButton
icon="arrow-left"
accessibilityLabel="Back"
onPress={goBack}
/>
<AppBar.Center />
<IconButton
icon="search"
accessibilityLabel="Search"
onPress={openSearch}
/>
</AppBar.Row>
<AppBar.Expanded>
<AppBar.Title size="medium">Headline</AppBar.Title>
<AppBar.Subtitle size="medium">Subtitle</AppBar.Subtitle>
</AppBar.Expanded>
</AppBar>Large
A larger title for the first screen of a section. To fold it into the row as the list scrolls, see Collapsible header.
<AppBar bordered>
<AppBar.Row>{/* Same row as Medium */}</AppBar.Row>
<AppBar.Expanded>
<AppBar.Title size="large">Headline</AppBar.Title>
<AppBar.Subtitle size="large">Subtitle</AppBar.Subtitle>
</AppBar.Expanded>
</AppBar>Props
AppBar
Takes every View prop.
| Prop | Type | Default | Description |
|---|---|---|---|
bordered | boolean | false | Draws a hairline under the bar. Useful when content can scroll behind it. |
safeArea | boolean | true | Adds the top safe-area inset. Set it to false when Scaffold already owns that inset. |
style | StyleProp<ViewStyle> | — | Overrides the surface, for example backgroundColor to match the screen. |
AppBar.Row, AppBar.Expanded
Take every View prop. The row is APP_BAR_HEIGHT (64pt) tall, with a small gap between its children. APP_BAR_HEIGHT is exported next to the bar.
AppBar.Center
Takes every View prop.
| Prop | Type | Default | Description |
|---|---|---|---|
inset | boolean | false | Lines the start up with the screen margin, for a row without a leading control. |
AppBar.Title, AppBar.Subtitle
Take every Title and Text prop, except variant.
| Prop | Type | Default | Description |
|---|---|---|---|
size | 'small' | 'medium' | 'large' | 'small' | small in the row, medium or large under it. |
numberOfLines | number | Title: 1 when small, 2 otherwise. Subtitle: 1 | Maximum lines before truncation. |
The title is announced as a heading.
Scroll behavior
The bar has no animation of its own. A screen that animates it wraps the parts in Animated.View and drives them from its scroll handler, so a static bar costs nothing and the animation stays readable in the screen that owns it:
- Collapsible header folds
AppBar.Expandedinto the row. - Scroll-aware AppBar fades in a surface layer and the row title.
- Hide-on-scroll moves the whole bar.