Sidebar
FreeA collapsible navigation rail for an app's main sections.
pnpm dlx shadcn@latest add https://caliperui.site/r/sidebar.jsonWhen to use #
Use it for
- Product navigation with five to ten destinations.
- Layouts that need an icon-only collapsed state.
Skip it when
- A marketing site; use a header.
Installation #
terminal
pnpm dlx shadcn@latest add https://caliperui.site/r/sidebar.json
Adds its 2 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.
Usage #
This is the code behind the preview above.
example.tsx
import { FolderOpen, Home, Inbox, Settings } from "lucide-react" import { useState } from "react" import { Sidebar } from "@/components/ui/sidebar" export function ProjectSidebar() { const [item, setItem] = useState("home"); const [collapsed, setCollapsed] = useState(false); return ( <Sidebar items={[ { id: "home", label: "Home", icon: <Home aria-hidden="true" /> }, { id: "inbox", label: "Inbox", icon: <Inbox aria-hidden="true" /> }, { id: "files", label: "Files", icon: <FolderOpen aria-hidden="true" /> }, { id: "settings", label: "Settings", icon: <Settings aria-hidden="true" /> }, ]} value={item} onValueChange={setItem} collapsed={collapsed} onCollapsedChange={setCollapsed} /> ); }
API reference #
Sidebar
component
PropTypeDefault
labelstring"Project"
items *readonly SidebarItem[]—
valuestring—
defaultValuestring—
onValueChange((value: string) => void)—
collapsedboolean—
defaultCollapsedbooleanfalse
onCollapsedChange((collapsed: boolean) => void)—
classNamestring—
Accessibility #
It is built on native elements and keeps aria-label, aria-pressed, aria-hidden and aria-current in step with state.
No custom key handling; Tab and the native activation keys do the work.
Motion #
It declares no animation in its component source. Any transition comes from its stylesheet, which uses the duration tokens that collapse to instant under prefers-reduced-motion.