Skip to content

Sidebar

Sidebar components are used to provide a collapsible navigation menu that can be toggled open or closed. They are typically used for site navigation, allowing users to access different sections of the application.

Loading Code Block...
Loading Code Block...
Loading Code Block...

The sidebar header is a discriminated union with three explicit configurations. Pass undefined (or omit the prop entirely) to render the sidebar with no header.

headerTypeUse caseNotes
'profile' (default)Avatar + title/description + optional context-switcher dropdownSub-modes via variant: 'side-by-side' (default) or 'stacked'.
'logo'Single brand image, alignable left/center/rightUseful for marketing-style sidebars.
omittedNo header — menu starts at the topUseful for embedded contexts.

'profile' is the default for backwards compatibility, so existing consumers don’t need to set headerType explicitly. In Vue, the legacy { profile: { ... } } wrapper is still accepted as a deprecated alias.

Loading Code Block...

Profile header with context-switcher dropdown

Section titled “Profile header with context-switcher dropdown”

Set hasDropdown: true to render a context-switcher (e.g. branch picker) inside the header. The dropdown is implemented with the design-system DropdownMenu component.

Loading Code Block...

Use headerType: 'logo' for a single brand image. The align prop controls horizontal alignment.

Loading Code Block...

Omit the prop entirely to render the sidebar with no header — the menu starts at the top.

Loading Code Block...

The React renderFooter prop and Vue <slot name="footer"> give you full control over the footer markup. When provided they take precedence over sidebarFooter / the footer prop.

Loading Code Block...

The Vue footer prop accepts both Vue-style ({ type: 'branding', logo, name } or { type: 'menu', menu }) and React-style ({ variant: 'image', image } or { variant: 'list', list }) shapes for parity.


PropsDefaultTypeDescription
sidebarHeader-SidebarHeader | undefinedConfiguration for the sidebar header. Discriminated union — see the Sidebar Header section. Omit for no header.
menu[]arrayAn array of section objects representing the sidebar menu. Author with the React keys (`sectionLabel`, `children`) — Vue additionally accepts the legacy `title` / `items` aliases, but React does not.
sidebarFooter-objectConfiguration for the sidebar footer section.
renderFooter-() => ReactNodeRender-prop alternative to `sidebarFooter`. When provided, takes precedence and gives full control over footer markup (equivalent to Vue's `<slot name="footer">`).
indentedSidebarfalsebooleanAdds a small left margin to nested items. Useful for visually distinguishing sub-items.

React consumers can also set the desktop width via the —sidebar-width CSS variable (range: 256px–380px) on the sidebar’s container.

The header prop is a discriminated union keyed by headerType. Common fields are listed first; variant-specific fields follow.

type SidebarHeader =
| {
headerType?: "profile"; // optional, defaults to "profile"
variant?: "side-by-side" | "stacked";
title?: string;
description?: string;
image?: string;
hasDropdown?: boolean;
dropdownOptions?: {
options: Array<{ label: string; value: string | object }>;
};
dropdownPlaceholder?: string;
onDropdownChange?: (value: string | object) => void;
}
| {
headerType: "logo";
image: string;
alt?: string;
align?: "left" | "center" | "right";
}
| undefined; // omit for no header
PropsDefaultTypeDescription
headerType'profile''profile' | 'logo'Discriminator for the header variant. Defaults to 'profile' for backwards compatibility.
variant'side-by-side''side-by-side' | 'stacked'Sub-mode for the profile header. 'side-by-side' renders avatar + text horizontally; 'stacked' renders them vertically.
title-stringThe title text for the profile header.
description-stringThe description text for the profile header.
image-stringImage URL. Required for `headerType: 'logo'`; optional avatar source for `headerType: 'profile'`.
align'left''left' | 'center' | 'right'Horizontal alignment for `headerType: 'logo'` only.
hasDropdownfalsebooleanProfile-only. When true, renders a context-switcher `<DropdownMenu />` inside the header.
dropdownOptions-{ options: Array<{ label: string; value: string | object }> }Profile-only. Options for the header dropdown. Required when `hasDropdown` is true.
dropdownPlaceholder'Select'stringProfile-only. Placeholder text for the header dropdown trigger.
onDropdownChange-(value: string | object) => voidProfile-only. Fires when the user picks a different option in the header dropdown. The callback receives the **selected option's `value`** (not the full option object).

Each entry in the menu array is a section. Both naming conventions are accepted; React keys are preferred and Vue keys are aliased.

PropsDefaultTypeDescription
sectionLabel-stringThe label text for the menu section. Aliased as `title` in Vue (deprecated).
children[]arrayMenu items inside this section. Aliased as `items` in Vue (deprecated).
PropsDefaultTypeDescription
title-stringThe display text for the menu item. Aliased as `label` in Vue (deprecated).
url-stringThe destination URL. Aliased as `href` in Vue (deprecated).
isActivefalsebooleanWhether the item represents the user's current route. Aliased as `active` in Vue (deprecated).
icon-ReactNode (React) | FunctionalComponent | VNode | string (Vue)Optional icon rendered to the left of the label. Vue additionally accepts a URL/path string — rendered as `<img :src>` inside the icon slot; React requires a `ReactNode`.
children-SidebarItem[]Optional nested items. Renders the parent as a collapsible group. Aliased as `items` in Vue (deprecated).
disabledfalsebooleanDisables the item — applies `opacity-50`, `pointer-events-none`, and `aria-disabled="true"`.

The footer prop accepts both Vue-style ({ type: 'branding' | 'menu' }) and React-style ({ variant: 'list' | 'image' }) shapes. React consumers can also pass renderFooter for full custom markup; Vue consumers can use the <slot name="footer"> (see Custom footer).

PropsDefaultTypeDescription
variant'list''list' | 'image'The visual variant of the footer.
list[]arrayFooter items rendered for `variant: 'list'`. Each entry uses the same shape as a menu item (`title`, `url`, optional `icon`).
image-stringImage URL rendered for `variant: 'image'`.
  • The nested hierarchy of the sidebar is semantically structured to be navigated via keyboard (Tab and Shift + Tab), with active states distinctly highlighted.
  • Text contrast ratios exceed standard accessibility checks to ensure readability against the primary dark background colors.
  • Interactive elements like dropdowns and expandable accordion menus emit proper ARIA roles when expanded or collapsed.