The phone tab bar: a frosted floating pill whose selection marker slides between destinations. The third nav mode beside the desktop rail and the top navbar.
DefaultBadgedEmbedded
<BottomNav {items} active={route} onnavigate={(id) => go(id)} />Installation
pnpm add @chanrg/4uiImport the stylesheet once, at the root of your app:
import '@chanrg/4ui/styles.css';Usage
import { BottomNav } from '@chanrg/4ui';<BottomNav {items} active={route} onnavigate={(id) => go(id)} />Badged
A badge count draws attention to a destination and is announced as text.
<BottomNav items={[{ id: 'alerts', label: 'Alerts', icon: 'bell', badge: 3 }]} active="home" />API reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
items | BottomNavItem[] | [] | id, label, icon, optional href and badge count. |
active | string | null | null | Current destination id. |
phoneOnly | boolean | true | Hides above 480px, where the sidebar rail takes over. |
fixed | boolean | true | Pins to the bottom inset; false renders it in flow (used by these docs). |
onnavigate | (id, item) => void | — | Fires on tap; items without href never navigate on their own. |
CSS variables
| Variable | Description |
|---|---|
--4ui-surface | Primary component surface. |
--4ui-text | Primary foreground color. |
--4ui-border | Default control and panel border. |
--4ui-bottomnav-h | Bar height, excluding the safe-area inset. |
--4ui-bottomnav-offset | Gap under the bar, derived from the home-indicator inset. |
Accessibility
- A labelled nav landmark; the current destination carries aria-current="page".
- Badges are announced as text rather than signalled by colour alone.
- The frosted layer sits on a pseudo-element, so the bar never becomes the containing block for fixed children.