‹ components

BottomNav

draftv0.9.0·open in canvas

Mobile tab bar — 3–5 top-level destinations, labels always visible.

Installnpx shadcn add @cids/bottom-nav
Live demo

Motion · tap to replay

honors reduced-motion

150ms on color only. No indicator slide in v1 — tab switches are instant context changes, not transitions.

Brand chip remounts on tap · highlighted tokens are named in this component's doc · spring is budgeted to human feedback only.

import { BottomNav } from "@/design-system";

const [tab, setTab] = useState<"feed" | "markets" | "portfolio">("feed");

<BottomNav
  className="fixed inset-x-0 bottom-0"
  value={tab}
  onValueChange={setTab}
  items={[
    { value: "feed", label: "Feed", icon: "≋" },
    { value: "markets", label: "Markets", icon: "▤" },
    { value: "portfolio", label: "Portfolio", icon: "◎" },
  ]}
/>

Tokens · live

Resolves in the active theme — flip the toggle above to verify.

States · from doc

Parsed from the doc. Interact with the live demo for hover/active.

**Inactive**: `fg-muted`hover raises to `fg`.weight change keeps the cue non-color .

Mobile tab bar — 3–5 top-level destinations, labels always visible.

Anatomy

┌────────┬────────┬────────┐
│   ≋    │   ▤    │   ◎    │ ← icon (aria-hidden)
│  Feed  │Markets │Portfol.│ ← label (always visible)
└────────┴────────┴────────┘ ← border-t, safe-area pb
   active: brand ink + semibold

Props

PropTypeDefaultNotes
itemsBottomNavItem<T>[]—{ value, label, icon? }; equal-width columns.
valueT—Controlled active tab.
onValueChange(value: T) => void—
classNamestring—cn-merged (positioning lives here).

Motion

150ms on color only. No indicator slide in v1 — tab switches are

instant context changes, not transitions.

A11y

<nav> landmark; items are real buttons ≥48px tall; the active item

carries aria-current="page". Icons are decorative (aria-hidden) —

the visible label names the tab, so there are no icon-only mystery

tabs.

Self-contained: copy the folder into any Tailwind+React app, or use the install command above. Docs and this page render the same file on disk — they cannot drift.