Application navigation

The product’s persistent chrome: five sidebar layouts and a header that draws four types, all collapsing to one bar and drawer below 1024px.

Demo

Every sub-component the navigation is assembled from, on the white surface. The finished layouts are in the contextual demo.

Component
import { NavItemBase } from "@/components/application/app-navigation/base-components/nav-item"; <NavItemBase type="link" href="/dashboard" icon={BarChartSquare02} badge={"10"} > Dashboard </NavItemBase>

Contextual demo

Navigation is the page’s chrome, so it is judged as a page — nine working screens, not a well.

The navigation is the page

One scenario per Type on the sheet’s two frames — the five sidebars and the four headers — and in each the real layout is the page’s chrome: a sidebar fixed to the viewport with its own spacer, or a header across the top, with a pane beside it that the rows actually drive. Resize the window and the sidebar becomes the mobile bar and drawer. The one row that cannot navigate is the Tabs header’s second tier, which the kit renders without hrefs or a selection callback; it is kept as the sheet draws it, and the Code tab records why.

The family

Twelve exports across nine modules: five sidebars, one header, five base components, no barrel.

The components in this family, with their descriptions and import paths
ComponentDescriptionImport from
SidebarNavigationSimpleThe 280px default: brand mark, a search input with its ⌘K chip, a flat item list, footer items, an optional feature card, and the account card. The only variant that takes className, showAccountCard and hideBorder.@/​components/​application/​app-navigation/​sidebar-navigation/​sidebar-simple
SidebarNavigationSlimA 68px icon-only rail that expands a 256px panel beside itself when an item has children. Its items and footerItems are typed icon-required, because a rail with no glyph has nothing to draw.@/​components/​application/​app-navigation/​sidebar-navigation/​sidebar-slim
SidebarNavigationDualTierA 280px panel with labels, plus the same hover-revealed 256px second panel Slim uses — not the sheet's permanent 536px two-tier. The only variant that reaches the account card's own props: selectedAccountId and accountItems pass straight through.@/​components/​application/​app-navigation/​sidebar-navigation/​sidebar-dual-tier
SidebarNavigationSectionDividersGroups separated by hairlines. Takes one flat list where a group break is an item of its own — { divider: true } — rather than a nested shape. Two props only.@/​components/​application/​app-navigation/​sidebar-navigation/​sidebar-section-dividers
SidebarNavigationSectionsSubheadingsThe same grouping under uppercase labels. Takes { label, items }[] — the one variant whose items prop is not a NavItemType[] at all. Two props only.@/​components/​application/​app-navigation/​sidebar-navigation/​sidebar-sections-subheadings
HeaderNavigationBaseAll four of the sheet's header Types from one component: Simple is items alone, Dual-tier and Tabs add subItems with secondaryType, and Centered is the centered flag. Takes an actions slot that replaces the whole right side.@/​components/​application/​app-navigation/​header-navigation
NavItemBaseOne row, in three shapes: a link, a collapsible summary, or a collapsible child. Draws the icon, the label, an optional badge, and a trailing external glyph when the href starts with http.@/​components/​application/​app-navigation/​base-components/​nav-item
NavButtonThe header's row element and the rail's icon button in one: icon-only at 36px square with a tooltip, or a labelled pill at px-2 py-1.5 when it has children.@/​components/​application/​app-navigation/​base-components/​nav-button
NavListRenders a NavItemType[] into rows, opening a <details> for any item carrying sub-items and drawing a hairline for any item marked divider.@/​components/​application/​app-navigation/​base-components/​nav-list
NavAccountCardThe signed-in card at the foot of a sidebar: avatar with status dot, name, email, and a chevron opening a 264px menu with profile actions, an account switcher and Sign out.@/​components/​application/​app-navigation/​base-components/​nav-account-card
NavAccountMenuThe menu on its own, for a trigger of your own. Its account list is hardcoded today — the accounts prop it declares never reaches the rendered rows.@/​components/​application/​app-navigation/​base-components/​nav-account-card
MobileNavigationHeaderThe 56px bar every sidebar renders below lg: brand mark and a hamburger that opens the same sidebar content in a dismissable drawer, 296px wide behind a blurred scrim.@/​components/​application/​app-navigation/​base-components/​mobile-header

Built from

Eleven layers make up the family; six have their own docs page.

Component
Where it’s used here
BadgeA sm gray pill-color badge wrapping any string or number passed as a nav item's badge — the sheet's “8” on Tasks.
Button“Add account” in the account menu, at sm secondary with a leading Plus.
RadioButtonBaseThe selected marker on each account-switcher row, positioned absolutely at top-2 right-2 rather than laid out with the row.
TooltipWraps every NavButton, disabled when no label is passed. It is what makes the slim rail's icon-only buttons readable.
@untitledui/iconsChevronDown on a collapsible row, Share04 on an external one, ChevronSelectorVertical on the account card, Menu02 and X in the mobile bar, and User01, Settings01, BookOpen01, LogOut01 and Plus in the account menu.

The seven symbol sets

Every part the navigation is assembled from, one group per _Nav symbol set on the sheet, with the configuration Figma exposes.

Subject
Figma axis
In the kit
_Nav item baseCurrentthe current prop
State (Default, Hover, Focused)live hover: / focus-visible: CSS on the element — hover or Tab the specimen
Dot (a boolean property: the 10px `_Dot` at fg-success-secondary, on in the base symbols, hidden on the sheet's team rows)nothing — NavItemBase has no dot and no slot for one
_Nav item dropdown baseOpenthe native <details open> attribute, which NavList drives
Currentthe current prop on the summary
Statelive CSS — and hover colour is dead on this shape (see Code)
_Nav buttonCurrentthe current prop
Icon onlyomitting children — there is no iconOnly prop
Statelive CSS on the element
_Nav menu buttonOpenedtap it inside the frame — MobileNavigationHeader exposes no open prop, and the button is not exported on its own
Statelive CSS on the element
_Nav account card menu itemType (Menu item, Account)both rows of NavAccountMenu, which is exported; the item itself is module-private
CurrentselectedAccountId on the Account rows; Menu item rows have no current
Statelive CSS on the rows
_Nav account cardType (Card, Simple)Card only — the kit has no ringless Simple shape and no prop to drop the ring
Openpress the chevron — a DialogTrigger, not a prop
Breakpoint (Desktop 280, Mobile 256)a width the card fills; the control sets the column
_Nav featured cardType (13)page-local recipes in featured-cards.tsx — the kit ships none

Every axis Figma exposes, and which ones a control can reach

The table above is the honest map: a control exists for every axis the kit can set from a prop, and the rows in gray are the ones it cannot — Hover and Focused everywhere, because they are live CSS states; the row’s _Dot, because NavItemBasehas no slot for one; the account card’s Simple Type, which the kit does not draw; and the menu button’s Opened state, which nothing sets from outside. None of those is faked with a control that does nothing. Whether the kit should grow to close them is a decision for the Code tab’s defect list, not something this page should paper over.

_Nav item base — 1152:89220

Current=False — bg-primary, label at text-secondary, icon and chevron at fg-quaternary
Current=True — bg-secondary, and the row carries aria-current="page"

The sheet's row opens with a dot the kit has no slot for

Read from the symbol (1152:89351): the row is a 10px _Dot at fg-success-secondary, then 8px, then the 20px icon, then 8px, then the label — before the badge and chevron. NavItemBase draws the icon first and has no dot prop, so the specimens above start one element short of the sheet. Recorded on the Code tab rather than invented here. Everything else matches: 36px row, radius-sm (6px), Text sm/Semibold label, 8px padding, 12px to the chevron. Hover it and Tab to it: the sheet's Hover and Focused symbols are live CSS states here, not props.

_Nav item dropdown base — 1152:90366

Open=False, Current=False
Open=True, Current=False
Open=False, Current=True
Open=True, Current=True

The open state is the browser's, not a prop

NavItemBase renders a <summary> for type="collapsible", so the disclosure is a native <details> and the chevron rotates through in-open:. The four cells above set the open attribute directly, which is the same thing NavList does. Note the sheet draws no dot and no badge on this set, unlike the row above it.

_Nav button — 1165:736

Icon only=False, Current=False — a 122×32 pill
Icon only=False, Current=True — bg-secondary
Icon only=True, Current=False — 36px square
Icon only=True, Current=True — the same square, filled

Icon-only is not a prop

The shape is decided by whether the button has children — there is no iconOnly prop and no size. Always pass label: it is both the accessible name and the tooltip, and the tooltip is disabled without it. Hover it and Tab to it: the sheet's Hover and Focused symbols are live CSS states here, not props.

_Nav menu button — 1161:14070

Opened=False and Opened=True, in the bar that owns them — tap the button inside the frame
The same button under a header layout, which renders the identical bar below lg

This one has no kit export

The sheet gives the menu button its own symbol set with an Opened axis. In the kit it is written inline inside MobileNavigationHeader — a 36px rounded-lg button holding both glyphs at once, with Menu02 fading out and the close icon fading in on group-aria-expanded. There is no way to render it on its own, which is why these are real 375px viewports rather than cells. The frames are the only place the drawer can be opened too, since every mobile treatment here is viewport-gated.

_Nav account card — 7891:87996

Caitlyn King

caitlyn@untitledui.com

Type=Card, Open=False — 280px, rounded-xl over a 1px inset ring, avatar with status dot

Caitlyn King

caitlyn@untitledui.com

Type=Card, Open=True — open the chevron: a 264px menu with the switcher, shortcuts and Sign out

Type=Simple is Figma-only

The sheet draws two Types: Card, the ringed block above, and Simple — a bare 60px row with no ring whose trailing control is a log-out button rather than the chevron selector. The kit ships only Card, with no prop to drop the ring or swap the control, so Simple has no specimen here. The Breakpoint axis is a width change the sheet draws at 280 and 256; the kit fills whatever column it is given.

_Nav account card menu item — 7891:71338

Sienna Hewitt

sienna@untitledui.com

Both Types in place — open the card above, or this one, to see Menu item and Account rows with their Current and Hover states

Also no kit export

NavAccountCardMenuItem is module-private in nav-account-card.tsx, and the Account rows are written inline in NavAccountMenu as a button around an AvatarLabelGroup and a RadioButtonBase. Both Types are reachable only by opening a card. The sheet’s Menu item draws a <kbd> shortcut chip, which the kit does render — ⌘K→P, ⌘S and ⌥⇧Q.

_Nav featured card — 1157:90307

Used space

Your team has used 80% of your available space. Need more?

Type=Progress bar — A quota with a linear bar, and the two-link action row nine of the thirteen share.
80%

Used space

Your team has used 80% of your available space. Need more?

Type=Progress circle — The same card with ProgressBarCircle at xs, which draws its own percentage label.

New features available!

Check out the new dashboard view. Pages now load faster.

A short tour of the new dashboard
Type=Image — The kit's VideoPlayer at sm, with a poster and its own play affordance.

Cookie preferences

We use cookies to analyze traffic, remember preferences, and improve your experience.

Type=Cookie preferences — A modern FeaturedIcon, and the only card whose body carries an inline underline.

Refer a friend

Earn 50% back for 12 months when someone uses your link.

Type=Referral link — A read-only sm Input beside a link-gray copy button.

Complete account

Step 3 of 4

  • Complete your profile
  • Verify your phone number
  • Set up 2FA and backups
  • Add payout bank details
Type=Onboarding steps — The tallest Type: a step count, a bar, four check rows, and a full-width button. No dismiss.

Upgrade to PRO

20% OFF

Unlock 20+ integrations, 40 GB data, and advanced reporting.

Type=Upgrade CTA — The only card with a primary button, and a modern Badge beside its title.
Online

Need help with something?

Our experts are ready to help.

Type=Support CTA — Opens with a BadgeWithDot rather than an icon, and closes with a leading-icon button.
Attendee 1
Attendee 2
Attendee 3
Attendee 4
+5

Join our workshop

Live

Learn how to leverage Claude to supercharge your workflow.

Type=Event CTA — An AvatarGroup with a +5 overflow and an add button, over a Live badge.
Mathilde Lewis

Mathilde Lewis

2 mins ago

I’ve finished adding my notes. Happy for you to review!

Type=Message — A single md Avatar with its online status dot, a timestamp, and a reply link.
Type=Current projects — The only card whose body is a list of links, each with a utility-ramp dot.

Free trial

24 days left

Type=Free trial CTA — The shortest Type: a count, a bar, a button, and no dismiss.

Verify this device

Open the app and scan the QR code below to verify this device.

Type=QR code — The kit's QRCode plus GradientScan. It offers md (96px) and lg (128px); the sheet draws about 110, so md is the closer of the two.

Thirteen Types, and none of them is a kit component

Every sidebar that takes a card declares featureCard?: ReactNode — a bare slot — and the kit ships nothing to put in it. The thirteen above are page-local recipes in featured-cards.tsx, each composed from parts the kit already exports: ProgressBarBase, ProgressBarCircle, FeaturedIcon, Badge, Button, Input, Avatar, AvatarGroup, VideoPlayer and QRCode, over theme tokens only. They are documentation of the slot, not a proposal for eleven new components. Shell read from 1157:99074: bg-secondary at radius-xl with 16px padding.