Sidebar
App navigation from data: header, groups (optionally foldable), badges and pinned footer entries. Collapses to an icon rail on a spring (⌘B / Ctrl+B) with labels kept for assistive tech; below md it is a left drawer.
npx @kznlabs/labsui add sidebarGuild admin
Overview
JDonlinePress ⌘B or the panel button to collapse the sidebar to an icon rail.
"use client";import { Home, Inbox, Settings } from "lucide-react";import { usePathname } from "next/navigation";import { Sidebar, SidebarLayout, SidebarTrigger,} from "@/components/ui/sidebar";const groups = [ { label: "Server", items: [ { label: "Overview", href: "/", icon: <Home /> }, { label: "Inbox", href: "/inbox", icon: <Inbox />, badge: 12 }, ], },];export function AdminLayout({ children }: { children: React.ReactNode }) { return ( <SidebarLayout className="h-dvh"> <Sidebar label="Admin" groups={groups} footer={[{ label: "Settings", href: "/settings", icon: <Settings /> }]} current={usePathname()} /> <main className="min-w-0 flex-1"> <SidebarTrigger /> {children} </main> </SidebarLayout> );}<Sidebar>
Navigation sidebar from data. Collapses to an icon rail on a spring; labels clip but stay in the a11y tree.
groups*SidebarGroup[]The navigation, top to bottom.
currentstringId of the current item: highlighted,
aria-current="page"on links.footerSidebarItem[]Entries pinned to the bottom, e.g. settings.
headerReactNodeTop slot, e.g. the workspace name.
labeldefault"Sidebar"stringAccessible name for the navigation landmark.
onSelect(id: string) => voidCalled with an item's id when it is picked (links too, e.g. for client routing).
| Prop | Type | Default |
|---|---|---|
groups*The navigation, top to bottom. | SidebarGroup[] | — |
currentId of the current item: highlighted, | string | — |
footerEntries pinned to the bottom, e.g. settings. | SidebarItem[] | — |
headerTop slot, e.g. the workspace name. | ReactNode | — |
labelAccessible name for the navigation landmark. | string | "Sidebar" |
onSelectCalled with an item's id when it is picked (links too, e.g. for client routing). | (id: string) => void | — |
<SidebarLayout>
Lays the sidebar and the page side by side and holds the rail state. Below md, the sidebar is a left drawer.
collapsedbooleanControlled rail state; pair with
onCollapsedChange.defaultCollapseddefaultfalsebooleanStart as the icon rail (uncontrolled).
onCollapsedChange(collapsed: boolean) => voidCalled from the trigger or the shortcut.
shortcutdefaulttruebooleanToggle with ⌘B / Ctrl+B (default: true). Ignored while typing in a field.
| Prop | Type | Default |
|---|---|---|
collapsedControlled rail state; pair with | boolean | — |
defaultCollapsedStart as the icon rail (uncontrolled). | boolean | false |
onCollapsedChangeCalled from the trigger or the shortcut. | (collapsed: boolean) => void | — |
shortcutToggle with ⌘B / Ctrl+B (default: true). Ignored while typing in a field. | boolean | true |
Also accepts every <div> prop.
<SidebarTrigger>
- type SidebarItem
- { id?: string; label: string; icon?: ReactNode; href?: string; badge?: ReactNode; }
- type SidebarGroup
- { label?: string; items: SidebarItem[]; collapsible?: boolean; defaultOpen?: boolean; }
* required. Every component also takes className.