Bottom Nav
betaA tab bar for phones: the app's top destinations along the bottom of the screen, icon over label, the current one lit, with badges.
- Navigation
- 1 file
- 2 npm packages
- Accessibility notes
Loading the example…
pnpm dlx @dowel-ui/cli add bottom-navnpm packages installed: class-variance-authority, radix-ui.
import { BottomNav } from "@/components/ui/bottom-nav";<BottomNav>
| Prop | Type | Default |
|---|---|---|
hideFrom | "md" | "lg" | "never" | "md" |
labelNames the navigation for screen readers. Default "Primary". | string | "Primary" |
position | "fixed" | "static" | "fixed" |
Plus every attribute of <nav>.
<BottomNavItem>
| Prop | Type | Default |
|---|---|---|
icon (required)The icon. Decorative: the label names the destination. | ReactNode | — |
label (required)The visible label. Keep it to a word. | string | — |
activeThis is the current page. Sets aria-current="page". | boolean | false |
badgeA count or a dot on the icon: a number, or true for a dot. | number | boolean | — |
badgeLabelWhat the badge means, spoken after the label, e.g. "unread". Default "new". | string | "new" |
asChildRender your router's link component instead of an <a>. | boolean | false |
Plus every attribute of <a>.
A labelled nav landmark of links. Every item has a visible text label — icons alone are guesswork — and the icon is decorative. The current page is marked aria-current="page", not by colour alone. A badge's count is spoken after the label ("Inbox, 3 new"). Targets fill the bar's height, well over the 24px minimum. It clears the home indicator with safe-area padding; give the page bottom padding so it hides nothing.
8/8
checks passed
- Tested — passes
- axe assertion — passes
- Keyboard tested — does not apply
- Storybook examples — passes
- Accessibility documented — passes
- Semantic tokens only — passes
- Motion from tokens — passes
- className merged — passes
- Visible focus — does not apply
- No fixed widths — passes