Tabs
A set of panels that lets users switch between related content.
Tabs divide related content into panels and show one panel at a time. Each trigger names its panel, so users can scan the list and open only the content they need.
Usage
Examples
Line
A page divided into sections, such as the stock, staff and revenue of one store, needs navigation that does not compete with its content. With variant set to "line", the list recedes behind those sections and only the active trigger keeps its emphasis, so users still see where they are.
Muted
Inside a card, tabs often switch between views of the same figures, such as a week and a month. Here, variant set to "muted" lets the list blend into the card, while the active trigger stays marked and tells users which view they are reading.
Vertical
Longer sets of panels, such as the settings of a store, need more triggers than one row holds comfortably. Set to "vertical", orientation places the list beside the content and stacks its triggers, so the list grows with every new panel and users scan it from top to bottom.
With Icon
Users who return to the same panels throughout the day learn to find a trigger by its icon before they read its name. The name still carries the meaning, so each trigger remains clear for those who meet the tabs for the first time.
Controlled
Other parts of an interface sometimes need to open a specific panel, for example a notification that leads users straight to the deliveries of the day. Through value and onValueChange, the application holds the active trigger, so it can switch panels on its own and restore the panel users chose last.
Disabled Trigger
Some panels have nothing to show yet, such as a daily report that exists only once the store has closed. A trigger that carries disabled stays within reach of the arrow keys and exposes its state to assistive technology, yet users cannot activate it, so they know the panel exists without opening it by mistake.
API Reference
Tabs
| Prop | value |
|---|---|
| Type | any |
| Default | – |
| Description | Sets the value of the active trigger and makes the tabs controlled. Update it in onValueChange. With null, no trigger is active. |
| Prop | defaultValue |
|---|---|
| Type | any |
| Default | 0 |
| Description | Sets the value of the trigger that is active at first render. The tabs then track the active trigger themselves. If no trigger has this value, the tabs activate the first enabled trigger. With null, no trigger is active. |
| Prop | onValueChange |
|---|---|
| Type | (value: any, eventDetails: TabsRootChangeEventDetails) => void |
| Default | – |
| Description | Runs when users activate another trigger. It receives the value of that trigger. Uncontrolled tabs also run it when they choose the active trigger themselves: at first render without defaultValue, and whenever the active trigger is missing or disabled. The reason in eventDetails tells these cases apart. |
| Prop | orientation |
|---|---|
| Type | "horizontal" | "vertical" |
| Default | "horizontal" |
| Description | Sets the direction of the layout. Horizontal places the list above the content, vertical places the list beside the content and stacks its triggers. The left and right arrow keys move through the triggers of a horizontal list, the up and down arrow keys those of a vertical list. |
| Prop | render |
|---|---|
| Type | ReactElement | render function |
| Default | – |
| Description | Replaces the native element or composes the tabs with another component. |
TabsList
| Prop | variant |
|---|---|
| Type | "default" | "line" | "muted" |
| Default | "default" |
| Description | Sets how the list shows the active trigger. "default" places the triggers on a muted bar and raises the active one above it. "line" removes the bar and draws a line under the active trigger, or beside it in vertical tabs. "muted" removes the bar and fills the active trigger with the muted color. |
| Prop | activateOnFocus |
|---|---|
| Type | boolean |
| Default | false |
| Description | Activates a trigger as soon as it receives focus, so the arrow keys change the content directly. Without it, users press Enter or Space to activate the focused trigger. |
| Prop | loopFocus |
|---|---|
| Type | boolean |
| Default | true |
| Description | Moves focus from the last trigger to the first, and from the first to the last, when users keep pressing the arrow keys. With false, focus stops at both ends. |
| Prop | render |
|---|---|
| Type | ReactElement | render function |
| Default | – |
| Description | Replaces the native element or composes the list with another component. |
TabsTrigger
| Prop | value |
|---|---|
| Type | any |
| Default | – |
| Description | Identifies the trigger in value, defaultValue and onValueChange of the tabs, and connects it to the TabsContent with the same value. Every trigger needs one. |
| Prop | render |
|---|---|
| Type | ReactElement | render function |
| Default | – |
| Description | Replaces the native element or composes the trigger with another component. |
| Prop | nativeButton |
|---|---|
| Type | boolean |
| Default | true |
| Description | Declares whether the rendered element is a native button. Set it to false when render returns a different element. |
| Prop | disabled |
|---|---|
| Type | boolean |
| Default | false |
| Description | Prevents users from activating the trigger and exposes the disabled state to assistive technology. The arrow keys still move to it. |
TabsContent
| Prop | value |
|---|---|
| Type | any |
| Default | – |
| Description | Connects the content to the TabsTrigger with the same value. The tabs show the content while that trigger is active. Every content needs one. |
| Prop | keepMounted |
|---|---|
| Type | boolean |
| Default | false |
| Description | Keeps the content in the DOM while another trigger is active, hidden from users. Without it, the tabs render only the active content. |
| Prop | render |
|---|---|
| Type | ReactElement | render function |
| Default | – |
| Description | Replaces the native element or composes the content with another component. |