Skip to content

Sidebar · Nav item · Nav section · Topbar

The product’s rail — a floating dark panel, not a full-height strip: 240 wide with 24 above and below it, right corners 16 and left corners square, on nav/bg; the logo, sections of links, room, the signed-in person at the bottom.

Beta · Shells and patterns · packages/css/src/components/sidebar.css · React on Base UI: @pepperui/sidebar · @pepperui/nav-item

.pui-sidebar (__logo __product __nav __group __spacer __user) · .pui-nav-item (aria-current; __icon __label __count __chevron) · .pui-nav-section · .pui-topbar (__search __control). The MAFO shell.

Sidebar · Nav item · Nav section · Topbar — every size and every stateOpen in the workshop

Sizes across, states down. It is 1023 px wide, more than this column holds — scroll the frame sideways, or open it in the workshop.

  • One component, 240 × 1032 (the 1080 canvas minus the 24 insets); resize the instance to the page, the Spacer takes the difference; 32 to the content on its right
  • Logo block: a 36 slot for the product mark (never re-drawn — drop the asset in) and Product as text; Nav: two groups of exposed Nav sections and Nav items at space/4, groups space/16 apart (MAFO’s real labels; Dashboard active; Optimisations with its count and chevron); Spacer; User card on the hover wash with an exposed Avatar, User name, User role and a chevron — Has user card
  • Every link is a Nav item — set State active on the one that is; every section a Nav section
  • Colour: the rail is the house dark (neutral/800); inks are nav/item/*

Use when a product screen — MAFO and the Cabinet open with it, and iRTB and MobuppsX as designed.

Do not use when the site (its nav is a top bar); a slide; a dialog or a settings panel (a Sheet or a Card).

Relates to Nav item, Nav section, Topbar, Avatar, Badge, the Shells & navigation pattern page.

Anti-patterns full height with sharp corners · an accent active pill · a logo re-drawn in vectors · more than seven links in a group without a section · a light rail.

Keywords: sidebar, rail, left navigation, app shell, product navigation, menu

Figma — page Sidebar: Sidebar (1 variants) · Nav section (1 variants)

shadcn: sidebar

One link of the rail — a 16 glyph, a label, a count pill when a section has things waiting, a chevron when the link opens a group.

  • State default / hover / active / focus (Button’s ring) / disabled (50%)
  • Label; Has icon and Icon (a 16 Lucide glyph on nav/item/fg — the same ink as the label); Has count (an exposed yellow Badge); Has chevron (a chevron-down on nav/section/fg — the links are dropdowns, not tabs)
  • Padding space/8 × space/12, gap space/8, radius/8; the label on body/x-small at Regular
  • 208 wide = the rail’s 240 minus its 16 sides; FILL inside Sidebar

Use when composing Sidebar; a link in any dark rail.

Do not use when the item switches a view in place (Tabs); it is an action (Button); the surface is light (a light nav is Topbar’s or the site’s).

Relates to Sidebar, Nav section, Badge, Topbar, Tabs.

Anti-patterns an accent pill for the active item · SemiBold labels · a count without a pill · a chevron on a link that opens a page.

Keywords: nav item, sidebar link, menu item, rail link, navigation

Figma — page Sidebar: Nav item (5 variants)

The class, the parts, and nothing that is not in the package. The same block opens sidebar.css.

<aside class="pui-sidebar"><div class="pui-sidebar__logo"><img src="…" alt=""><span class="pui-sidebar__product">MAFO</span></div>
<nav class="pui-sidebar__nav"><div class="pui-sidebar__group"><div class="pui-nav-section">Workspace</div>
<a class="pui-nav-item" href="…" aria-current="page"><span class="pui-icon pui-nav-item__icon">…</span>Dashboard</a>
<a class="pui-nav-item" href="…">Optimisations<span class="pui-badge pui-badge--yellow pui-badge--small pui-nav-item__count">3</span>
<span class="pui-icon pui-nav-item__chevron">…</span></a></div></nav>
<div class="pui-sidebar__spacer"></div>
<div class="pui-sidebar__user"><span class="pui-avatar pui-avatar--blue">FK</span><div class="pui-sidebar__user-texts">…</div></div></aside>
What it is Note
Nav item :hover · active = [aria-current] or --active · :focus-visible · [aria-disabled=“true”] · --nested (a group’s child) —

Every number here is measured on the rendered component: contrast (npm run contrast:render), the focus ring (npm run focus) and the keyboard (npm run keyboard). The floors are principle 12’s.

ink on ground reads floor the matrix calls it
#ec6663 on #f9d3d2 2.29 4.5 Red badge / chip (exempt) axe
#858080 on #352d2d 3.44 4.5 Sidebar user role (exempt) axe
#858080 on #231b1b 4.33 4.5 Nav section title (exempt) axe
#1a6b36 on #d4f2de 5.48 4.5 Success badge (promised) ok
#634e0f on #fad567 5.62 4.5 Yellow badge / chip (promised) ok
#544d4d on #dad9d9 5.85 4.5 text.muted on ground.card.sunken (promised) ok
#b5b3b3 on #231b1b 8.08 4.5 Nav item at rest (promised) ok
#544d4d on #ffffff 8.24 4.5 text.muted on surface.page (promised) ok
#5b0e0d on #f9d3d2 10.09 4.5 Red avatar initials (promised) ok
#ffffff on #463f3f 10.27 4.5 Nav item when active (promised) ok
… 8 more pair(s)

18 distinct pair(s) rendered, 3 that axe calls a violation — each one carries its reason in storybook/test/axe-allowlist.json.

primitive on the indicator over the change
Sidebar nav item surface/inverse shadow #6a66e4 2 px #231b1b 3.72 ok

8 of 8 focus stop(s) in this block meet WCAG 2.4.13 on screen — the same crop screenshotted focused and unfocused, and the difference measured.

Nothing in this component claims an ARIA role with a keyboard contract; its controls are ordinary ones and the browser already gives them their keys.

Tab order across the whole library is document order over 344 stops, and Shift+Tab is its exact reverse — no keyboard trap anywhere (WCAG 2.1.2).

Pepper UI v1.5.0

The Mobupps design system. 386 tokens, 88 components, 65 pages in the workshop — every page of this site generated from the repository, so nothing here is typed twice.