Sidebar

App-shell sidebar with collapsible width, context-driven open state, and composable Header/Content/Footer/Item parts. Provider-based so any descendant can toggle it.

Toggle the sidebar

Click the toggle to collapse or expand the sidebar.

Installation

pnpm
pnpm dlx @hex-core/cli add sidebar

API Reference

PropTypeDefaultDescription
open
booleanControlled open state — read from SidebarProvider
defaultOpen
booleantrueInitial open state (uncontrolled)
onOpenChange
functionCallback when open state flips: (open: boolean) => void
side
stringleftWhich edge the sidebar sits on: 'left' | 'right'

AI Guidance

When to use

Use for persistent app-shell navigation: admin dashboards, document editors, SaaS sidebars. The Provider pattern lets any descendant component toggle the sidebar (e.g. a topbar button on mobile).

When not to use

Don't use for mobile-first UX (use Sheet — sidebar collapses to zero-width but Sheet gives a native drawer feel). Don't use for marketing sites (no shell). Don't use for contextual menus (use DropdownMenu or NavigationMenu).

Common mistakes

  • Rendering Sidebar outside SidebarProvider — useSidebar throws
  • Forgetting that SidebarProvider is a flex container — main content must be its direct sibling
  • Using the wrong ordering for side='right' — SidebarProvider handles this via order-last
  • Overriding the width variant manually instead of toggling open state

Accessibility

Sidebar is an <aside> landmark (not a modal — no focus trap). When collapsed, the aside sets inert + aria-hidden so its children are removed from the tab order and the accessibility tree. SidebarTrigger exposes aria-expanded and a rotating aria-label (suppressed when asChild so the consumer's visible label/aria-label wins). SidebarItem uses aria-current='page' when active. Focus rings use the ring token.

Token budget: 900