Sidebar

uistable

Sidebar — from shadcn/ui (radix-nova style).

npx shadcn add @krawma/sidebar

npm: class-variance-authority@^0.7.1, lucide-react@^1.22.0, radix-ui@^1.6.1 · registry: @krawma/button, @krawma/input, @krawma/separator, @krawma/sheet, @krawma/skeleton, @krawma/tooltip, @krawma/use-mobile, @krawma/utils

Preview

Content area
Variants
defaultoutline
Sizes
defaultsmlg
States
expandedcollapsedmobile-openhoverfocus-visibleactive
Keyboard
EnterSpaceEscape
Depends on
utilsbuttoninputseparatorsheetskeletontooltipuse-mobile

Purpose

The app-shell navigation region: a collapsible left/right rail composing menu groups, items, and actions. This is a block, not a leaf primitive — it brings its own layout, state, and responsive behavior. Use it for primary app navigation; for transient side content use sheet directly.

Anatomy

SidebarProvider (owns open/collapsed state; wrap the app) › SidebarSidebarHeader / SidebarContent (SidebarGroupSidebarGroupLabel, SidebarMenuSidebarMenuItemSidebarMenuButton [+ SidebarMenuAction, SidebarMenuBadge, SidebarMenuSub]) / SidebarFooter, plus SidebarTrigger, SidebarRail, and SidebarInset (the main content region). useSidebar() exposes state.

Style

  • The variant/size apply to SidebarMenuButton: variant default | outline; size default | sm | lg (default/default). All colors use the --sidebar-* tokens.
  • Collapsible modes are driven by data-collapsible (icon / offcanvas); styling reacts to group-data-[collapsible=…].

Behavior & functionality

  • SidebarProvider controls expanded/collapsed; SidebarTrigger toggles it; state persists (cookie) and exposes useSidebar().
  • Responsive: below the mobile breakpoint (via use-mobile) the sidebar renders as an off-canvas Sheet — the mobile-first collapse rule in PRINCIPLES.md §4.

Accessibility

  • SidebarMenuButtons are buttons/links — operable with Enter/Space, visible focus-visible, and data-active for the current item.
  • The mobile Sheet presentation traps focus and closes on Escape (inherits sheet's dialog semantics).
  • Icon-collapsed items expose their label via tooltip.

Do / Don't

  • ✅ Wrap the app in SidebarProvider and put page content in SidebarInset.
  • ✅ Use SidebarMenuButton isActive/data-active for the current route.
  • ❌ Don't hand-build a nav rail from raw divs — compose these parts.
  • ❌ Don't nest a second SidebarProvider.