Tabs
Tabs organize related content into selectable panels. Use when users need to switch between peer sections.
Each TabsTrigger value must match one TabsContent value.
Basic usage
Section titled “Basic usage”Code
<Tabs defaultValue="summary"> <TabsList> <TabsTrigger value="summary">Summary</TabsTrigger> <TabsTrigger value="activity">Activity</TabsTrigger> </TabsList>
<TabsContent value="summary"> <p className="tw:text-sm tw:text-muted-foreground"> Green Valley Farm has 12 open orders and $12,450 outstanding. </p> </TabsContent>
<TabsContent value="activity"> <p className="tw:text-sm tw:text-muted-foreground"> Pricing was updated 2 hours ago by Maria Larsen. </p> </TabsContent></Tabs>Vertical
Section titled “Vertical”Code
<Tabs defaultValue="summary" orientation="vertical"> <TabsList> <TabsTrigger value="summary">Summary</TabsTrigger> <TabsTrigger value="products">Products</TabsTrigger> <TabsTrigger value="activity">Activity</TabsTrigger> </TabsList>
<TabsContent value="summary"> <p className="tw:text-sm tw:text-muted-foreground"> ORD-1042 includes 3 product lines for Friday delivery. </p> </TabsContent></Tabs>Code
<Tabs defaultValue="orders"> <TabsList variant="line"> <TabsTrigger value="orders">Orders</TabsTrigger> <TabsTrigger value="invoices">Invoices</TabsTrigger> <TabsTrigger value="activity">Activity</TabsTrigger> </TabsList>
<TabsContent value="orders" className="tw:pt-4"> <p className="tw:text-sm tw:text-muted-foreground"> 12 open orders are awaiting fulfillment review. </p> </TabsContent>
<TabsContent value="invoices" className="tw:pt-4"> <p className="tw:text-sm tw:text-muted-foreground"> 4 invoices are due within the next 7 days. </p> </TabsContent>
<TabsContent value="activity" className="tw:pt-4"> <p className="tw:text-sm tw:text-muted-foreground"> Last contact was logged yesterday by the sales team. </p> </TabsContent></Tabs>Selectable peer panels; use vertical orientation for side-by-side section nav.
| Name | Type/Description |
|---|---|
className | string | ((state: TabsRootState) => string | undefined) | undefinedCSS class applied to the element, or a function that returns a class based on the component's state. |
defaultValue = "0" | anyThe default value. Use when the component is not controlled. When the value is `null`, no Tab will be active. |
onValueChange | ((value: any, eventDetails: TabsRootChangeEventDetails) => void) | undefinedCallback invoked when new value is being set. The event `reason` is `'none'` for user-initiated changes, such as a click or keyboard navigation; `'initial'` for the first automatic selection or fallback in uncontrolled roots when `defaultValue` is omitted or `undefined`, including when the implicit initial value is disabled or missing; `'disabled'` for automatic fallback when the selected tab becomes disabled in uncontrolled roots; or `'missing'` for automatic fallback when the selected tab is removed, or when an explicit `defaultValue` never matches a mounted tab in uncontrolled roots. For automatic changes, the selected value can be `null` when no enabled Tab is available as a fallback. Automatic changes cannot be canceled; calling `eventDetails.cancel()` for `'initial'`, `'disabled'`, or `'missing'` has no effect. |
orientation = "horizontal" | Orientation | undefinedThe component orientation (layout flow direction). |
ref | ((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined |
render | ReactElement<any, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, TabsRootState> | undefinedAllows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render. |
style | CSSProperties | ((state: TabsRootState) => CSSProperties | undefined) | undefinedStyle applied to the element, or a function that returns a style object based on the component's state. |
value | anyThe value of the currently active `Tab`. Use when the component is controlled. When the value is `null`, no Tab will be active. |
TabsContent
Section titled “TabsContent”| Name | Type/Description |
|---|---|
className | string | ((state: TabsPanelState) => string | undefined) | undefinedCSS class applied to the element, or a function that returns a class based on the component's state. |
keepMounted = false | boolean | undefinedWhether to keep the HTML element in the DOM while the panel is hidden. |
ref | ((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined |
render | ReactElement<any, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, TabsPanelState> | undefinedAllows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render. |
style | CSSProperties | ((state: TabsPanelState) => CSSProperties | undefined) | undefinedStyle applied to the element, or a function that returns a style object based on the component's state. |
value | anyThe value of the TabPanel. It will be shown when the Tab with the corresponding value is active. |
TabsList
Section titled “TabsList”| Name | Type/Description |
|---|---|
activateOnFocus = false | boolean | undefinedWhether to automatically change the active tab on arrow key focus. Otherwise, tabs will be activated using <kbd>Enter</kbd> or <kbd>Space</kbd> key press. |
className | string | ((state: TabsListState) => string | undefined) | undefinedCSS class applied to the element, or a function that returns a class based on the component's state. |
loopFocus = true | boolean | undefinedWhether to loop keyboard focus back to the first item when the end of the list is reached while using the arrow keys. |
ref | ((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined |
render | ReactElement<any, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, TabsListState> | undefinedAllows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render. |
style | CSSProperties | ((state: TabsListState) => CSSProperties | undefined) | undefinedStyle applied to the element, or a function that returns a style object based on the component's state. |
variant = "default" | "line" | "default" | null | undefined |
TabsTrigger
Section titled “TabsTrigger”| Name | Type/Description |
|---|---|
className | string | ((state: TabsTabState) => string | undefined) | undefinedCSS class applied to the element, or a function that returns a class based on the component's state. |
disabled | boolean | undefinedWhether the Tab is disabled. If a first Tab on a `<Tabs.List>` is disabled, it won't initially be selected. Instead, the next enabled Tab will be selected. However, it does not work like this during server-side rendering, as it is not known during pre-rendering which Tabs are disabled. To work around it, ensure that `defaultValue` or `value` on `<Tabs.Root>` is set to an enabled Tab's value. |
nativeButton = true | boolean | undefinedWhether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `false` if the rendered element is not a button (for example, `<div>`). |
ref | ((instance: HTMLButtonElement | null) => void) | RefObject<HTMLButtonElement> | null | undefined |
render | ReactElement<any, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, TabsTabState> | undefinedAllows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render. |
style | CSSProperties | ((state: TabsTabState) => CSSProperties | undefined) | undefinedStyle applied to the element, or a function that returns a style object based on the component's state. |
value | anyThe value of the Tab. |