# Sidebar

**Maturity:** experimental

A reusable single-selection navigation sidebar, preserving the visual language of liquidify-page's docs sidebar without depending on Fumadocs or a router.

## Import

```tsx
import { Sidebar } from "@liquidify/react/sidebar"
```

## Props

- `children`: `ReactNode`; default `undefined`. Navigation content and optional direct Header/Footer slots.
- `className`: `string | undefined`. Optional additional CSS class merged into the glass surface class. The supported per-instance customisation seam: override any `--lq-*` custom property from this class's CSS — the token cascade the engine reads (ADR-0004). No raw inline style is involved, so this stays ADR-0003 clean.
- `defaultValue`: `string | null | undefined`; default `null`. Initial uncontrolled selection.
- `dir`: `"auto" | "ltr" | "rtl" | undefined`; default `undefined`. Text direction, inherited from the host when omitted.
- `id`: `string | undefined`; default `undefined`. Native root id.
- `onChange`: `((value: string | null) => void) | undefined`; default `undefined`. Requests the next selection in either mode; unchanged requests are suppressed.
- `ref`: `Ref<HTMLElement> | undefined`. Forwarded ref to the rendered element — the component's native root (or the merged child element on a component that opts into {@link SlottableProps}). Generic over `E` (charter `docs/api-conventions.md` §4 rule 1, default `HTMLElement`) so a component with a polymorphic root (Link's navigation / action mode union, Text's `as`) can instantiate the concrete element per variant instead of leaving every consumer with a widened `Ref<HTMLElement>`. A component that does not narrow simply inherits the `HTMLElement` default — source-compatible with every pre-existing non-generic `extends ControlProps`.
- `tint`: `LiquidTintValue | undefined`. System-accent of the control — drawn from the RESTRICTED {@link LIQUID_COLORS} palette (the thirteen Apple system colours). **Orthogonal to a component's `variant`**: it recolours the accent the surface draws from (focus ring, tinted fill, selection) without changing its variant. Resolved via `data-tint` attribute selectors in CSS (tokens-only, ADR-0003).
- `value`: `string | null | undefined`; default `undefined`. Controlled selected identity; null explicitly means no selection.

## SwiftUI mapping

- `List(selection:)` → `value / defaultValue / onChange` (direct): string or null; controlled/uncontrolled selection
- `Row tag and label` → `Sidebar.Item value / children` (direct): Stable identity independent of visible text
- `Navigation destination` → `Sidebar.Item href` (direct): Native router-neutral anchor
- `Section header` → `Sidebar.Section label / children` (direct): Static grouping
- `DisclosureGroup isExpanded` → `Sidebar.Group expanded / defaultExpanded / onExpandedChange` (direct): Independent presentation state
- `Label image` → `icon` (direct): Optional decorative ReactNode
- `tint modifier` → `inherited tint` (direct): System accent by default
- `Header/footer content` → `Sidebar.Header / Sidebar.Footer` (direct): Optional composition slots
