Pre-alphaThe registry and the CLI are not published yet.Roadmap

AppBar

Mobile top bar made of plain parts: a surface, a row of controls and an optional block for a large title.

Inbox3 unread
Maya ChenCan we move the review to 3?
09:42
Design teamNora shared a file.

4

Installation

npx axiom add app-bar
pnpm dlx axiom add app-bar
yarn dlx axiom add app-bar
bun x axiom add app-bar

Also 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.

PartWhat it is
AppBarThe surface: background, top safe-area inset and an optional hairline.
AppBar.RowThe 64pt row of controls.
AppBar.CenterFills the row between the controls. Empty, it pushes the controls after it to the end.
AppBar.ExpandedThe block under the row, for a medium or large title.
AppBar.Title, AppBar.SubtitleText in the bar colors, at the small, medium or large size.

Variants

AppBar.Center holds anything, not only a title: here a search field between the navigation and the avatar.

Search product
<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.

HeadlineSubtitle
<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.

HeadlineSubtitle
<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.

HeadlineSubtitle
<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.

PropTypeDefaultDescription
borderedbooleanfalseDraws a hairline under the bar. Useful when content can scroll behind it.
safeAreabooleantrueAdds the top safe-area inset. Set it to false when Scaffold already owns that inset.
styleStyleProp<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.

PropTypeDefaultDescription
insetbooleanfalseLines 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.

PropTypeDefaultDescription
size'small' | 'medium' | 'large''small'small in the row, medium or large under it.
numberOfLinesnumberTitle: 1 when small, 2 otherwise. Subtitle: 1Maximum 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: