Peer views in one place; one visible, all reachable.
| Prop / event | Type | Notes |
|---|---|---|
| variant | line · pill · enclosed | Indicator style; line is the default |
| size | S · M · L | Tab scale; M is the default |
| value / onChange | string / (v) => void | The active tab; controlled or default |
| count | number | Optional pill riding in a tab |
| disabled (tab) | boolean | Unreachable, skipped by the arrow keys |
| ← / → · Home / End | — | Roving focus between tabs; Home/End jump to the ends |
Tabs switch peer views inside one page. To move between pages of a list use Pagination; for top-level wayfinding use the nav.
Two to five short, parallel labels. One noun each; they scan as a set.
Don't route the whole app through tabs. Navigation and sign-out aren't peer views.
Use the pill variant for a short, toggle-like set of mutually exclusive modes.
Don't overflow tabs off the edge. Too many peers wants a nav or a menu.
Line tabs sit at the top of a card, the panel content directly below.
Pill tabs act as a compact view switcher in a toolbar.
Folder tabs read as a container the active tab belongs to.
| Token | Value | Role |
|---|---|---|
| --tab-gap | 24px | Space between line tabs |
| --tab-indicator | 2px · #FF7A00 | Sliding active underline |
| --tab-idle | #9AA0A8 | Inactive label |
| --tab-active | #F4F5F6 | Active label |
| --tab-tray | #101114 | Pill variant background |
| --tab-active-fill | #1F1F25 | Pill / enclosed active fill |
<div class="o-tabs o-tabs--line" role="tablist">
<button role="tab" aria-selected="true" class="o-tab is-active">Overview</button>
<button role="tab" aria-selected="false" class="o-tab">
Activity <span class="o-tab__count">3</span>
</button>
<button role="tab" aria-selected="false" class="o-tab">Settings</button>
</div>
<div role="tabpanel">…</div>