TabBar

Organism
Bottom app navigation: a row of equal-width destinations, each an icon over a short label, with exactly one active. The mobile idiom (the iOS 26 floating tab bar / Material 3 navigation bar), rendered through the glass functional layer.

Playground

Every control sets a real prop of TabBarProps. The JSX below updates as you go.
Props
active
one of
JSX · TabBarProps
<TabBar active="home" />

Variants

1 examples from src/organisms/tab-bar/tab-bar.md, each rendered live from its own JSX.
Controlled
<Stateful initial="home">
{(active, setActive) => (
<TabBar
active={active}
onSelect={setActive}
items={[
{ key: "home", label: "Home", icon: (active) => <Icon home size={19} primary={active} muted={!active} /> },
{ key: "search", label: "Search", icon: (active) => <Icon search size={19} primary={active} muted={!active} /> },
{ key: "profile", label: "Profile", icon: (active) => <Icon user size={19} primary={active} muted={!active} /> }
]}
/>
)}
</Stateful>

Anatomy

1
Bar
2
Item
3
Active indicator
4
Label
Dimmed parts appear only in some states or variants.

Props

7 props on TabBarProps, grouped as they are declared in source. Required props are marked *.
Prop
Type
Default
Description
Props
7 props
items *
TabBarItem[]
–
active
string
–
The active item's key; omit for uncontrolled use.
defaultActive
string
–
Initial active key for uncontrolled use (defaults to the first item's key).
onSelect
(key: string) => void
–
Called with the pressed destination's key (both modes).
testID
string
–
E2E hook forwarded to the tablist row.
bottomInset
number
0
Safe-area bottom inset, e.g. insets.bottom. It is added BELOW the bar's own symmetric vertical padding (not in place of it), so the bar clears the home indicator without making the bottom margin heavier than the top. Defaults to 0 (web desktop / no inset).
style
StyleProp<ViewStyle>
–
Outer layout composition only. Use bottomInset for the safe area.

Accessibility and keyboard

Keyboard
ArrowLeft
ArrowRight
Moves between tabs
Home
End
First · last tab
Enter
Space
Activates the focused tab
Tab
Leaves for the panel
Semantics
Roles
tab
tablist
States
selected
ARIA on web
aria-selected
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.
Web
control 10 · field 10 · card 16 · Instrument Sans
iOS
capsule controls · field 8 · card 12 · SF Pro · 44 pt
Android
Material 3 stadium · field 4 · card 12 · Roboto · 48 dp

Usage

<TabBar
items={[
{ key: "home", label: "Home", icon: (active) => <Icon home size={19} primary={active} muted={!active} /> },
{ key: "search", label: "Search", icon: (active) => <Icon search size={19} primary={active} muted={!active} /> },
{ key: "profile", label: "Profile", icon: (active) => <Icon user size={19} primary={active} muted={!active} /> }
]}
/>
iOS and web share the iOS 26 anatomy: a 62 px capsule that floats above the content (which scrolls beneath it), inset from the sides, with the safe-area inset kept under the capsule, and the selected destination washed in the accent as a capsule covering its whole cell. Android docks the Material 3 bar full-bleed, 80 tall under a hairline, with its 64 by 32 icon pill. In glass mode the selection is a control-layer pane on the active destination: the cell capsule on iOS and web, the icon pill on Android. Solid mode retains the ordinary platform surface.

Tokens

Read from the playground render. Values follow the scheme and the ion hue.
--bf
--fd
--ft
--gl
--ion-soft
--ion-tx
--ln2
--sh-lg
--tx2

Related components