docs / core / tabs
Tabs
one panel at a time, picked from a row of peer tabs. the active tab takes a single indicator, a pill or a hairline, never both.
intensity · recedesrsc · client
provenance
authored in usvalayer
core / primitivesintensity
recedes · safe anywhere, including dense surfacescomposition
settings and detail views where sections are true peersvertical orientation for a settings rail beside its panelsnot navigation between pages. tabs never change the urlnot for sequential steps. a wizard has order, tabs do nota11y
realtab / tabpanel roles · one tab stop into the list, arrows rove and activate · disabled tabs stay visible at 50%jest-axedependencies
@base-ui/reactlive demo · try it out
Manage your account details.
customize
variantpill surface or hairline underline
orientationrow of tabs or a side rail
activateOnFocusarrows switch panels as focus moves
disabledTabthe team tab stays visible at 50%
usage
import { Tabs } from "@usva-ui/react/primitives/tabs";
<Tabs defaultValue="account">
<Tabs.List>
<Tabs.Tab value="account">Account</Tabs.Tab>
<Tabs.Tab value="password">Password</Tabs.Tab>
<Tabs.Tab value="team">Team</Tabs.Tab>
</Tabs.List>
<Tabs.Panel value="account">Manage your account details.</Tabs.Panel>
<Tabs.Panel value="password">Change your password.</Tabs.Panel>
<Tabs.Panel value="team">Invite and manage teammates.</Tabs.Panel>
</Tabs>Tabs
| prop | type | default | notes |
|---|---|---|---|
| value | Value | null | — | controlled active tab. |
| defaultValue | Value | null | — | initial active tab when uncontrolled. |
| onValueChange | (value, eventDetails) => void | — | fires when the active tab changes. |
| orientation | "horizontal" | "vertical" | "horizontal" | vertical stacks the list and moves the indicator to its edge. |
Tabs.List
| prop | type | default | notes |
|---|---|---|---|
| variant | "pill" | "underline" | "pill" | pill slides a raised surface behind the tab; underline slides a hairline along the list edge. |
| activateOnFocus | boolean | true | arrow keys switch panels as focus moves, not on a second Enter. |
get it
bun add @usva-ui/reactusage
import { Tabs } from "@usva-ui/react/primitives/tabs";
<Tabs defaultValue="account">
<Tabs.List>
<Tabs.Tab value="account">Account</Tabs.Tab>
<Tabs.Tab value="password">Password</Tabs.Tab>
</Tabs.List>
<Tabs.Panel value="account">Manage your account details.</Tabs.Panel>
<Tabs.Panel value="password">Change your password.</Tabs.Panel>
</Tabs>