Sidebar
A hand-drawn sidebar that floats inside the page layout, styled with shadcn conventions. It is a set of parts rather than one component, so the shell is yours to compose.
Sidebar
A hand-drawn navigation panel that floats inside the page with an even gap on every side.
Floating panel with collapsible groups
Sketchbook
Sketchbook
Installation
npx shadcn@latest add https://sketchcn.chuwii.com/r/sidebar.jsonUsage
import {
Sidebar,
SidebarContent,
SidebarGroup,
SidebarGroupContent,
SidebarHeader,
SidebarInset,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
SidebarProvider,
SidebarTrigger,
} from "@/components/ui/sidebar";
export function AppShell({ children }: { children: React.ReactNode }) {
return (
<SidebarProvider>
<Sidebar>
<SidebarHeader>Sketchcn</SidebarHeader>
<SidebarContent>
<SidebarGroup>
<SidebarGroupContent>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton isActive>Home</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
</SidebarContent>
</Sidebar>
<SidebarInset>
<SidebarTrigger />
{children}
</SidebarInset>
</SidebarProvider>
);
}Props
Sidebar adds no props of its own. Size it with the variables SidebarProvider sets, overriding them on the provider.
| Variable | Default | Description |
|---|---|---|
--sidebar-width | 16rem | Width when expanded. 18rem inside the mobile sheet. |
--sidebar-width-icon | 3.5rem | Width once collapsible="icon" has shrunk it. |
--sidebar-gap | 0.75rem | Padding around the drawn panel, counted into the collapsed width. |
Parts
| Part | Description |
|---|---|
SidebarProvider | Owns the open state and the width variables. Wrap the whole shell in it. |
Sidebar | The drawn panel, on desktop or inside a sheet on mobile. |
SidebarInset | The main area beside the panel. |
SidebarHeader | Block pinned to the top of the panel. |
SidebarContent | Scrollable middle of the panel. |
SidebarFooter | Block pinned to the bottom of the panel. |
SidebarRail | Thin strip along the panel edge that toggles it. |
SidebarSeparator | Sketched divider sized to the panel padding. |
SidebarInput | Sidebar-sized Input. |
SidebarGroup | A labelled section of the panel. |
SidebarGroupLabel | Heading for a group, hidden once collapsed to icons. |
SidebarGroupAction | Control pinned to the right of the group label. |
SidebarGroupContent | Body of a group. |
SidebarMenu | The ul holding menu items. |
SidebarMenuItem | A single li. |
SidebarMenuButton | The clickable row, with size and variant scales. |
SidebarMenuAction | Secondary control pinned to the right of a row. |
SidebarMenuBadge | Count or status pinned to the right of a row. |
SidebarMenuSkeleton | Loading placeholder shaped like a row. |
SidebarMenuSub | Nested ul for child rows. |
SidebarMenuSubItem | A single nested li. |
SidebarMenuSubButton | The clickable nested row. |
SidebarTrigger | Button that toggles the panel from anywhere. |
Examples
App shell
Studio
Pinned
- 4
Canvas
import { Sidebar, SidebarContent, SidebarGroup, SidebarGroupContent, SidebarInset, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar";
export function AppShell({ children }: { children: React.ReactNode }) {
return (
<SidebarProvider>
<Sidebar>
<SidebarContent>
<SidebarGroup>
<SidebarGroupContent>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton isActive>
<span>Sketchbook</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
</SidebarContent>
</Sidebar>
<SidebarInset>
<SidebarTrigger className="m-3" />
{children}
</SidebarInset>
</SidebarProvider>
);
}Collapsible groups
Canvas
<SidebarGroup collapsible defaultOpen>
<SidebarGroupLabel>Workspace</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton>
<Star />
<span>Favourites</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>Roomier gap
Canvas
<SidebarProvider
style={{ "--sidebar-gap": "1.5rem", "--sidebar-width": "14rem" } as React.CSSProperties}
>
<Sidebar>{/* ... */}</Sidebar>
</SidebarProvider>Nested pages
<SidebarMenuItem collapsible defaultOpen>
<SidebarMenuButton>
<Folder />
<span>Projects</span>
</SidebarMenuButton>
<SidebarMenuSub>
<SidebarMenuSubItem>
<SidebarMenuSubButton href="#" isActive>
<span>Hand-drawn icons</span>
</SidebarMenuSubButton>
</SidebarMenuSubItem>
</SidebarMenuSub>
</SidebarMenuItem>Collapse to icons
Toggle the rail
Canvas
The icon rail is a desktop affordance. On narrow screens the sidebar opens as a sheet instead, so this preview only runs from the md breakpoint up.
<Sidebar collapsible="icon">
<SidebarContent>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton isActive tooltip="Overview">
<Home />
<span>Overview</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarContent>
</Sidebar>