Sidebar
Navigation · Sidebar, UserMenu, WorkspaceSwitcher, Menu
App navigation down the side: groups with headings, counts and badges, one level of nested pages, links, item menus and a collapsed mode with icons only.
- Three looks:
variant="floating" (default, a card with a gap to the edge), "attached" (flush with the left edge, full height, a hairline to the content) and "shell" (on the dark frame; AppShell navigation="sidebar" uses it). - Items with
href render as links; pass your router's link as linkAs (Next.js Link, React Router Link). external opens in a new tab and says so to screen readers. - Extras per item:
count, badge ("dot" for new activity or a short word like "New"), disabled, actions (a "…" menu on hover and focus) and items for nested pages. Groups take collapsible, defaultOpen and an action such as "New project". - Collapsed, every label is a tooltip; a parent opens a flyout with its pages on hover, click or →. Pass
storageKey to remember the state and shortcut for ⌘B / Ctrl+B. header and footer take nodes or a function of { collapsed }, e.g. a WorkspaceSwitcher and a UserMenu that turn compact.- On phones (≤ 760px) the sidebar becomes an off-canvas drawer behind a menu button: Escape and the scrim close it, focus stays inside and returns to the button. Control it with
mobileOpen and onMobileOpenChange. - For filters, use
as="aside": items with checked become checkbox (or, with the group's select: "single", radio) options with counts, and a group's content holds sliders or date fields. See the Filter Sidebar pattern.
Props
| Prop | Type | Notes |
|---|
groups | SidebarGroup[] | Required |
current? | string | Id (or label) of the current page. |
onPick? | (id: string) => void | |
variant? | "floating" | "attached" | "shell" | `floating` (default): a card with rounded corners and a shadow. `attached`: full height, flush
with the edge of the screen, divided by a line. `shell`: on the dark frame of `AppShell`. |
collapsed? | boolean | Icons only. |
defaultCollapsed? | boolean | |
onCollapsedChange? | (collapsed: boolean) => void | |
storageKey? | string | Remember the collapsed state in the browser under this key. |
shortcut? | boolean | ⌘B (Ctrl+B) collapses and expands the sidebar, except while typing in a field. |
linkAs? | ElementType | The element items with an `href` render as (default `a`), e.g. Next.js `Link`. |
mobileOpen? | boolean | On phones (up to 760px wide): whether the drawer is open (controlled). |
onMobileOpenChange? | (open: boolean) => void | |
header? | ReactNode | ((state: { collapsed: boolean }) => ReactNode) | Top of the sidebar (brand, `WorkspaceSwitcher`); a function gets the collapsed state. |
footer? | ReactNode | ((state: { collapsed: boolean }) => ReactNode) | Bottom of the sidebar (`UserMenu`, settings); a function gets the collapsed state. |
as? | "nav" | "aside" | `nav` (default) for app navigation. `aside` for filters, settings or other tools beside the
content: a complementary region instead of a navigation landmark. |
collapsible? | boolean | Offers the collapse button and the icons-only mode (default true; filters usually set false). |
label? | string | Accessible name of the navigation (or the aside). |
className? | string | Extra class on the root element. |
style? | CSSProperties | Inline style on the root element. |
| Prop | Type | Notes |
|---|
name | string | Required |
email? | string | |
avatar? | string | Picture URL; initials otherwise. |
items? | (MenuItem | "-")[] | The menu: profile, settings, sign out … |
compact? | boolean | Only the avatar (a collapsed sidebar). |
side? | "top" | "bottom" | Where the menu opens (default `top`, for the foot of a sidebar). |
className? | string | Extra class on the root element. |
style? | CSSProperties | Inline style on the root element. |
WorkspaceSwitcher
| Prop | Type | Notes |
|---|
items | { id: string; name: string; sub?: string; tint?: Tint; logo?: ReactNode }[] | Required |
value? | string | |
onChange? | (id: string) => void | |
label? | string | |
footer? | ReactNode | |
variant? | "frame" | |
width? | number | |
compact? | boolean | Only the workspace's mark, its name as the accessible name (a collapsed sidebar). |
className? | string | Extra class on the root element. |
style? | CSSProperties | Inline style on the root element. |
| Prop | Type | Notes |
|---|
items | (MenuItem | "-")[] | Required |
label? | string | Accessible name of the menu. |
autoFocus? | boolean | Focus the first item on mount (menus opened from a button or the keyboard). |
onClose? | () => void | Called after an item runs, and on Escape, so the owner can close the menu. |
className? | string | Extra class on the root element. |
style? | CSSProperties | Inline style on the root element. |