Skip to content
Twentyfirst UIPro

Sidebar

Navigation · Sidebar, UserMenu, WorkspaceSwitcher, Menu

View as Markdown

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

Sidebar

PropTypeNotes
groupsSidebarGroup[]Required
current?stringId (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?booleanIcons only.
defaultCollapsed?boolean
onCollapsedChange?(collapsed: boolean) => void
storageKey?stringRemember 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?ElementTypeThe element items with an `href` render as (default `a`), e.g. Next.js `Link`.
mobileOpen?booleanOn 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?booleanOffers the collapse button and the icons-only mode (default true; filters usually set false).
label?stringAccessible name of the navigation (or the aside).
className?stringExtra class on the root element.
style?CSSPropertiesInline style on the root element.

UserMenu

PropTypeNotes
namestringRequired
email?string
avatar?stringPicture URL; initials otherwise.
items?(MenuItem | "-")[]The menu: profile, settings, sign out …
compact?booleanOnly the avatar (a collapsed sidebar).
side?"top" | "bottom"Where the menu opens (default `top`, for the foot of a sidebar).
className?stringExtra class on the root element.
style?CSSPropertiesInline style on the root element.

WorkspaceSwitcher

PropTypeNotes
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?booleanOnly the workspace's mark, its name as the accessible name (a collapsed sidebar).
className?stringExtra class on the root element.
style?CSSPropertiesInline style on the root element.

Menu

PropTypeNotes
items(MenuItem | "-")[]Required
label?stringAccessible name of the menu.
autoFocus?booleanFocus the first item on mount (menus opened from a button or the keyboard).
onClose?() => voidCalled after an item runs, and on Escape, so the owner can close the menu.
className?stringExtra class on the root element.
style?CSSPropertiesInline style on the root element.