Navbar

Organism
Topbars with a brand, navigation links, and an action button. Used as the primary app-level navigation.

Playground

Every control sets a real prop of NavbarProps. The JSX below updates as you go.
Canvas
Dashboard
Users
Settings
RC
Props
brand
string
Surface
pick one
active
number
0
actionLabel
string
JSX · NavbarProps
<Navbar brand="Canvas" active={0} actionLabel="Get started" />

Variants

5 examples from src/organisms/navbars/navbars.md, each rendered live from its own JSX.
Canvas
Dashboard
Users
Settings
Bordered
<Navbar bordered brand="Canvas" links={["Dashboard", "Users", "Settings"]} />
Canvas
Dashboard
Users
Settings
Floating
<Navbar floating brand="Canvas" links={["Dashboard", "Users", "Settings"]} />
Canvas
Dashboard
Users
Settings
Bare
A bare bar paints no surface and no hairline, so it sits clear on what is behind it. Pass it at the scroll edge, while nothing has scrolled under the bar, and drop it once content does: the bar's own surface then returns to keep its labels legible, as iOS's navigation bar and Material 3's top app bar do. A framed bar (bordered, floating) keeps its frame over bare.
<Navbar bare brand="Canvas" links={["Dashboard", "Users", "Settings"]} />
Catalog
App menu
An app with more destinations than a bar can hold (a component catalog, a settings tree) passes onMenu: the bar leads with a menu button at every width and the app opens its own navigation, such as a Drawer of grouped sections. It replaces links.
<Stateful initial={false}>
{(open, setOpen) => (
<View>
<Navbar bordered brand="Catalog" onMenu={() => setOpen(true)} />
<Drawer open={open} onOpenChange={setOpen} accessibilityLabel="Catalog menu">
<Column padLoose loose>
<Typography h3>Components</Typography>
<Button ghost onPress={() => setOpen(false)}>Button</Button>
<Button ghost onPress={() => setOpen(false)}>Card</Button>
</Column>
</Drawer>
</View>
)}
</Stateful>
RC
Console topbar
<Navbar
brandContent={<Icon layers />}
actions={<Button ghost small icon accessibilityLabel="Search" iconLeft={<Icon search size={16} />} />}
avatar="RC"
/>

Anatomy

Canvas
Dashboard
Users
Settings
RC
1
Bar
2
Brand
3
Links
4
Active link
5
Actions
Dimmed parts appear only in some states or variants.

Props

22 props on NavbarProps, grouped as they are declared in source. Required props are marked *.
Prop
Type
Default
Description
Props
15 props
brand
string
–
Brand or product name shown at the left, in a semibold face.
brandContent
ReactNode
–
A brand ELEMENT for the left cluster (a logo mark, a workspace switcher). It LEADS the cluster, so passing it beside brand renders the mark first and keeps the wordmark beside it; passing it alone makes the mark the whole brand. It takes the left cluster's own gap, so it needs no wrapper.
brandHref
string
–
Where the brand leads (an app's home, /). With it, or with onBrandPress, the brand lockup is one link: a real anchor on the web (an <a href>, so middle-click and modifier-click open it in a new tab), named by brand, with the kit's focus ring.
onBrandPress
(event: GestureResponderEvent) => void
–
Called when the brand is pressed; on the web a modifier-click on a brandHref stays the browser's.
brandDivider
boolean
false
Draw a short vertical separator between the brand and the links (the kit <Divider vertical inset strong />), as the hand-off's floating docs pill does. It shows only while both the brand and the links row are on the bar, so a collapsed bar or one without links never ends its brand on a stray rule.
links
string[]
–
Ordered navigation link labels rendered in the middle row. Omit it (or pass an empty array) for a bar with no middle nav: neither the links row nor the narrow menu button that stands in for it renders.
hrefs
string[]
–
Destinations for links, by index (parallel to it). A link with an href renders as a real anchor on the web (an <a href>, so middle-click, modifier-click and open-in-new-tab work); natively it is ignored. A plain click still selects the link and calls onSelect with the press event, so an app that routes on the client calls event.preventDefault() there; a modifier or middle click is left to the browser and selects nothing. Omit it (or an entry) for a link without a destination.
active
number
–
Index of the active link (CONTROLLED; its label reads in the foreground color). Omit for uncontrolled use.
defaultActive
number
–
Initial active link for uncontrolled use (a bare navbar moves the active link on press).
actions
ReactNode
–
Free-form trailing controls for the right cluster: a ghost search button, icon buttons, a notification dropdown, an account menu. They LEAD the cluster, ahead of the built-in actionLabel button and avatar, and take the cluster's own gap, so they need no wrapper. Keep them few and compact: the bar is a fixed height and the slot is rendered as given at every width.
actionLabel
string
–
Optional primary action; renders a <Button primary small> on the right.
onAction
() => void
–
Called when the action button is pressed.
avatar
string
–
Optional account initials/name; renders an <Avatar small> on the right.
onSelect
(index: number, event?: GestureResponderEvent) => void
–
Called when a nav link is pressed, with its index, and the press event when it came from the link itself (not from the narrow menu).
onMenu
() => void
–
The app's own navigation menu. When set, the bar leads with a menu button at every width and calls this on press, so the app can open navigation of its own (a Drawer of grouped sections). It replaces the links row and its narrow menu: pass one or the other.
Surface
pick one
3 props
bordered
boolean
false
floating
boolean
false
bare
boolean
false
No surface and no hairline: the bar sits clear on what is behind it. Pass it while nothing has scrolled under the bar (the scroll edge) and drop it once content does.
Density
pick one
4 props
compact
boolean
false
The tight bar: 44px with a 5px inset and 2px between items on the web (the docs pill).
scrolls
boolean
false
Keep every link at every width: the bar's content row scrolls sideways inside the bar (no scroll indicator) instead of folding the links into the narrow menu button. Pair it with floating and compact for the hand-off's docs pill.
testID
string
–
E2E hook forwarded to the root element.
style
StyleProp<ViewStyle>
–
Outer layout composition only (width/flex within a parent), never a restyle hook.

Accessibility and keyboard

Keyboard
Tab
Moves between links
Enter
Follows the link
Semantics
Roles
link
States
selected
ARIA on web
aria-current
Below the platform minimum, the touch area grows to 44 pt on iOS and 48 dp on Android without moving the layout.

Platform skins

The playground's props on each platform: same tree, native shapes, type and touch sizes.
RC
Web
control 10 · field 10 · card 16 · Instrument Sans
RC
iOS
capsule controls · field 8 · card 12 · SF Pro · 44 pt
RC
Android
Material 3 stadium · field 4 · card 12 · Roboto · 48 dp

Usage

<Navbar
brand="Canvas"
links={["Dashboard", "Users", "Settings"]}
actionLabel="New"
avatar="RC"
/>
The bar measures its own width: at and below the sm breakpoint (640) the links row automatically collapses into a menu button opening a dropdown of the same links (the active one checkmarked), so links never clip off a phone screen; active and onSelect keep their contract in both renderings. The menu button leads the bar, ahead of the logo and brand, where Material 3's top app bar puts its navigation icon. Pass scrolls to keep every link at every width instead: the bar's content row then pans sideways inside the bar, with no scroll indicator, and the links never fold into the menu. onMenu still replaces the links when both are passed.
On the web the bar is the v4 hand-off's: 56px tall with a 16px gutter, 32px capsule links in the interface face, the active one (and a hovered one) on the secondary fill. floating lifts it as a pill on the stronger hairline with the md shade. On iOS and Android the bar keeps the platform's own navigation bar and top app bar shape.
In glass mode the active link paints a control-layer pane (iOS keeps its inactive capsules and carries the brand fill as glass, web and Android carry their tinted tile), and the collapsed menu is Dropdown's dense-layer glass card under the hamburger. Solid mode keeps the skin's own active tile.

Tokens

Read from the playground render. Values follow the scheme and the ion hue.
--bls
--bw
--f-dp
--fd
--ft
--ion
--ion-fg
--ln
--sf3
--tx
--tx2

Related components