Tabs
<Tabs> rotates between sibling sub-views inside one page — Overview / Activity / Settings on a detail page, for example. Each tab owns a panel; only the active one renders.
When to use
- Detail pages with 2–5 logically-related sub-views.
- Settings sub-pages where switching is fast and stateless.
Don’t use Tabs for: navigation between top-level pages (URL change → real <a> links), step-driven flows (Stepper — planned), or 6+ choices (collapse with RightPanel or split into separate pages).
Default
Overview body content goes here.
<Tabs defaultValue="overview"> <TabsList> <TabsTrigger value="overview">Overview</TabsTrigger> <TabsTrigger value="activity">Activity</TabsTrigger> <TabsTrigger value="settings">Settings</TabsTrigger> </TabsList> <TabsContent value="overview">…</TabsContent> <TabsContent value="activity">…</TabsContent> <TabsContent value="settings">…</TabsContent></Tabs>Disabled tab
You see this. The other tab is disabled.
<TabsTrigger value="audit" disabled>Audit (admin only)</TabsTrigger>API
Tabs
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | Controlled active tab. Pair with onValueChange. |
defaultValue | string | — | Initial active tab for uncontrolled mode. |
onValueChange | (value: string) => void | — | Fires on tab change. |
orientation | "horizontal" | "vertical" | "horizontal" | Drives arrow-key navigation direction. |
activationMode | "automatic" | "manual" | "automatic" | automatic = arrow keys also activate. manual = arrow moves focus only; Enter activates. |
TabsList / TabsTrigger / TabsContent
TabsTrigger requires value. TabsContent requires the matching value.
Design guidelines
✓ Do
- Persist the active tab to the URL when reload-survival matters (e.g., ?tab=activity).
- Lazy-mount expensive panels — content for inactive tabs need not render eagerly.
- Order tabs by the user's frequency of use, left to right.
✗ Don't
- Use Tabs as page-level navigation. Tabs are sub-views; navigation belongs in URL.
- Hide critical state behind a tab. Anything the user might miss should be on the default tab.
- Add 6+ tabs. The TabsList overflows ungracefully; reach for a layout with a sidebar.
Accessibility
- Composes Radix Tabs —
role="tablist",tabitems,tabpanelcontent. Arrow keys move between tabs; Enter / Space activates in manual mode. - Each
TabsContentis automaticallyaria-labelledbyits corresponding trigger.
Related
Stepper— Linear flow (planned).SegmentedControl— When the choice axis is data, not view.