Skip to content
HyperDesign System

Tabs

Switch between views of the same thing without leaving the page. The default list is a tint track with the active tab lifted onto the canvas; line is text with an ink rule. Source: src/components/ui/tabs.tsx.

Default

A 36px pill track. Click a tab, or focus the list and use the arrow keys; Home and End jump to the ends.

Weekly digest

Summarises every thread in #eng-updates and posts on Monday at 09:00.

Line

variant="line" on TabsList drops the track. The active tab gets a 2px ink rule that fades in; it does not slide between tabs.

Preview

The rendered output of the last run.

With icons and counts

Leading icons at 16px, marked data-icon="inline-start" so the padding trims. A trailing Badge carries a count.

Preview

What the agent will post.

Vertical and disabled

orientation="vertical" puts the list beside the panel, for settings-style navigation. A disabled trigger is skipped by the arrow keys.

General

Workspace name, default model and time zone.

Props

Tabs props
PropTypeDefaultDescription
defaultValue / valuestring—Tabs (Radix). The open tab, uncontrolled or controlled; pair value with onValueChange.
orientation"horizontal" | "vertical""horizontal"Tabs. Lays the list beside the content and switches arrow keys to up/down.
activationMode"automatic" | "manual""automatic"Tabs (Radix). manual waits for Enter or Space before switching; use it when a panel is costly to render.
variant"default" | "line""default"TabsList. A tint track with a lifted pill, or text tabs with an ink rule. Mirrored as data-variant.
value, disabledstring, boolean—TabsTrigger. Each trigger's value matches one TabsContent.
forceMounttrue—TabsContent (Radix). Keep an inactive panel in the DOM, e.g. to preserve its scroll or form state.
...propsRadix Tabs parts—Native attributes pass through; className merges last on every part.

Best practices

When to use

  • Two to five peer views of one object: overview / runs / settings. Each panel should make sense alone.
  • Not for steps in a sequence (use a stepper or separate pages) and not for filters that combine (use a ToggleGroup or chips).
  • If a tab should be linkable or survive a reload, make it a route and use links, not Tabs.

Behavior

  • Switching is instant. The pill fill and the line rule fade on the normal duration; nothing slides.
  • Inactive panels unmount by default, so their state resets. Use forceMount, or lift state up, when that matters.
  • Labels never change weight on select (all triggers are medium), so the row doesn't shift.

Accessibility

  • Radix wires tablist, tab and tabpanel roles, aria-selected and aria-controls.
  • Focus moves with the arrow keys; Tab leaves the list and enters the active panel.
  • Icon-only triggers need an aria-label.

Content

  • One or two words per tab, nouns, sentence case.
  • Keep the order stable. Don't hide or reorder tabs based on content; disable instead and say why nearby.