Sidebar

Headless icon-rail collapsible sidebar primitive.

Features

  • Headless sidebar state

  • Icon-rail collapse

  • Controlled or uncontrolled

  • Trigger and rail toggles

  • Composable menu structure

  • shadcn-compatible data attributes

Installation

npm install @ariaui/sidebar

Examples

Sidebar is headless and icon-rail collapsible. Compose Sidebar.Root, Panel, Trigger, Rail, and menu parts, then style the rail from data-state and the sidebar width CSS variables.

Default

Default sidebar that collapses from full labels to compact icon buttons.

Preview

No preview output yet.

live.tsxReady

Framer Motion

Collapse the sidebar with Framer Motion — panel width and label fades stay in sync with open from Sidebar.useSidebar(), while menu buttons keep a fixed icon anchor so icons do not drift during the transition. Toggle the Home item to animate submenu open/close with height, opacity, and staggered item fades.

Sidebar collapse animated with Framer Motion on panel width and label fades, synced to Sidebar.useSidebar().

Preview

No preview output yet.

live.tsxReady

Anatomy

tsx
import * as Sidebar from "@ariaui/sidebar";

export default function Example() {
  return (
    <Sidebar.Root>
      <Sidebar.Panel>
        <Sidebar.Header />
        <Sidebar.Content>
          <Sidebar.Group>
            <Sidebar.GroupLabel />
            <Sidebar.GroupContent>
              <Sidebar.Menu>
                <Sidebar.MenuItem>
                  <Sidebar.MenuButton />
                </Sidebar.MenuItem>
              </Sidebar.Menu>
            </Sidebar.GroupContent>
          </Sidebar.Group>
        </Sidebar.Content>
      </Sidebar.Panel>
      <Sidebar.Rail />
      <Sidebar.Inset />
    </Sidebar.Root>
  );
}

API Reference

Root

State container for a headless icon-rail collapsible sidebar. Provides state and metadata to child parts.

PropTypeDefault
open
boolean
defaultOpen
booleantrue
onOpenChange
(open: boolean) => void
side
"left" | "right""left"
collapsible
"icon" | "none""icon"
keyboardShortcut
string | null"b"
AttributeValues
data-state"expanded" | "collapsed"
data-side"left" | "right"
data-collapsible"icon" | "none"

Parts

Panel

Sidebar panel host. Renders an aside by default and can slot props onto a custom host with asChild.

PropTypeDefault
asChild
booleanfalse
AttributeValues
idGenerated panel id used by Trigger
data-sidebar"sidebar"
data-state"expanded" | "collapsed"

Trigger

Button that toggles the sidebar expanded state.

PropTypeDefault
asChild
booleanfalse
AttributeValues
aria-controlsID of the Panel element
aria-expanded"true" when expanded
data-sidebar"trigger"
data-state"expanded" | "collapsed"

Rail

Thin hit target for toggling the sidebar from the panel edge.

AttributeValues
aria-label"Toggle Sidebar" by default
tabIndex-1 by default
data-sidebar"rail"

Header, Content, Footer, Group, Menu, SubMenu

Headless structural parts for composing sidebar sections, groups, menu items, badges, actions, and nested links.

AttributeValues
data-sidebarPart-specific identifier

Accessibility

Sidebar.Trigger exposes aria-expanded and aria-controls for the panel it toggles. Use clear visible labels or screen-reader-only labels for icon-only triggers and menu buttons.

The sidebar package does not assign landmark labels automatically. Add aria-label or aria-labelledby to Sidebar.Panel when the navigation region needs a name, and keep final menu item semantics appropriate for your app.

The default Ctrl+B / Meta+B shortcut can be disabled with keyboardShortcut={null} when it conflicts with application shortcuts.

Previous
Select