Tabs are implemented using a collection of related components:
<Tabs.Root /> is a top-level component that wraps the Tabs List and Tab Panel components so that tabs and their panels can communicate with one another.
<Tabs.Tab /> is the tab element itself. Clicking on a tab displays its corresponding panel.
<Tabs.List /> is the container that houses the tabs. Responsible for handling focus and keyboard navigation between tabs.
<Tabs.Panel /> is the card that hosts the content associated with a tab.
<Tabs.Indicator /> is an optional active tab indicator.
By default, Tab components and their corresponding panels are zero-indexed.
The first tab has a value of 0, the second tab has a value of 1, and so on.
Activating a tab opens the panel with the same value, corresponding to the order in which each component is nested within its container.
Though not required, you can add the value prop to the Tab and Tab Panel to control how these components are associated.
Though it's optional, the Tabs.Indicator component can be added to implement a visual indicator for the active tab.
To help with styling—in particular animating its position—some CSS variables are provided.
--active-tab-top is the distance in px between the top of the active tab and the top of the Tabs.Panel's bounding box.
--active-tab-bottom is the distance in px between the bottom of the active tab and the bottom of the Tabs.Panel's bounding box.
--active-tab-left is the distance in px between the left-hand edge of the active tab and the left-hand edge of the Tabs.Panel's bounding box.
--active-tab-right is the distance in px between the right-hand edge of the active tab and the right-hand edge of the Tabs.Panel's bounding box.
--active-tab-width is the width in px of the active tab's bounding box.
--active-tab-height is the height in px of the active tab's bounding box.
Additionally, the Indicator has the data-activation-direction attribute representing the relation of the selected tab to the previously selected one.
Its value is one of the following:
left when the active tab is to the left of the previously active tab (only applied when orientation=horizontal).
right when the active tab is to the right of the previously active tab (only applied when orientation=horizontal).
top when the active tab is above the previously active tab (only applied when orientation=vertical).
bottom when the active tab is below the previously active tab (only applied when orientation=vertical).
none when there is no previously selected tab.
This example uses the CSS variables and data attributes described above to create an "elastic" movement effect.
The next example shows a differently shaped Indicator with a simpler movement.
As the transition is independent of direction, the data-activation-direction attribute is not used for styling.
The Indicator's rendering depends on React effects and cannot be done on the server.
This means that if you're using server-side rendering (SSR), the initially rendered content will not contain the Indicator.
It will appear after React hydrates the components.
If you want to minimize the time the Indicator is not visible, you can set the renderBeforeHydration prop to true.
This will make the component include an inline script that sets the CSS variables as soon as it's rendered by the browser.
<Tabs.Indicator renderBeforeHydration />
It is disabled by default, as the script contributes to the size of the payload sent by the server.
To arrange tabs vertically, set orientation="vertical" on the <Tabs /> component.
Now, the user can navigate with the up and down arrow keys rather than the default left-to-right behavior for horizontal tabs.
Tabs can be rendered as links to routes in your application.
A common use case for tabs is implementing client-side navigation that doesn't require an HTTP round-trip to the server.
By default, when using keyboard navigation, tabs are activated automatically when they receive focus.
Alternatively, you can set activateOnFocus={false} on <Tabs.List> so tabs are not activated automatically when they receive focus.
Class names applied to the element or a function that returns them based on the component's state.
defaultValue
any
0
The default value. Use when the component is not controlled. When the value is null, no Tab will be selected.
direction
enum
'ltr'
The direction of the text.
onValueChange
func
Callback invoked when new value is being set.
orientation
enum
'horizontal'
The component orientation (layout flow direction).
render
union
A function to customize rendering of the component.
value
any
The value of the currently selected Tab. Use when the component is controlled. When the value is null, no Tab will be selected.
TabPanel
Prop
Type
Default
Description
className
union
Class names applied to the element or a function that returns them based on the component's state.
keepMounted
bool
false
If true, keeps the contents of the hidden TabPanel in the DOM.
render
union
A function to customize rendering of the component.
value
any
The value of the TabPanel. It will be shown when the Tab with the corresponding value is selected. If not provided, it will fall back to the index of the panel. It is recommended to explicitly provide it, as it's required for the tab panel to be rendered on the server.
Tab
Prop
Type
Default
Description
className
union
Class names applied to the element or a function that returns them based on the component's state.
render
union
A function to customize rendering of the component.
value
any
The value of the Tab. When not specified, the value is the child position index.
TabsList
Prop
Type
Default
Description
activateOnFocus
bool
true
If true, the tab will be activated whenever it is focused. Otherwise, it has to be activated by clicking or pressing the Enter or Space key.
className
union
Class names applied to the element or a function that returns them based on the component's state.
loop
bool
true
If true, using keyboard navigation will wrap focus to the other end of the list once the end is reached.
render
union
A function to customize rendering of the component.
TabIndicator
Prop
Type
Default
Description
className
union
Class names applied to the element or a function that returns them based on the component's state.
render
union
A function to customize rendering of the component.
renderBeforeHydration
bool
false
If true, the indicator will include code to render itself before React hydrates. This will minimize the time the indicator is not visible after the SSR-generated content is downloaded.