suiss/ui · Component
Sidebar
A collapsible app sidebar for navigation, with icon, off-canvas and mobile sheet modes.
Sidebar is an open-source component from suiss/ui for React. The @esuiss/ui CLI copies its source into your project, so you own the code.
SidebarProvider holds the open state and wraps the whole layout. Inside it, Sidebar renders the panel and SidebarInset renders the main content beside it. The sidebar stacks SidebarHeader, a scrolling SidebarContent and SidebarFooter. Content is organized into SidebarGroup sections, each with a SidebarGroupLabel, an optional SidebarGroupAction and a SidebarGroupContent. Navigation lives in a SidebarMenu of SidebarMenuItem rows, each holding a SidebarMenuButton and optionally a SidebarMenuAction, SidebarMenuBadge or nested SidebarMenuSub.
SidebarTrigger and SidebarRail toggle the sidebar. On screens narrower than 48rem, the sidebar renders inside a Sheet instead. Use Sidebar for the main navigation of an app; for bottom navigation on small screens, consider TabBar.
Installation
CLI
Works in any project with a components.json. See Installation for the one-line registry setup. Or use the suiss/ui CLI:
Manual
- Install the dependencies and add the
cnhelper:
-
Add the pieces it builds on: Button, Direction, Input, Separator, Sheet, Skeleton, Tooltip,
use-mobile,use-platform. -
Copy the source into
components/ui/sidebar.tsx:
- Update the import paths to match your project.
Usage
Use defaultOpen on SidebarProvider for an uncontrolled sidebar, or open with onOpenChange to control it. Read and change state from any child with the useSidebar hook, which returns state, open, setOpen, openMobile, setOpenMobile, isMobile and toggleSidebar.
Set collapsible="icon" to shrink the sidebar to a rail of icons when collapsed, offcanvas to slide it out of view, or none to keep it fixed. Give each SidebarMenuButton a tooltip so its label stays available while collapsed to icons.
Use the render prop on SidebarMenuButton to render it as a link.
Set asChild on SidebarMenuButton and pass a link as the child to render it as a link.
Pass a render function to SidebarMenuButton that returns a link with the props it receives.
Examples
Floating
Uses the floating variant, a rounded panel with a shadow.
Inset
Uses the inset variant, which also raises the main content into a rounded card.
Collapsed
Starts collapsed to icons and expands from the rail.
Offcanvas
Slides the sidebar fully out of view when collapsed.
Right side
Places the sidebar on the right edge.
Loading
Shows SidebarMenuSkeleton placeholders while items load.
API Reference
SidebarProvider
Holds the open state, provides it through context and wraps the layout.
| Prop | Type | Default | Description |
|---|---|---|---|
defaultOpen | boolean | true | Sets whether the sidebar starts expanded when uncontrolled. |
open | boolean | - | Controls whether the sidebar is expanded. |
onOpenChange | (open: boolean) => void | - | Called with the new state when the sidebar expands or collapses. |
Also accepts the props of React.ComponentProps<"div">.
Sidebar
The sidebar panel; a sheet on mobile.
| Prop | Type | Default | Description |
|---|---|---|---|
side | "left" | "right" | "left" | Places the sidebar on the left or right edge. |
variant | "sidebar" | "floating" | "inset" | "sidebar" | Chooses a full-height sidebar, a rounded floating panel, or an inset layout. |
collapsible | "offcanvas" | "icon" | "none" | "offcanvas" | Sets how the sidebar collapses: off canvas, to icons, or not at all. |
Also accepts the props of React.ComponentProps<"div">.
SidebarTrigger
An icon button that toggles the sidebar.
Also accepts the props of React.ComponentProps<typeof Button>.
SidebarRail
A thin hit area along the sidebar's edge that toggles it on click.
Also accepts the props of React.ComponentProps<"button">.
SidebarInset
The main element for page content next to the sidebar.
Also accepts the props of React.ComponentProps<"main">.
SidebarInput
A compact Input styled for use in the sidebar.
Also accepts the props of React.ComponentProps<typeof Input>.
SidebarHeader
The top area, above the scrolling content.
Also accepts the props of React.ComponentProps<"div">.
SidebarFooter
The bottom area, below the scrolling content.
Also accepts the props of React.ComponentProps<"div">.
SidebarSeparator
A divider between sidebar sections.
Also accepts the props of React.ComponentProps<typeof Separator>.
SidebarContent
The scrolling region that holds the groups.
Also accepts the props of React.ComponentProps<"div">.
SidebarGroup
A section of related content.
Also accepts the props of React.ComponentProps<"div">.
SidebarGroupLabel
The title of a group; it fades out when collapsed to icons.
Also accepts the props of useRender.ComponentProps<"div">, React.ComponentProps<"div">.
SidebarGroupAction
A small button in the corner of a group, such as an add button.
Also accepts the props of useRender.ComponentProps<"button">, React.ComponentProps<"button">.
SidebarGroupContent
The body of a group.
Also accepts the props of React.ComponentProps<"div">.
SidebarMenu
A list of menu items.
Also accepts the props of React.ComponentProps<"ul">.
SidebarMenuItem
A list item that holds a menu button and its extras.
Also accepts the props of React.ComponentProps<"li">.
SidebarMenuButton
The clickable row for a destination or command.
| Prop | Type | Default | Description |
|---|---|---|---|
isActive | boolean | false | Marks the button as the current item. |
tooltip | string | React.ComponentProps<typeof TooltipContent> | - | Text or TooltipContent props for a tooltip shown only while collapsed on desktop. |
variant | "default" | "outline" | "default" | Uses a plain style or an outline style with a background and border. |
size | "default" | "sm" | "lg" | "default" | Sets the row height: sm, default or lg. |
Also accepts the props of useRender.ComponentProps<"button">, React.ComponentProps<"button">.
SidebarMenuAction
A small button at the end of a menu item, such as a more button.
| Prop | Type | Default | Description |
|---|---|---|---|
showOnHover | boolean | false | On desktop, hides the action until its item is hovered or focused. |
Also accepts the props of useRender.ComponentProps<"button">, React.ComponentProps<"button">.
SidebarMenuBadge
A count or label shown at the end of a menu item.
Also accepts the props of React.ComponentProps<"div">.
SidebarMenuSkeleton
A loading placeholder shaped like a menu item.
| Prop | Type | Default | Description |
|---|---|---|---|
showIcon | boolean | false | Adds a square placeholder for an icon. |
Also accepts the props of React.ComponentProps<"div">.
SidebarMenuSub
A nested list of sub-items, indented with a leading line.
Also accepts the props of React.ComponentProps<"ul">.
SidebarMenuSubItem
A list item inside a sub-menu.
Also accepts the props of React.ComponentProps<"li">.
SidebarMenuSubButton
The clickable row of a sub-item, rendered as a link by default.
| Prop | Type | Default | Description |
|---|---|---|---|
size | "sm" | "md" | "md" | Sets the text size: sm or md. |
isActive | boolean | false | Marks the sub-item as the current page. |
Also accepts the props of useRender.ComponentProps<"a">, React.ComponentProps<"a">.
Accessibility
SidebarTriggerandSidebarRailare labelledToggle Sidebar. The rail is removed from the tab order, so keep aSidebarTriggerin reach of keyboard users.- Press
Command-Bon Apple platforms, orCtrl+Belsewhere, to toggle the sidebar. - On mobile, the sidebar is a dialog with a visually hidden title,
Sidebar;Escapecloses it. - Menu-button tooltips appear only while the sidebar is collapsed, so labels stay available when only icons show.
Notes
- Every toggle writes the state to a
sidebar_statecookie for 7 days. Read it on the server to setdefaultOpenand avoid a flash on load. - Widths come from
--sidebar-width(16rem) and--sidebar-width-icon(3rem), set onSidebarProvider; override them through itsstyle. - The sidebar element exposes
data-state(expandedorcollapsed),data-collapsible,data-variantanddata-sidefor styling. Menu buttons setdata-activeanddata-size. useSidebarthrows if it's used outside aSidebarProvider.- The panel uses
bg-sidebar; active items usebg-sidebar-accentwith atext-sidebar-primaryicon. Change thesidebar-*variables to style it apart from the page.