Bottom Nav
Mobile bottom navigation bar in two styles — a full-width dock and an iOS-style floating pill. Controlled or uncontrolled active state. Badge support (dot or count). LTR and RTL.
Installation
pnpm add @tessinaui/uiUsage
import { BottomNav } from "@tessinaui/ui";
const items = [
{ value: "home", label: "Home", icon: <Home className="size-5" /> },
{ value: "search", label: "Search", icon: <Search className="size-5" /> },
{ value: "profile", label: "Profile", icon: <User className="size-5" /> },
];
<BottomNav items={items} defaultValue="home" />Playground
Preview
Showcase
Preview
Types
| Type | Description |
|---|---|
default | Full-width dock pinned at the bottom of the screen. Dark background, items share equal width. |
floating | iOS-style translucent pill. Glass morphism (backdrop-blur) with a solid dark active-item pill. |
Props
BottomNav
| Prop | Type | Default | Description |
|---|---|---|---|
type | "default" | "floating" | "default" | Visual style of the navigation bar |
items | BottomNavItemDef[] | — | Nav items (3–5 recommended) |
value | string | — | Controlled active value |
defaultValue | string | First item value | Uncontrolled initial active value |
onValueChange | (value: string) => void | — | Called when the active item changes |
dir | "ltr" | "rtl" | "ltr" | Text direction |
className | string | — | Extra classes applied to the container |
BottomNavItemDef
| Field | Type | Description |
|---|---|---|
value | string | Unique identifier for the item |
label | string | Label text shown below the icon |
icon | React.ReactNode | Icon element — use a 20×20 Lucide icon |
badge | number | boolean | true → notification dot; number → count badge (capped at 99+); omit to hide |
Accessibility
- Container uses
role="tablist"andaria-label="Bottom navigation". - Each item uses
role="tab"andaria-selectedto reflect active state. - Badges use
aria-labeldescribing the notification count. - Full keyboard focus ring on every item via
focus-visibleutilities.