Tabs
Switches between related panels of content in one place.
Installation
pnpm dlx shadcn@latest add @paneui/tabsUsage
Composition
Examples
Motion
The indicator slides over 300ms ease-out. Under prefers-reduced-motion: reduce it jumps without sliding.
Keyboard
ArrowLeft / ArrowRight (or ArrowUp / ArrowDown when vertical) move focus between tabs (looping), Home / End jump to the ends, and Enter or Space activates the focused tab.
API Reference
Built on the Tabs primitive. Only the props this library adds or changes are listed; everything else passes through.
Tabs
Column wrapper with a 12px gap between list and panels; a row when vertical. Also accepts every prop of Tabs.Root.
- defaultValue= 0
- any
- Tab selected on first render.
- value
- any
- Controlled selected tab.
- orientation= "horizontal"
- "horizontal" | "vertical"
- Lays the list out as a row or a column; the indicator and arrow keys follow it.
- onValueChange
- (value: any, eventDetails) => void
- Called when the selected tab changes.
| Prop | Type | Default | Description |
|---|---|---|---|
| defaultValue | any | 0 | Tab selected on first render. |
| value | any | — | Controlled selected tab. |
| orientation | "horizontal" | "vertical" | "horizontal" | Lays the list out as a row or a column; the indicator and arrow keys follow it. |
| onValueChange | (value: any, eventDetails) => void | — | Called when the selected tab changes. |
TabsList
Segmented track. Renders the sliding indicator after its children. Also accepts every prop of Tabs.List.
- size= "default"
- "xs" | "sm" | "default" | "lg"
- Height 24 / 28 / 32 / 36px for the list, the Button heights. Applies to every tab.
- variant= "default"
- "default" | "underline"
defaultis a raised indicator on a well;underlineis a 2px bar on a hairline.- activateOnFocus= false
- boolean
- Select a tab as soon as it receives keyboard focus.
- loopFocus= true
- boolean
- Wrap arrow-key focus at the ends.
| Prop | Type | Default | Description |
|---|---|---|---|
| size | "xs" | "sm" | "default" | "lg" | "default" | Height 24 / 28 / 32 / 36px for the list, the Button heights. Applies to every tab. |
| variant | "default" | "underline" | "default" | default is a raised indicator on a well; underline is a 2px bar on a hairline. |
| activateOnFocus | boolean | false | Select a tab as soon as it receives keyboard focus. |
| loopFocus | boolean | true | Wrap arrow-key focus at the ends. |
- data-size
- The
sizevalue. - data-variant
- The
variantvalue.
| Data attribute | Description |
|---|---|
| data-size | The size value. |
| data-variant | The variant value. |
TabsTab
Sizes its icons to 16px. Also accepts every prop of Tabs.Tab.
- value*
- any
- Matches the
TabsPanelit shows. - disabled= false
- boolean
- Dim the tab, block selection and skip it in the keyboard order.
| Prop | Type | Default | Description |
|---|---|---|---|
| value* | any | — | Matches the TabsPanel it shows. |
| disabled | boolean | false | Dim the tab, block selection and skip it in the keyboard order. |
- data-active
- Present on the selected tab.
- data-disabled
- Present when disabled.
- data-orientation
horizontalorvertical, from the root.
| Data attribute | Description |
|---|---|
| data-active | Present on the selected tab. |
| data-disabled | Present when disabled. |
| data-orientation | horizontal or vertical, from the root. |
TabsPanel
Also accepts every prop of Tabs.Panel.
- value*
- any
- The
TabsTabvalue that shows this panel. - keepMounted= false
- boolean
- Keep the panel in the DOM while hidden.
- typeset= false
- boolean | "docs" | "reading" | "chat"
- Turn prose styles back on for the panel content inside a
typesetcontainer, or name a preset when it stands alone.
| Prop | Type | Default | Description |
|---|---|---|---|
| value* | any | — | The TabsTab value that shows this panel. |
| keepMounted | boolean | false | Keep the panel in the DOM while hidden. |
| typeset | boolean | "docs" | "reading" | "chat" | false | Turn prose styles back on for the panel content inside a typeset container, or name a preset when it stands alone. |