Sidebar Nav

Compact text navigation for docs and settings sidebars.

Installation

pnpm dlx shadcn@latest add @paneui/sidebar-nav

Usage

Composition

Examples

Icons

Icons and Groups

Linked Groups

Remembered Sections

RTL

When to use

For long page trees in docs, settings and admin sidebars. For an app rail with icons that folds to a strip, use Animated Sidebar.

Icon alignment

When a list, or the rows of a section, holds a row or group label with an icon, the rows and group labels beside it that have none start at the icon rows' text, and so do the rows inside those groups. This happens on its own. To force or cancel it, set --sidebar-nav-inset (for example [--sidebar-nav-inset:1.5rem] or [--sidebar-nav-inset:0px]) on a wrapper.

Keyboard

Section headings are buttons with aria-expanded. A linked heading is a link plus a separate chevron button named by the locale’s toggleNamed(label) (“Toggle Guides”), or toggleSection when the label is not text; toggleLabel overrides it. The current row has aria-current="page", and on mount the list scrolls it into view when it would start below the fold.

API Reference

SidebarNav

Column that fills its container. Also accepts every prop of div.

SidebarNavSearch

A field-shaped button that opens your search. Also accepts every prop of button.

shortcut
React.ReactNode
Key cap at the end, such as ⌘K.
children= `labels.searchPlaceholder`
React.ReactNode
The field text. The default comes from the locale.
PropTypeDefaultDescription
shortcutReact.ReactNode—Key cap at the end, such as ⌘K.
childrenReact.ReactNode`labels.searchPlaceholder`The field text. The default comes from the locale.

SidebarNavContent

The scrolling list. Give it an aria-label. Also accepts every prop of nav.

SidebarNavSection

Also accepts every prop of Collapsible.Root.

label*
React.ReactNode
Heading text.
count
number
Muted count after the label.
level= "section"
"section" | "group"
group is a smaller muted heading inside a section.
collapsible= true
boolean
false drops the toggle and keeps it open.
href
string
Makes the label a link to the section's own page; the chevron beside it still folds the rows.
labelRender
React.ReactElement | (props) => React.ReactElement
Renders the label link with your router's link, such as <Link href="…" />.
active= false
boolean
Marks the label's page as current with the fill, the bar and aria-current="page".
icon
React.ReactNode
Leading icon in the same 16px slot as SidebarNavLink, muted until the label is hovered or current.
toggleLabel
string
Name of the chevron button beside a linked label. Defaults to the locale's toggleNamed(label).
PropTypeDefaultDescription
label*React.ReactNode—Heading text.
countnumber—Muted count after the label.
level"section" | "group""section"group is a smaller muted heading inside a section.
collapsiblebooleantruefalse drops the toggle and keeps it open.
hrefstring—Makes the label a link to the section's own page; the chevron beside it still folds the rows.
labelRenderReact.ReactElement | (props) => React.ReactElement—Renders the label link with your router's link, such as <Link href="…" />.
activebooleanfalseMarks the label's page as current with the fill, the bar and aria-current="page".
iconReact.ReactNode—Leading icon in the same 16px slot as SidebarNavLink, muted until the label is hovered or current.
toggleLabelstring—Name of the chevron button beside a linked label. Defaults to the locale's toggleNamed(label).

SidebarNavList

Also accepts every prop of ul.

A row inside its own li. Use render for your router's link. Also accepts every prop of a.

active= false
boolean
Marks the current page with a fill, a bar in the gutter and aria-current="page".
icon
React.ReactNode
Leading icon in a 16px slot, muted until the row is hovered or current.
badge
React.ReactNode
Trailing content, such as a New badge.
PropTypeDefaultDescription
activebooleanfalseMarks the current page with a fill, a bar in the gutter and aria-current="page".
iconReact.ReactNode—Leading icon in a 16px slot, muted until the row is hovered or current.
badgeReact.ReactNode—Trailing content, such as a New badge.

SidebarNavFooter

Pinned under the list, above a hairline. Also accepts every prop of div.