Sidebar

A collapsible app sidebar with a workspace switcher, icon tabs, and nested navigation.

Home content
Installation
$Terminal
npx shadcn@latest add https://sdk-components.thesqd.com/r/app-sidebar.json
Usage
Give the shell a bounded height; the sidebar floats inside it and the content area fills the rest.
TSImport
import { Sidebar } from "@/components/blocks/app-sidebar";
TSExample
import { Sidebar } from "@/components/blocks/app-sidebar";

export function AppShell() {
  return (
    <div className="h-screen w-full">
      <Sidebar
        workspaces={[{ id: "default", name: "TheSquad", logoSrc: "/sqd-logo.png" }]}
        groups={[{ label: "Favorites", items: [{ name: "Design Engineering", href: "#" }] }]}
      >
        <main className="p-8">Content area</main>
      </Sidebar>
    </div>
  );
}
Composition
Slot layout of the sidebar shell.
Sidebar (shell — owns collapse, peek, resize)
├── children            (content area — reflows around the sidebar)
├── aside               (docked sidebar, slides off-frame when collapsed)
│   ├── Brand row       (workspaces + workspaceMenu dropdown, collapse button)
│   ├── Tabs            (variant="rounded" — tabs prop; active expands)
│   ├── Nav             (groups → items → children, actions on hover)
│   └── Footer          (footer prop)
├── Resize handle       (resizable — drag the right edge)
└── Peek panel          (peek — floating preview while collapsed)
Default
Workspace switcher, rounded icon tabs, favorites and collapsible workspace groups, and a pinned footer. Hover the brand row to reveal the collapse button, and drag the sidebar's right edge to resize it — at full width every tab reveals its label.
Home content
Collapsed
The sidebar slides off-frame and the content reflows to fill. Hovering the top-left toggle reveals a floating peek that overlays the content without shifting it; clicking reopens the sidebar for good.
Home content
Minimal
Nav groups only — no tab strip, no footer, and pinned open at a fixed width by turning off `collapsible` and `resizable`.
API Reference
Props for Sidebar, plus the data shapes it takes.
PropTypeDefaultDescription
workspacesSidebarWorkspace[]Switchable workspaces listed in the brand dropdown.
workspacestringControlled active workspace id.
defaultWorkspacestringworkspaces[0].idUncontrolled initial workspace.
onWorkspaceChange(id: string) => voidFires when a workspace is selected.
workspaceMenuSidebarMenuItem[]Extra entries appended under the workspace list (Settings, Sign out, …).
tabsSidebarTab[]Rounded icon tabs under the brand row. Omit to hide the strip.
tabstringControlled active tab value.
defaultTabstringtabs[0].valueUncontrolled initial tab.
onTabChange(value: string) => voidFires when a tab is selected.
groupsSidebarNavGroup[][]Nav groups rendered in the scroll area.
footerReact.ReactNodePinned footer content (buttons, user menu, …).
collapsiblebooleantrueAllow collapsing the sidebar off-frame.
collapsedbooleanControlled collapsed state.
defaultCollapsedbooleanfalseUncontrolled initial collapsed state.
onCollapsedChange(collapsed: boolean) => voidFires when the sidebar collapses or expands.
peekbooleantrueReveal a floating preview when hovering the reopen toggle while collapsed.
resizablebooleantrueDrag the right edge to resize between minWidth and maxWidth.
minWidthnumber274Narrowest sidebar width in px.
maxWidthnumber408Widest sidebar width in px. At this width every tab reveals its label.
defaultWidthnumberminWidthInitial sidebar width in px.
reserveTitlebarbooleanfalsePad the brand row so macOS traffic lights sit inside the sidebar (Tauri).
classNamestringClass override for the shell wrapper.
childrenReact.ReactNodeContent area to the right of the sidebar — reflows when it collapses.
PropTypeDefaultDescription
SidebarWorkspace{ id, name, logoSrc?, account? }`logoSrc` renders an image mark; `account` renders the number as small grey text.
SidebarTab{ value, label, icon? }One rounded icon tab.
SidebarNavGroup{ label?, items, more? }`more: true` appends an inert “More” row; pass `{ label, onClick }` to wire it up.
SidebarNavItem{ name, icon?, href?, onClick?, children?, actions? }`children` makes the row collapsible; `actions` adds a hover “…” dropdown.
SidebarMenuItem"separator" | { heading } | { label, icon?, onClick?, variant?, disabled? }Dropdown entry — same spec as DropdownMenu `items`.