Rost
← All components
component

Navigation

A side navigation on frosted glass. The logo at the top, the main items below it, one action at the bottom. Collapsed to icons, or open with labels.

In codeContract: reviewGuidance: agreedContract on GitHubFigma 356:949

When to use

  • Used as the main navigation of an app, down the side: a few top-level places, and one action that matters everywhere.

When not to use

  • More than a handful of items. It's for the top level only.
  • A website's header nav. That runs across the top.

Behaviour

collapsed is icons only, 72px wide; open is 160px with labels. The items are ListItems: the current one is selected. The action is an IconButton when collapsed and a Button when open.

Accessibility

  • Element: a <nav> with an aria-label. The current item has aria-current="page".
  • Name: the aria-label on the <nav>, like "Main". Each item is named by its label.
  • Collapsed: icon-only items need an aria-label, since there's no visible text.
  • Keyboard: Tab goes through the items in order, then the action. Nothing custom, since they're links and a button.
  • Focus: each ListItem's own focus-ring.
  • Contrast: the plate is see-through, so check the labels against what's behind it, not just the page colour.

Content

One or two words per item, nouns. The action says what it does.

Props

PropTypeValuesDefault
collapsedbooleanfalse
logoslot
mainslot
actionslot

Values

Straight from the contract. Each value sits next to its token, because six tokens here all come out as #3a3a3a and the colour alone can't tell you which one is right.

Never changes

PartPropertyValueToken
rootdisplayflexlayout
rootflex-directioncolumnlayout
rootjustify-contentspace-betweenlayout
rootalign-itemsflex-startlayout
rootpositionrelativelayout
rootoverflowhiddenlayout
rootheight100%layout
rootpadding-top16pxspacing/gap/medium
rootpadding-bottom16pxspacing/gap/medium
rootborder-radius24pxspacing/radius/xlarge
backgroundpositionabsolutelayout
backgroundinset0layout
backgroundpointer-eventsnoneFigma frame size
backgroundbackgroundcolor-mix(in srgb, var(--non-interactive-background-primary) 48%, transparent)on purpose: Figma's fill is a plain #060805 at 48%: `non-interactive/background/primary` at `opacity/medium`, though Figma doesn't bind either.
backgroundbackdrop-filterblur(12px)effect/thumb
logodisplayflexlayout
logoflex-shrink0layout
logopositionrelativelayout
logowidth40pxspacing/size/medium
logoheight40pxspacing/size/medium
maindisplayflexlayout
mainflex-directioncolumnlayout
mainpositionrelativelayout
mainwidth100%layout
maingap8pxspacing/gap/small
actiondisplayflexlayout
actionflex-directioncolumnlayout
actionpositionrelativelayout
actionwidth100%layout
actiongap8pxspacing/gap/small

Changes by variant

root.align-items1
collapsed=Truecenterlayout
root.padding-left2
collapsed=True12pxspacing/gap/small-medium
collapsed=False16pxspacing/gap/medium
root.padding-right2
collapsed=True12pxspacing/gap/small-medium
collapsed=False16pxspacing/gap/medium
root.width2
collapsed=True72pxspacing/size/2xlarge
collapsed=False160pxon purpose: Figma's own 160px; no size token is 160.