{
  "title": "Sidebar",
  "description": "Collapsible side-panel navigation with compound API — Header, Content, Footer, Group, GroupLabel, Menu, MenuItem.",
  "url": "/docs/components/sidebar",
  "since": "1.8.0",
  "tags": [
    "navigation",
    "layout"
  ],
  "platform": "both",
  "source": "---\ntitle: Sidebar\ndescription: Collapsible side-panel navigation with compound API — Header, Content, Footer, Group, GroupLabel, Menu, MenuItem.\nsince: 1.8.0\ntags: [navigation, layout]\nplatform: both\ncategory: navigation\n---\n\nimport { BundleSize } from '@/components/bundle-size';\nimport { Preview } from '@/components/preview';\nimport { PropsTable } from '@/components/props-table';\n\n<BundleSize component=\"Sidebar\" />\n\n## At a glance\n\n- Compound API: `Sidebar`, `Sidebar.Header`, `Sidebar.Content`, `Sidebar.Footer`, `Sidebar.Group`, `Sidebar.GroupLabel`, `Sidebar.Menu`, `Sidebar.MenuItem`.\n- Web: fixed `<aside>` with `role=\"navigation\"`. Width transitions between 240 px (expanded) and 56 px (collapsed — icons only).\n- Native v1: always-visible `View`. Slide-in drawer behavior is a v2 follow-up.\n- Accessibility: `role=\"navigation\"` + `aria-label`. Active item gets `aria-current=\"page\"`. Collapsed label surfaced as `title` tooltip on web.\n\n## Preview\n\n<Preview name=\"sidebar-basic\" />\n\n## Open / collapsed state\n\n`collapsed` (controlled) + `onCollapsedChange` is the parent-driven shape.  \nUse `defaultCollapsed` for uncontrolled mode.\n\n```tsx\nimport { Sidebar } from '@nori-ui/core';\n\n// Uncontrolled — starts expanded.\n<Sidebar defaultCollapsed={false}>\n  {/* ... */}\n</Sidebar>\n\n// Controlled — parent owns state.\nconst [collapsed, setCollapsed] = useState(false);\n<Sidebar collapsed={collapsed} onCollapsedChange={setCollapsed}>\n  {/* ... */}\n</Sidebar>\n```\n\n## Anatomy\n\n| Subcomponent | Role |\n|---|---|\n| `Sidebar` | Root — owns collapsed state, wraps `<aside role=\"navigation\">` on web. |\n| `Sidebar.Header` | Top slot — logo, workspace switcher, etc. |\n| `Sidebar.Content` | Scrollable middle zone — holds Groups. |\n| `Sidebar.Footer` | Pinned bottom slot — user row, logout. |\n| `Sidebar.Group` | Logical section inside Content. |\n| `Sidebar.GroupLabel` | Section heading. Hidden when collapsed. |\n| `Sidebar.Menu` | Ordered list of MenuItem entries. |\n| `Sidebar.MenuItem` | Single tappable nav entry with optional icon and active state. |\n\n## Full example\n\n```tsx\nimport { Sidebar } from '@nori-ui/core';\n\n<Sidebar defaultCollapsed={false}>\n  <Sidebar.Header>\n    <Avatar src=\"...\" />\n    <Text>Acme Inc.</Text>\n  </Sidebar.Header>\n  <Sidebar.Content>\n    <Sidebar.Group>\n      <Sidebar.GroupLabel>Main</Sidebar.GroupLabel>\n      <Sidebar.Menu>\n        <Sidebar.MenuItem icon={<HomeIcon />} onPress={() => navigate('/')}>\n          Home\n        </Sidebar.MenuItem>\n        <Sidebar.MenuItem icon={<UsersIcon />} active>\n          Team\n        </Sidebar.MenuItem>\n      </Sidebar.Menu>\n    </Sidebar.Group>\n    <Sidebar.Group>\n      <Sidebar.GroupLabel>Settings</Sidebar.GroupLabel>\n      <Sidebar.Menu>\n        <Sidebar.MenuItem icon={<CogIcon />} onPress={() => navigate('/settings')}>\n          Preferences\n        </Sidebar.MenuItem>\n      </Sidebar.Menu>\n    </Sidebar.Group>\n  </Sidebar.Content>\n  <Sidebar.Footer>\n    <Button onPress={logout}>Logout</Button>\n  </Sidebar.Footer>\n</Sidebar>\n```\n\n## Collapsed mode (web)\n\nWhen `collapsed={true}` the sidebar narrows to 56 px. Labels are hidden; only icons remain visible. On web, the icon button receives a `title` attribute equal to the label string, which browsers surface as a native tooltip on hover.\n\n```tsx\n// Icons are required in collapsed mode for usability.\n<Sidebar.MenuItem icon={<HomeIcon />} onPress={goHome}>\n  Home\n</Sidebar.MenuItem>\n```\n\n## Variants\n\n| Variant | Description |\n|---|---|\n| `standard` (default) | Full-bleed panel attached to the screen edge. Right border separates it from content. |\n| `inset` | Standard with a subtle box-shadow instead of a border. |\n| `floating` | Has margin + rounded corners — visually floats above the page. |\n\n```tsx\n<Sidebar variant=\"floating\">\n  {/* ... */}\n</Sidebar>\n```\n\n## Side\n\nThe `side` prop controls which edge the sidebar attaches to. Defaults to `'left'`.\n\n```tsx\n<Sidebar side=\"right\">\n  {/* ... */}\n</Sidebar>\n```\n\n## Props\n\n### Sidebar\n\n<PropsTable component=\"Sidebar\" />\n\n### Sidebar.MenuItem\n\nA single tappable navigation row inside `Sidebar.Menu`. Accepts:\n\n- `children` — the item's text label. Hidden (visually) when the sidebar is collapsed; still read by screen readers.\n- `icon` — a React element rendered to the left of the label. Required in collapsed mode for usability.\n- `active` — marks the item as the current page. Applies an active style and sets `aria-current=\"page\"`.\n- `onPress` — press handler. The item is tappable when this is provided.\n- `disabled` — prevents interaction and dims the row.\n- `className` — custom styles for the row element.\n\n## v2 / deferred\n\n- **Native slide-in drawer** — on mobile, a real drawer with swipe-to-open/close gesture is the idiomatic pattern. v1 ships as an always-visible View.\n- **Collapsible-on-hover variant** — auto-collapse when the user leaves the sidebar; auto-expand on hover.\n"
}
