Skip to content
Zuno UI
Explore components
EXPLORE
Actions
Forms
Layout
Navigation
Data display
Feedback
Overlays
RESOURCES
Components/Sidebar

Sidebar

App navigation that expands, collapses to an icon rail and becomes a drawer on phones.

Home

Installation

Run it from the root of a project already set up with zunoui init.

npx zunoui@latest add sidebar

Dependencies

What add sidebar installs alongside the component. The CLI skips any you already have in a compatible version.

Examples

3 examples · 1 component
sidebar

Home

App shell

Header, grouped links with a badge, a footer and the content column; the trigger or ⌘B slides it away. Narrow the window to see the phone drawer.

sidebar

Home

Icon rail

collapsible="icon" keeps the icons; hover or focus one to see its tooltip.

sidebar

Profile

Nested pages

SidebarMenuSub lists child pages under their section.

API reference

Forwards props and ref to the container element; it only adds composition utilities.

PropTypeDefault
SidebarProvider

State for the desktop panel (open/onOpenChange to control or persist it) and the phone drawer. shortcut ("b") toggles with ⌘/Ctrl; false turns it off.

divdefaultOpen = true
Sidebar

A nav landmark (aria-label defaults to "Main"). side is logical and flips in RTL. collapsible: "offcanvas" slides away, "icon" keeps an icon rail, "none" stays open. Below 768 px it becomes a modal drawer.

navside = "start", collapsible = "offcanvas"
SidebarTrigger

Ghost icon button with aria-expanded; opens the drawer on phones.

Button"Toggle sidebar"
SidebarInset

The content column. render={<div />} when the page already has a main.

main—
SidebarHeader / SidebarContent / SidebarFooter

Top, scrolling middle and bottom areas.

div—
SidebarGroup / SidebarGroupLabel / SidebarSeparator

Sections with a label; the label becomes screen-reader-only in the icon rail.

div—
SidebarMenu / SidebarMenuItem

The list of destinations.

ul / li—
SidebarMenuButton

Icon first, label in a <span>. render={<a href />} for links; isActive marks the current page with aria-current="page". tooltip shows beside it in the icon rail.

buttonsize = "default"
SidebarMenuBadge

A count inside the button, read as part of its name.

span—
SidebarMenuSub / SidebarMenuSubItem / SidebarMenuSubButton

Nested destinations; left out of the icon rail.

ul / li / button—
useSidebar()

state, open, setOpen, openMobile, setOpenMobile, isMobile and toggle.

hook—

States

The states that apply to this component and their visual treatment.

StateTreatment
Expanded16 rem panel with icons and labels.
Collapsed (offcanvas)Width 0 and inert; content takes the full width.
Collapsed (icon)Icon rail; labels are screen-reader-only and shown as tooltips.
ActiveAccent surface, medium weight and aria-current="page".
Hover / Focus visibleAccent surface; 2 px sidebar-ring outline inside the button.
PhoneModal drawer from the start edge; swipe, Escape or the backdrop close it.

Accessibility

The sidebar is a named nav landmark and every menu is a list, so screen readers can jump to it and hear how many destinations it holds.

Links are real links (render={<a href />}); the current page carries aria-current="page", not only a background.

The trigger is a labelled button with aria-expanded. ⌘B / Ctrl B is a shortcut on top of it, never the only way.

Collapsed to offcanvas, the panel is inert, so its links leave the Tab order. In the icon rail labels stay in the DOM as the accessible name and a tooltip shows them on hover and focus.

On phones it is a modal drawer: focus moves inside, Escape or the backdrop closes it, focus returns to the trigger, and choosing a destination closes it.

side is logical: start is the right edge in right-to-left pages, and the panel icon mirrors.