Native Solid 2 fork. Original documentation and designs © WorkOS; historical posts retain their original context.
Tabs
A set of layered sections of content—known as tab panels—that are displayed one at a time.
Make changes to your account here. Click save when you're done.
import { Tabs } from "@radix-solid/primitives";
import styles from "./styles.module.css";
const TabsDemo = () => <Tabs.Root class={styles.Root} defaultValue="tab1">
<Tabs.List class={styles.List} aria-label="Manage your account">
<Tabs.Trigger class={styles.Trigger} value="tab1">
Account
</Tabs.Trigger>
<Tabs.Trigger class={styles.Trigger} value="tab2">
Password
</Tabs.Trigger>
</Tabs.List>
<Tabs.Content class={styles.Content} value="tab1">
<p class={styles.Text}>
Make changes to your account here. Click save when you're done.
</p>
<fieldset class={styles.Fieldset}>
<label class={styles.Label} for="name">
Name
</label>
<input class={styles.Input} id="name" defaultValue="Pedro Duarte" />
</fieldset>
<fieldset class={styles.Fieldset}>
<label class={styles.Label} for="username">
Username
</label>
<input class={styles.Input} id="username" defaultValue="@peduarte" />
</fieldset>
<div style={{
"display": "flex",
"margin-top": "20px",
"justify-content": "flex-end"
}}>
<button class={`${styles.Button} green`}>Save changes</button>
</div>
</Tabs.Content>
<Tabs.Content class={styles.Content} value="tab2">
<p class={styles.Text}>
Change your password here. After saving, you'll be logged out.
</p>
<fieldset class={styles.Fieldset}>
<label class={styles.Label} for="currentPassword">
Current password
</label>
<input class={styles.Input} id="currentPassword" type="password" />
</fieldset>
<fieldset class={styles.Fieldset}>
<label class={styles.Label} for="newPassword">
New password
</label>
<input class={styles.Input} id="newPassword" type="password" />
</fieldset>
<fieldset class={styles.Fieldset}>
<label class={styles.Label} for="confirmPassword">
Confirm password
</label>
<input class={styles.Input} id="confirmPassword" type="password" />
</fieldset>
<div style={{
"display": "flex",
"margin-top": "20px",
"justify-content": "flex-end"
}}>
<button class={`${styles.Button} green`}>Change password</button>
</div>
</Tabs.Content>
</Tabs.Root>;
export default TabsDemo;Features
Can be controlled or uncontrolled.
Supports horizontal/vertical orientation.
Supports automatic/manual activation.
Full keyboard navigation.
Anatomy
Import all parts and piece them together.
import { Tabs } from "@radix-solid/primitives";
export default () => <Tabs.Root>
<Tabs.List>
<Tabs.Trigger value="overview">Overview</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="overview" />
</Tabs.Root>;API Reference
Root
Contains all the tabs component parts.
| Prop | Type | Default |
|---|---|---|
asChildRender through a single-target factory, merging props and behavior with the chosen host.Read our Composition guide for more details. | boolean | false |
defaultValueThe value of the tab that should be active when initially rendered. Use when you do not need to control the state of the tabs. | string | — |
valueThe controlled value of the tab to activate. Should be used in conjunction with onValueChange. | string | — |
onValueChangeEvent handler called when the value changes. | function | — |
orientationThe orientation of the component. | enum | "horizontal" |
dirThe reading direction of the tabs. If omitted, inherits globally from DirectionProvider or assumes LTR (left-to-right) reading mode. | enum | — |
activationModeWhen automatic, tabs are activated when receiving focus. When manual, tabs are activated when clicked. | enum | "automatic" |
| Data attribute | Values |
|---|---|
[data-orientation] | "vertical" | "horizontal" |
List
Contains the triggers that are aligned along the edge of the active content.
| Prop | Type | Default |
|---|---|---|
asChildRender through a single-target factory, merging props and behavior with the chosen host.Read our Composition guide for more details. | boolean | false |
loopWhen true, keyboard navigation will loop from last tab to first, and vice versa. | boolean | true |
| Data attribute | Values |
|---|---|
[data-orientation] | "vertical" | "horizontal" |
Trigger
The button that activates its associated content.
| Prop | Type | Default |
|---|---|---|
asChildRender through a single-target factory, merging props and behavior with the chosen host.Read our Composition guide for more details. | boolean | false |
value*A unique value that associates the trigger with a content. | string | — |
disabledWhen true, prevents the user from interacting with the tab. | boolean | false |
| Data attribute | Values |
|---|---|
[data-state] | "active" | "inactive" |
[data-disabled] | Present when disabled |
[data-orientation] | "vertical" | "horizontal" |
Content
Contains the content associated with each trigger.
| Prop | Type | Default |
|---|---|---|
asChildRender through a single-target factory, merging props and behavior with the chosen host.Read our Composition guide for more details. | boolean | false |
value*A unique value that associates the content with a trigger. | string | — |
forceMountUsed to force mounting when more control is needed. Useful when controlling animation with Solid-compatible animation libraries. | boolean | — |
| Data attribute | Values |
|---|---|
[data-state] | "active" | "inactive" |
[data-orientation] | "vertical" | "horizontal" |
Examples
Vertical
You can create vertical tabs by using the orientation prop.
import { Tabs } from "@radix-solid/primitives";
export default () => <Tabs.Root defaultValue="tab1" orientation="vertical">
<Tabs.List aria-label="tabs example">
<Tabs.Trigger value="tab1">One</Tabs.Trigger>
<Tabs.Trigger value="tab2">Two</Tabs.Trigger>
<Tabs.Trigger value="tab3">Three</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="tab1">Tab one content</Tabs.Content>
<Tabs.Content value="tab2">Tab two content</Tabs.Content>
<Tabs.Content value="tab3">Tab three content</Tabs.Content>
</Tabs.Root>;Accessibility
Adheres to the Tabs WAI-ARIA design pattern.
Keyboard Interactions
| Key | Description |
|---|---|
Tab | When focus moves onto the tabs, focuses the active trigger. When a trigger is focused, moves focus to the active content. |
ArrowDown | Moves focus to the next trigger depending on orientation and activates its associated content. |
ArrowRight | Moves focus to the next trigger depending on orientation and activates its associated content. |
ArrowUp | Moves focus to the previous trigger depending on orientation and activates its associated content. |
ArrowLeft | Moves focus to the previous trigger depending on orientation and activates its associated content. |
Home | Moves focus to the first trigger and activates its associated content. |
End | Moves focus to the last trigger and activates its associated content. |