Tabs
Accessible React tabs built on Radix with a roving tablist, icons, full-width and flush styles, overflow handling, and Arabic labels. Arrow keys move between tabs.
Each TabsTrigger pairs with a TabsContent by value; defaultValue picks the first panel and arrow keys move between tabs.
When to use
Use Tabs to split one page into related panels that share context, such as a request's details, documents, and history. Keep tab labels to one or two words and put the default panel first.
For switching views of the same data, use ContentSwitcher. For long content that all needs to be visible, use headings and Accordion.
Examples
Props
Props declared by Tabs. Native attributes of the underlying element pass through.
<Tabs>
| Prop | Type | Default | Description |
|---|---|---|---|
size | "sm" | "md" | "lg" | ||
asChild | boolean | ||
value | string | The value for the selected tab, if controlled | |
defaultValue | string | The value of the tab to select by default, if uncontrolled | |
onValueChange | (value: string) => void | A function called when a new tab is selected | |
orientation | "vertical" | "horizontal" | horizontal | The orientation the tabs are layed out. Mainly so arrow navigation is done accordingly (left & right vs. up & down) |
dir | Direction | The direction of navigation between toolbar items. | |
activationMode | "manual" | "automatic" | automatic | Whether a tab is activated automatically or manually. |
<TabsList>
| Prop | Type | Default | Description |
|---|---|---|---|
fullWidth | boolean | ||
flush | boolean | ||
overflow | boolean | Collapse tabs that don't fit into a trailing "More" overflow menu (SDGA "More Tab"). Horizontal lists only - the list fills its container's inline size and pushes the overflow trigger to the trailing edge. | |
moreLabel | string | Accessible name for the overflow trigger when overflow is set. | |
asChild | boolean | ||
loop | boolean |
<TabsTrigger>
| Prop | Type | Default | Description |
|---|---|---|---|
startIcon | react.ReactNode | Leading icon, rendered before the label in a decorative (aria-hidden)
wrapper. Ignored when asChild is set - compose icons inside your own
element in that mode. | |
endIcon | react.ReactNode | Trailing icon (e.g. a count/badge glyph). Same rules as startIcon. | |
asChild | boolean | ||
valuerequired | string |
<TabsContent>
| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | ||
valuerequired | string | ||
forceMount | true | Used to force mounting when more control is needed. Useful when controlling animation with React animation libraries. |
Accessibility
Tabs follow the tabs pattern: role="tablist", role="tab", and role="tabpanel" with the selected tab exposed. The arrow keys move focus between tabs, Home and End jump to the ends, and the arrow keys follow the reading direction in RTL.
Give the list an aria-label. Overflowing tabs move into a "More" menu whose label you control with moreLabel.