Sidebar
ImplementedVertical navigation sidebar with grouped items, active-state indicator (aria-current), and a built-in mobile drawer (portal + scrim + focus trap + Escape + scroll lock). Persistent at >= breakpoint; overlay drawer below it. Real implementation; the organisms/sidebar stories twin was removed per ADR-035.
components/molecules/Sidebar/Sidebar.tsxVertical navigation panel with grouped items.
Sidebar
molecules
Renders a sticky vertical nav with grouped items, active-item accents, optional badges, and expandable sub-items. A collapsible mode swaps to a mobile drawer below the configured breakpoint.
Usage
Pass a logo node and an ordered groups array. Item accents attach to stable item positions (ADR-031 §3) — never cycle them over dynamic collections. Set collapsible to get the toggle button and mobile drawer.
For generic controlled side panels see Drawer; centered dialogs see Modal; ⌘K palettes see CommandMenu.
import { Sidebar } from '@epasslive/design-system'
<Sidebar
logo={<span>ePassLive</span>}
groups={[
{
id: 'main',
label: 'Main',
items: [
{ id: 'dashboard', label: 'Dashboard', active: true },
{ id: 'events', label: 'Events' },
],
},
]}
/>Props
logo*React.ReactNodeBrand node rendered above the nav groups.
groups*SidebarGroup[]Grouped navigation items (id, label, items).
activeKeystringId or href of the active item.
onItemClick(key: string) => voidFired when a leaf item is activated.
ariaLabelstring"Primary navigation"Accessible name for the nav landmark.
collapsiblebooleanEnables the toggle button and mobile drawer mode.
breakpoint"sm" | "md" | "lg" | "xl""lg"Min-width above which the static panel renders.
defaultOpenbooleanfalseInitial open state for the mobile drawer (persisted to localStorage).
storageKeystring"epasslive-sidebar"localStorage key for drawer open-state persistence. Cross-tab sync via the storage event.
toggleLabelstring"Open navigation"Accessible label for the hamburger toggle when the drawer is closed.
closeLabelstring"Close navigation"Accessible label for the hamburger toggle (open) and the drawer × button.
classNamestringAdditional CSS classes on the aside.
idstringStable id prefix for the panel and drawer.
Props
Sidebar
logoReact.ReactNode—Brand/logo node rendered at the top of the sidebar.
groupsSidebarGroup[]—Nav groups (id, label, items). SidebarItem supports icon, href, active, badge, nested children, and an ADR-031 accent for the active indicator bar.
activeKeystring—Highlights the item whose id equals this key; an explicit per-item `active` overrides the match.
onItemClick(key: string) => void—Called with the item's id when a nav item is activated.
ariaLabelstring'Primary navigation'Accessible name for the nav landmark.
classNamestring—Class applied to the root element.
idstring'sidebar'Root element id.
collapsiblebooleanfalseEnables the hamburger toggle + overlay drawer below `breakpoint`. Not a desktop icon-rail collapse.
breakpointSidebarBreakpoint'lg'Min-width at which the persistent sidebar replaces the mobile drawer ('lg' = 1024px).
defaultOpenbooleanfalseInitial open state of the mobile drawer.
storageKeystring'epasslive-sidebar'localStorage key persisting the drawer open state.
toggleLabelstring'Open navigation'Accessible label for the hamburger toggle button.
closeLabelstring'Close navigation'Accessible label for the overlay close button.
<Sidebar />Usage
Import
import { Sidebar } from "@epasslive/design-system"Example 1
Example 2
Example 3
const { isOpen, toggle } = useSidebarState('app-sidebar')Anti-patterns
— Do not hand-roll a fixed <aside> + hamburger — the molecule ships the mobile drawer with focus trap and aria-current
— Do not set per-item active:false while relying on activeKey — explicit false overrides the key match
— Do not use for transient overlay panels — Drawer and Modal are the overlay primitives