Skip to content

BottomNav

Open .md
Live preview

Loading example…

Phone navigation bar for Sidebar’s items. The first items fill the bar and the rest move behind a “More” button that opens a drawer. Place it as the last child of the page column inside AppShell: it sticks to the bottom of the viewport and hides itself once the shell is 900 px or wider, where the sidebar takes over. Without an AppShell it is always visible.

import { BottomNav } from "@jcsoftdev/ui/shell";

Single-component entry points tree-shake to just this component: @jcsoftdev/ui/shell/bottom-nav.

export const Default: Story = {
render: (args) => (
<Frame>
<AppShell className="min-h-full flex-col">
<main className="flex-1 p-4 text-ink">
<h1 className="font-bold text-lg">Agenda</h1>
</main>
<BottomNav {...args} moreFooter={<Button block>Sign out</Button>} />
</AppShell>
</Frame>
),
};

Source of the Storybook story.

Prop Type Default Description
items * readonly SidebarItem[] Same items as Sidebar (groups.flatMap((group) => group.items)). Order decides what overflows.
ariaLabel * string Accessible name of the bar landmark.
maxSlots number BOTTOM_NAV_MAX_SLOTS Slots in the bar including “More”. Defaults to 5; with fewer items than slots there is no “More”.
moreLabel string Text of the “More” button and the drawer title. Defaults to the localized “More”.
moreBadgeLabel ((count: number) => string) Accessible text of the total on “More”; defaults to the localized “{count} pending”.
badgeStyle "dot" | "count" "count" count (default) shows numeric badges as a count chip on the phone bar; dot keeps the small dot.
moreFooter ReactNode Pinned at the bottom of the “More” drawer, e.g. the account or a sign-out button.
renderLink BottomNavRenderLink defaultRenderLink Link renderer; defaults to a plain anchor.
className string
classNames Partial<Record<BottomNavPart, string>> Per-part classes merged with cn; consumer classes win. className still targets the root and is merged last.

* marks a required prop.

packages/ui/src/shell/bottom-nav/bottom-nav.tsx