Clinia UI

Sidebar

The app shell's navigation: collapsible, with groups, badges and an active item.

shadcn docs →

When to use

  • The main navigation of an app: sources, records, conversations, settings.
  • An app with more sections than fit in a top bar, grouped under labels.

When not to use

  • Site navigation with a few top-level sections: use Navigation Menu.
  • A trail back up the hierarchy: use Breadcrumb.
  • Filters or details beside the content: use Sheet.

Install

npx shadcn@latest add @clinia/sidebar
Montreal clinic

Sources

The page for the selected item renders here.

Clinia rules

  • Exactly one item is isActive: the current page. It gets a bg-sidebar-accent/15 tint and font-medium, with foreground text.
  • Hover is the ink tint, bg-sidebar-foreground/4, so a hovered item never reads as the current page.
  • Item labels are short nouns that match the page title: Sources, not Manage your sources.
  • Counts sit in SidebarMenuBadge. When the sidebar collapses to icons, give each SidebarMenuButton a tooltip with its label.

Do and don't

Do mark one item active: the current page.
Don't highlight several items at once.

States

collapsed to icons · tooltip

Toggle the site theme to review both themes.

Sizes

SizeHeightPadding xGapRadiusType
defaulth-9 · 36pxpx-3 · 12pxgap-2 · 8px--radius-mdtext-sm · 14px
smh-8 · 32pxpx-3 · 12pxgap-2 · 8px--radius-mdtext-xs · 12px
lgh-14 · 56pxpx-3 · 12pxgap-2 · 8px--radius-mdtext-sm · 14px

Accessibility

Built in

  • The active item is tinted bg-sidebar-accent/15 with foreground text: Trust never sits behind label-size text. isActive also sets data-active for your own styling.
  • Cmd+B on macOS or Ctrl+B elsewhere toggles the sidebar.
  • On mobile it opens as a Sheet, which moves focus inside and returns it on close.
  • SidebarTrigger and SidebarRail are labelled buttons, so they are named for screen readers.

Your responsibility

  • isActive styles the item but doesn't set aria-current. Pass aria-current="page" on the active item yourself.
  • Render items that navigate as links: render={<Link href="/sources" />} on SidebarMenuButton.
  • Put the page content in SidebarInset, which renders <main>, and wrap the menu in <nav aria-label="Workspace">.

How to test

  1. Press Tab through the items: each one shows the Trust focus ring.
  2. With a screen reader, the active item is announced as Sources, current page, link.
  3. Press Cmd+B or Ctrl+B: the sidebar collapses, and Cmd+B again restores it.
  4. At a mobile width, open the sidebar: focus moves inside it. Press Escape: it closes and focus returns to the trigger.

API

Sidebar

PropValuesDefaultDescription
side
leftright
left

Which edge of the screen the sidebar sits on.

variant
sidebarfloatinginset
sidebar

floating detaches it with a gap; inset sets the page content in a card beside it.

collapsible
offcanvasiconnone
offcanvas

offcanvas slides it away, icon shrinks it to an icon rail, none keeps it fixed.

SidebarMenuAction

PropValuesDefaultDescription
showOnHover
boolean
false

Hides the action until its row is hovered or focused.

SidebarMenuButton

PropValuesDefaultDescription
isActive
boolean
false

Marks the current page. Sets data-active and tints the item.

tooltip
string | (TooltipPopupProps & Pick<TooltipPositionerProps, "align" | "alignOffset" | "side" | "sideOffset">)
–

Label shown on hover when the sidebar is collapsed to icons.

variant
defaultoutline
default

outline draws a border around the item.

size
defaultsmlg
default

Height: sm 32px, default 36px, lg 56px, for an item with two lines.

SidebarMenuSkeleton

PropValuesDefaultDescription
showIcon
boolean
false

Adds an icon placeholder to the skeleton row.

SidebarMenuSubButton

PropValuesDefaultDescription
size
smmd
md

Text size of the nested item.

isActive
boolean
false

Marks the current page. Sets data-active and tints the item.

SidebarProvider

PropValuesDefaultDescription
defaultOpen
boolean
true

Whether the sidebar starts expanded.

open
boolean
–

Controlled expanded state. Pair with onOpenChange.

onOpenChange
((open: boolean) => void)
–

Called when the user expands or collapses the sidebar.

All other props come from the native div element.