Sidebar
Basic composition
Provider → Root (panel) + Inset (main area). Rail is a narrow clickable strip on the inner edge of the panel (desktop) — it appears in the collapsed state and expands the panel; the example uses defaultCollapsed so the Rail is visible. Icons in MenuIcon: a uniform h-8 w-8 wrapper + SVG h-5 w-5. In the header Sidebar.HeaderTitle hides "Application" when collapsed (md:sr-only); Sidebar.Header centers the row when collapsed (md:justify-center).
Rail at the right edge of the collapsed panel or the trigger expands the navigation.import { Sidebar } from "~/components/ui/base/sidebar";
<Sidebar.Provider defaultCollapsed class="min-h-[28rem] overflow-hidden rounded-xl border border-separator-opaque">
<Sidebar.Root>
<Sidebar.Rail />
<Sidebar.Header class="flex flex-row items-center gap-2 border-b p-3">
<span class="flex h-8 w-8 shrink-0 items-center justify-center rounded-md bg-fill-accent/20 text-label">
<svg viewBox="0 0 24 24" class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<rect x="3" y="3" width="7" height="7" rx="1.5" />
<rect x="14" y="3" width="7" height="7" rx="1.5" />
<rect x="3" y="14" width="7" height="7" rx="1.5" />
<rect x="14" y="14" width="7" height="7" rx="1.5" />
</svg>
</span>
<Sidebar.HeaderTitle>Application</Sidebar.HeaderTitle>
</Sidebar.Header>
<Sidebar.Content>
<Sidebar.Group>
<Sidebar.GroupLabel>Menu</Sidebar.GroupLabel>
<Sidebar.GroupContent>
<Sidebar.Menu>
<Sidebar.MenuItem>
<Sidebar.MenuButton active>
<Sidebar.MenuIcon>
<span class="flex h-8 w-8 shrink-0 items-center justify-center text-label [&_svg]:h-5 [&_svg]:w-5">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" />
<path d="M9 22V12h6v10" />
</svg>
</span>
</Sidebar.MenuIcon>
<Sidebar.MenuLabel>Overview</Sidebar.MenuLabel>
</Sidebar.MenuButton>
</Sidebar.MenuItem>
<Sidebar.MenuItem>
<Sidebar.MenuButton>
<Sidebar.MenuIcon>
<span class="flex h-8 w-8 shrink-0 items-center justify-center text-label [&_svg]:h-5 [&_svg]:w-5">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z" />
</svg>
</span>
</Sidebar.MenuIcon>
<Sidebar.MenuLabel>Projects</Sidebar.MenuLabel>
</Sidebar.MenuButton>
</Sidebar.MenuItem>
</Sidebar.Menu>
</Sidebar.GroupContent>
</Sidebar.Group>
</Sidebar.Content>
</Sidebar.Root>
<Sidebar.Inset>
<header class="flex items-center gap-2 border-b p-3">
<Sidebar.Trigger aria-label="Panel">☰</Sidebar.Trigger>
<span class="text-callout font-medium text-label">Main content</span>
</header>
<div class="p-4 text-body text-secondary-label">
Clicking <code class="rounded bg-fill-secondary/40 px-1 py-0.5 text-caption-1">Rail</code> at the right edge of the collapsed panel or the trigger expands the navigation.
</div>
</Sidebar.Inset>
</Sidebar.Provider>
Default collapsed state
The defaultCollapsed prop on Provider — useful for narrow panels with icons; labels in GroupLabel are hidden on desktop in collapsed mode ( sr-only).
import { Sidebar } from "~/components/ui/base/sidebar";
<Sidebar.Provider defaultCollapsed class="min-h-[28rem] overflow-hidden rounded-xl border border-separator-opaque">
<Sidebar.Root>
<Sidebar.Rail />
<Sidebar.Header class="flex flex-row items-center gap-2 border-b p-3">
<span class="flex h-8 w-8 shrink-0 items-center justify-center rounded-md bg-fill-accent/20 text-label">
<svg viewBox="0 0 24 24" class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<rect x="3" y="3" width="7" height="7" rx="1.5" />
<rect x="14" y="3" width="7" height="7" rx="1.5" />
<rect x="3" y="14" width="7" height="7" rx="1.5" />
<rect x="14" y="14" width="7" height="7" rx="1.5" />
</svg>
</span>
<Sidebar.HeaderTitle>Application</Sidebar.HeaderTitle>
</Sidebar.Header>
<Sidebar.Content>
<Sidebar.Group>
<Sidebar.GroupLabel>Menu</Sidebar.GroupLabel>
<Sidebar.GroupContent>
<Sidebar.Menu>
<Sidebar.MenuItem>
<Sidebar.MenuButton active>
<Sidebar.MenuIcon>
<span class="text-base leading-none">◉</span>
</Sidebar.MenuIcon>
<Sidebar.MenuLabel>Overview</Sidebar.MenuLabel>
</Sidebar.MenuButton>
</Sidebar.MenuItem>
<Sidebar.MenuItem>
<Sidebar.MenuButton>
<Sidebar.MenuIcon>
<span class="text-base leading-none">◇</span>
</Sidebar.MenuIcon>
<Sidebar.MenuLabel>Projects</Sidebar.MenuLabel>
</Sidebar.MenuButton>
</Sidebar.MenuItem>
<Sidebar.MenuItem>
<Sidebar.MenuButton>
<Sidebar.MenuIcon>
<span class="text-base leading-none">▤</span>
</Sidebar.MenuIcon>
<Sidebar.MenuLabel>Documents</Sidebar.MenuLabel>
</Sidebar.MenuButton>
</Sidebar.MenuItem>
<Sidebar.MenuItem>
<Sidebar.MenuButton>
<Sidebar.MenuIcon>
<span class="text-base leading-none">⚙</span>
</Sidebar.MenuIcon>
<Sidebar.MenuLabel>Settings</Sidebar.MenuLabel>
</Sidebar.MenuButton>
</Sidebar.MenuItem>
</Sidebar.Menu>
</Sidebar.GroupContent>
</Sidebar.Group>
</Sidebar.Content>
</Sidebar.Root>
<Sidebar.Inset>
<header class="flex items-center gap-2 border-b p-3">
<Sidebar.Trigger aria-label="Panel">☰</Sidebar.Trigger>
<span class="text-callout font-medium text-label">Main content</span>
</header>
<div class="p-4 text-body text-secondary-label">
In collapsed mode the icons stay visible; the item and group labels are for screen readers (`sr-only`), and after expanding they appear next to the icons.
</div>
</Sidebar.Inset>
</Sidebar.Provider>
MenuIcon + MenuLabel + MenuAction
Sidebar.MenuIcon / Sidebar.MenuLabel — see above. Inline dropdown menu: DropdownMenu.Root + DropdownMenu.Trigger variant="icon" (dots). Sidebar.Trigger in Inset toggles the collapsed panel on desktop — a "collapse sidebar" icon (arrow into the panel). In DropdownMenu.Item you can insert an icon + text (text-label on the SVG).
DropdownMenu on the item; in the header a Sidebar.Trigger with an icon to toggle the panel width (desktop).import { DropdownMenu } from "~/components/ui/base/dropdown-menu";
import { Sidebar } from "~/components/ui/base/sidebar";
<Sidebar.Provider class="min-h-[28rem] overflow-hidden rounded-xl border border-separator-opaque">
<Sidebar.Root>
<Sidebar.Rail />
<Sidebar.Content>
<Sidebar.Menu>
<Sidebar.MenuItem>
<Sidebar.MenuButton>
<Sidebar.MenuIcon>
<span class="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-fill-accent/25 text-caption-1 font-semibold text-label">
AS
</span>
</Sidebar.MenuIcon>
<Sidebar.MenuLabel>Anna Smith</Sidebar.MenuLabel>
</Sidebar.MenuButton>
<DropdownMenu.Root gutter={4} class="absolute right-1 top-1.5 z-20 inline-block md:[aside[data-collapsed]_&]:hidden">
<DropdownMenu.Trigger aria-label="Contact actions" data-q-sidebar-menu-action="">
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" class="opacity-90">
<circle cx="12" cy="6" r="1.75" />
<circle cx="12" cy="12" r="1.75" />
<circle cx="12" cy="18" r="1.75" />
</svg>
</DropdownMenu.Trigger>
<DropdownMenu.Popover>
<DropdownMenu.Item>
<svg class="h-4 w-4 shrink-0 text-label" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z" />
<path d="m22 6-10 7L2 6" />
</svg>
Message
</DropdownMenu.Item>
<DropdownMenu.Item>
<svg class="h-4 w-4 shrink-0 text-label" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M12 20h9M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z" />
</svg>
Edit
</DropdownMenu.Item>
<DropdownMenu.Separator />
<DropdownMenu.Item>
<svg class="h-4 w-4 shrink-0 text-red-500" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M3 6h18M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
</svg>
Remove
</DropdownMenu.Item>
</DropdownMenu.Popover>
</DropdownMenu.Root>
</Sidebar.MenuItem>
<Sidebar.MenuItem>
<Sidebar.MenuButton>
<Sidebar.MenuIcon>
<span class="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-fill-secondary/40 text-caption-1 font-semibold text-label">
MJ
</span>
</Sidebar.MenuIcon>
<Sidebar.MenuLabel>Mark Johnson</Sidebar.MenuLabel>
</Sidebar.MenuButton>
<DropdownMenu.Root gutter={4} class="absolute right-1 top-1.5 z-20 inline-block md:[aside[data-collapsed]_&]:hidden">
<DropdownMenu.Trigger aria-label="Contact actions" data-q-sidebar-menu-action="">
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" class="opacity-90">
<circle cx="12" cy="6" r="1.75" />
<circle cx="12" cy="12" r="1.75" />
<circle cx="12" cy="18" r="1.75" />
</svg>
</DropdownMenu.Trigger>
<DropdownMenu.Popover>
<DropdownMenu.Item>
<svg class="h-4 w-4 shrink-0 text-label" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z" />
<path d="m22 6-10 7L2 6" />
</svg>
Message
</DropdownMenu.Item>
<DropdownMenu.Item>
<svg class="h-4 w-4 shrink-0 text-label" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M12 20h9M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z" />
</svg>
Edit
</DropdownMenu.Item>
<DropdownMenu.Separator />
<DropdownMenu.Item>
<svg class="h-4 w-4 shrink-0 text-red-500" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M3 6h18M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
</svg>
Remove
</DropdownMenu.Item>
</DropdownMenu.Popover>
</DropdownMenu.Root>
</Sidebar.MenuItem>
</Sidebar.Menu>
</Sidebar.Content>
</Sidebar.Root>
<Sidebar.Inset>
<header class="flex items-center gap-2 border-b p-3">
<Sidebar.Trigger aria-label="Collapse or expand the sidebar">
<svg class="h-5 w-5 shrink-0 text-label" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="m11 17-5-5 5-5" />
<path d="m18 17-5-5 5-5" />
</svg>
</Sidebar.Trigger>
<span class="text-callout font-medium text-label">Main content</span>
</header>
<div class="p-4 text-body text-secondary-label">
Both rows have the same <code class="rounded bg-fill-secondary/40 px-1 py-0.5 text-caption-1">DropdownMenu</code> on the item; in the header a <code class="rounded bg-fill-secondary/40 px-1 py-0.5 text-caption-1">Sidebar.Trigger</code> with an icon to toggle the panel width (desktop).
</div>
</Sidebar.Inset>
</Sidebar.Provider>
Collapsed panel: icons or abbreviation
Without Sidebar.MenuIcon add the abbrevSource prop to Sidebar.MenuLabel, or use Sidebar.MenuButton with itemLabel (abbreviation in a rounded-md avatar).
import { Sidebar } from "~/components/ui/base/sidebar";
<Sidebar.Provider defaultCollapsed class="min-h-[28rem] overflow-hidden rounded-xl border border-separator-opaque">
<Sidebar.Root>
<Sidebar.Rail />
<Sidebar.Content>
<Sidebar.Menu>
<Sidebar.MenuItem>
<Sidebar.MenuButton>
<Sidebar.MenuIcon>
<span class="flex h-8 w-8 shrink-0 items-center justify-center rounded-md bg-fill-secondary/30 text-caption-1 font-medium text-label">
P
</span>
</Sidebar.MenuIcon>
<Sidebar.MenuLabel>Overview</Sidebar.MenuLabel>
</Sidebar.MenuButton>
</Sidebar.MenuItem>
<Sidebar.MenuItem>
<Sidebar.MenuButton>
<Sidebar.MenuLabel abbrevSource="Document management">Document management</Sidebar.MenuLabel>
</Sidebar.MenuButton>
</Sidebar.MenuItem>
<Sidebar.MenuItem>
<Sidebar.MenuButton itemLabel="Account settings" />
</Sidebar.MenuItem>
</Sidebar.Menu>
</Sidebar.Content>
</Sidebar.Root>
<Sidebar.Inset>
<header class="flex items-center gap-2 border-b p-3">
<Sidebar.Trigger aria-label="Toggle panel">☰</Sidebar.Trigger>
<span class="text-callout font-medium text-label">Expand with the trigger — abbreviations vs. full names</span>
</header>
<div class="p-4 text-body text-secondary-label">
In collapsed state: a custom icon, an abbreviation from `abbrevSource`, or one generated from `itemLabel`.
</div>
</Sidebar.Inset>
</Sidebar.Provider>
Metadata
Source: meta.generated.json (see npm run generate)
File base/sidebar/meta.generated.json not found or path not allowed.