Sidebar
Grouped sidebar list of links or buttons with an active state.
Usage
svelte
<script lang="ts">
import { Sidebar, type SidebarSection } from "@milandekruijf/ui/svelte";
let active = $state("overview");
const sections: SidebarSection[] = [
{
label: "Getting started",
items: [
{ value: "overview", label: "Overview" },
{ value: "install", label: "Install" },
],
},
];
</script>
<Sidebar
{sections}
{active}
onSelect={(item) => (active = item.value)}
ariaLabel="Docs"
/>Examples
Grouped navigation
<script lang="ts">
import { css } from "@milandekruijf/pandacss/css";
import { Sidebar, type SidebarSection } from "@milandekruijf/ui/svelte";
let active = $state("overview");
const sections: SidebarSection[] = [
{
label: "Getting started",
items: [
{ value: "overview", label: "Overview" },
{ value: "install", label: "Install" },
],
},
{
label: "Components",
items: [],
groups: [
{
label: "Primitives",
items: [
{ value: "button", label: "Button" },
{ value: "badge", label: "Badge" },
],
},
],
},
];
const wrapClass = css({ maxW: "16rem", minW: 0 });
</script>
<div class={wrapClass}>
<Sidebar
{sections}
{active}
onSelect={(item) => (active = item.value)}
ariaLabel="Example sidebar"
/>
</div>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| sections | SidebarSection[] | — | Groups of items; a section can hold plain `items` and nested `groups` with their own headings. |
| active? | string | — | `value` of the current item; items without it render as inactive. |
| onSelect? | (item: SidebarItem) => void | — | Called for button items (no `href`); links navigate themselves. |
| ariaLabel | string | — | Accessible name for the sidebar landmark. |
| emptyLabel? | string | "No items" | Shown when a section has no matches. |
| class? | string | — | Extra classes merged on the root. |
`SidebarSection` is `{ label?, items, groups? }`; each item is `{ value, label, href? }` and each group is `{ label, value?, href?, items }` (a group heading links to its overview when `href` is set).