Prepared Docs

Prepared Docs

⌘K

    Loading navigation…

User

  1. Components
  2. Tabs
  3. Usage

Tabs

Usage

Overview

Tabs pairs triggers with linked content panels on a single route. It fits settings categories, incident summaries with peer sections, and dashboards where each tab reveals closely related content without an additional navigation hop. The mental model is "peer sections that share context"—if the content belongs on separate routes or users expect bookmarkable URLs per panel, reach for TabNav instead. Tabs is the pattern that stays on one URL; the triggers and panels are programmatically associated for assistive technologies so the label, state, and content are announced together.

Live transcript of the active call updates here in real time.

When to use

For peer sections that share an entity or task

Incident detail split across "Summary", "Transcript", and "Metadata"; settings panels grouped into "General", "Privacy", and "Integrations"; a QA form that splits scoring, evidence, and notes. Operators switch among panels frequently while the entity in focus stays the same.

For dashboards that swap visualization without losing context

Tabs let an operator flip between "Calls", "Shifts", and "Incidents" views of the same time range without navigating away. The shared control bar (filters, time range) stays visible across panels.

For compact surfaces that can't host sidebars or long stacks

On narrow dispatch rails and mobile, tabs are a small-footprint way to offer three to seven peer views.

When not to use

For filters that only change data on the same canvas

Use TabMenu. Tabs create linked content panels; a filter strip changes what a single panel renders.

For navigation to distinct routes

Use TabNav. Users expect a link-based component to change the URL and be bookmarkable; tabs imply a single-route container.

For more than about seven panels

Seven is already crowded. Above that, restructure the information architecture: a sidebar, a stepped flow, or nested pages.

For stacked progressive disclosure

Use Accordion when the mental model is "a tall list where I open a couple of sections", not "a row of peer panels I switch between."

Variants

AxisValuesWhen to pick it
Orientationhorizontal, verticalHorizontal for short label lists atop panels; vertical when labels are long or sit beside a single wide panel
Stateuncontrolled (defaultValue) or controlled (value + onValueChange)Controlled when panel changes drive analytics, URL state, or cross-panel validation

Composition

Tabs wraps a TabsList of TabsTrigger buttons followed by one TabsContent panel per value. Labels sit in the trigger; optional counts use the counter affordance so operators can see magnitude without opening the tab. Keep labels short and parallel; verbose labels crowd the list and push counts off-screen.

Content guidelines

  • Short, parallel labels. "Calls", "Shifts", "Incidents"—not "All calls", "Shift history", "Incident records".
  • Counts use the counter prop; do not bake numbers into label text, where translations will break the rhythm.
  • Localize labels with formatMessage. Even short English labels lengthen in German or French; test the longest expected translation inside the list width.
  • Use sentence case for labels per product typography conventions.

Behavior and states

  • Uncontrolled. defaultValue covers static settings views where no other UI depends on the active tab.
  • Controlled. value + onValueChange when syncing to URL params, analytics, or cross-panel validation. Drive the value from the source of truth; do not fork state across two parents.
  • Entity changes. Reset the active tab when the underlying entity changes (new record id). Otherwise the operator opens a new incident and sees the last incident's tab highlighted with a fresh panel's content—a classic stale-state bug.
  • Lazy mounting. Heavy panels (charts, transcripts, long-running queries) can mount on first activation. Ensure focus still moves into the panel once it finishes mounting; otherwise keyboard users land in limbo.

Best practices

Do

  • Order tabs by frequency or workflow sequence, not alphabetically. Operators pick up the rhythm within a shift.
  • Keep the set stable across sessions. Tabs that appear or disappear per user feel buggy even when they're correct.
  • Preserve active tab state across re-renders within the same entity. Losing the tab on every parent update is disorienting.

Don't

  • Hide required fields exclusively in inactive tabs without a summary indicator on submit. Operators will submit with missing data and not know why.
  • Mix unrelated domains in one tab set ("Settings" next to "Recent activity" next to "Help"). The peer-sections mental model breaks.
  • Nest tabs inside tabs. The inner tablist confuses assistive technology and signals an IA problem.
  • Animate tab transitions so slowly that operators perceive the UI as stuck.

Accessibility

Radix implements the WAI-ARIA Tabs pattern: tablist, tab, and tabpanel roles with arrow-key navigation and focus management. The app still supplies the list's accessible name and the trigger labels. See Accessibility for the full keyboard map, announcement sequences, and labelling patterns.

Related Components

  • TabMenu for button-style filter strips that change a single canvas.
  • TabNav for link-based navigation across routes.
  • Accordion for stacked disclosure instead of peer panels.
  • Sidebar for primary navigation.

Previous

Accessibility / Alignment Accessibility

Next

Tabs / API and Development

On this page

Overview
When to use
For peer sections that share an entity or task
For dashboards that swap visualization without losing context
For compact surfaces that can't host sidebars or long stacks
When not to use
For filters that only change data on the same canvas
For navigation to distinct routes
For more than about seven panels
For stacked progressive disclosure
Variants
Composition
Content guidelines
Behavior and states
Best practices
Accessibility
Related Components