Tabs
Tabs switches between sibling panels — a row of tabs, exactly one panel visible at a time, the arrow keys moving between them.
What it is
A compound component with four parts. Tabs.Root owns the active value. Tabs.List is the
role="tablist" row. Tabs.Tab is one role="tab" button. Tabs.Panel is the matching
role="tabpanel". A tab and its panel are linked by their shared value.
Install
Anatomy
API
Tabs.Root
Tabs.Root
stablefunction Tabs.Root(props: TabsRootProps): JSX.Element
Controlled active-tab value. Pass alongside `onValueChange`.
Initial active-tab value for the uncontrolled mode.
Called when the active tab changes.
Tab-list orientation. Decides whether the left/right or up/down arrows move between tabs.
The List and Panel parts.
Tabs.List
The role="tablist" container. Takes children and style; aria-orientation is set from the
Root's orientation.
Tabs.Tab
Tabs.Tab
stablefunction Tabs.Tab(props: TabsTabProps): JSX.Element
Links this tab to the panel with the same value.
Skip the tab in arrow-key navigation and ignore activation.
Inline style for the tab button.
The tab label.
Tabs.Panel
Tabs.Panel
stablefunction Tabs.Panel(props: TabsPanelProps): JSX.Element | null
Links this panel to the tab with the same value.
Keep the panel mounted when inactive — hidden via the `hidden` attribute. Use it to preserve panel state across tab switches.
The panel content.
Inline style for the panel.
Keyboard
| Key | Action |
|---|---|
| Arrow Left / Right (horizontal) | Move to the previous / next tab, wrapping |
| Arrow Up / Down (vertical) | Move to the previous / next tab, wrapping |
| Home / End | Move to the first / last tab |
Moving to a tab both focuses and activates it — the matching panel shows immediately.
Accessibility
Tabs implements the WAI-ARIA tabs pattern. The list is role="tablist", each tab is role="tab"
with aria-selected, each panel is role="tabpanel" labelled by its tab. Only the active tab is
in the Tab order — tabIndex is 0 on it and -1 on the rest — so a keyboard user tabs into the
list once, then uses the arrow keys, and tabs straight out to the panel.
By default an inactive panel is unmounted. forceMount keeps it mounted with the hidden
attribute, which preserves its internal state — a half-filled form, a scroll position — across
tab switches.
Examples
A settings panel: