Sidebar
Vertical navigation sidebar. Groups of items can be labelled with an eyebrow heading. Each item can be a link (href) or a button (onItemClick). Active state is driven by activeId matching an item's id — the active item gets a filled accent background.
Examples
Loading examples…
API
From COMPONENTS.md.
Vertical navigation with labelled groups.
import { Sidebar, type NavGroupDef } from 'achery-ui'
const groups: NavGroupDef[] = [
{
label: 'Library',
items: [
{ id: '/recipes', label: 'All Recipes', glyph: 'scroll', count: 8 },
{ id: '/archive', label: 'Archived', href: '/archive' },
],
},
]
<Sidebar
groups={groups}
activeId={currentPath} // string
onItemClick={id => navigate(id)}
footer={<Node />}
collapsed={isCollapsed} // boolean — icon-only mode (52px)
onCollapsedChange={setCollapsed} // (boolean) => void — shows the collapse toggle (desktop mode only)
mobileOpen={menuOpen} // boolean — passing it (even false) switches to fixed overlay mode
onMobileOpenChange={setMenuOpen} // (boolean) => void — backdrop click and Escape fire this
/>
Items render as <a> when href is set, otherwise <button>.
Overlay mode (mobileOpen passed): pass it only on narrow viewports, with useIsDesktop() (see Hooks).
While open, Escape closes it, focus moves to the active item, and focus returns where it was (usually the
menu button) on close. While closed the panel is inert, so its links are out of the tab order.
mobileBreakpoint is deprecated and has no effect.
NavItemDef props: id, label, glyph?, icon?, iconColor?, href?, count?, countTone?: 'accent' | 'neutral'countTone='accent' renders the count badge in the current accent colour.icon — a custom leading ReactNode (monogram, avatar, bespoke mark) rendered in place of glyph; takes precedence over it. Keep it ~14–18px square.iconColor — tints the leading glyph via currentColor (any CSS colour). Ignored when a custom icon is supplied — colour that yourself.