Tessera UI

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/ui

Usage

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

TypeDescription
defaultFull-width dock pinned at the bottom of the screen. Dark background, items share equal width.
floatingiOS-style translucent pill. Glass morphism (backdrop-blur) with a solid dark active-item pill.

Props

BottomNav

PropTypeDefaultDescription
type"default" | "floating""default"Visual style of the navigation bar
itemsBottomNavItemDef[]Nav items (3–5 recommended)
valuestringControlled active value
defaultValuestringFirst item valueUncontrolled initial active value
onValueChange(value: string) => voidCalled when the active item changes
dir"ltr" | "rtl""ltr"Text direction
classNamestringExtra classes applied to the container

BottomNavItemDef

FieldTypeDescription
valuestringUnique identifier for the item
labelstringLabel text shown below the icon
iconReact.ReactNodeIcon element — use a 20×20 Lucide icon
badgenumber | booleantrue → notification dot; number → count badge (capped at 99+); omit to hide

Accessibility

  • Container uses role="tablist" and aria-label="Bottom navigation".
  • Each item uses role="tab" and aria-selected to reflect active state.
  • Badges use aria-label describing the notification count.
  • Full keyboard focus ring on every item via focus-visible utilities.

On this page