Navigation
Tabs
A set of headings that swaps one panel at a time.
When to use it: Use it for peer sections where only one needs to be visible.
Example
import { Button, Tab, TabList, TabPanel, Tabs } from "@comp0/react";
export function Example() {
return (
<Tabs as="div" defaultValue="preview">
<TabList className="flex max-w-full gap-1 overflow-x-auto border-b border-zinc-950/10 dark:border-white/10">
<Tab
className="shrink-0 px-3 py-2.5 text-base text-zinc-700 data-selected:border-b-2 data-selected:border-teal-600 data-selected:text-teal-800 sm:py-2 sm:text-sm dark:text-zinc-300 dark:data-selected:border-teal-400 dark:data-selected:text-teal-200"
tab="preview"
>
Preview
</Tab>
<Tab
className="shrink-0 px-3 py-2.5 text-base text-zinc-700 data-selected:border-b-2 data-selected:border-teal-600 data-selected:text-teal-800 sm:py-2 sm:text-sm dark:text-zinc-300 dark:data-selected:border-teal-400 dark:data-selected:text-teal-200"
tab="code"
>
Code
</Tab>
</TabList>
<TabPanel
className="pt-3 text-base text-zinc-700 sm:text-sm dark:text-zinc-300"
tab="preview"
>
A live component preview.
</TabPanel>
<TabPanel
className="pt-3 font-mono text-base text-zinc-700 sm:text-sm dark:text-zinc-300"
tab="code"
>
import {"{ Button }"} from "@comp0/react"
</TabPanel>
</Tabs>
);
}Anatomy
Dashed frames are invisible state providers; shaded shapes own real DOM. Numbered pins match the list below.
A wireframe sketch of the assembled component. Each numbered marker matches a part in the list that follows.
Tabs
Selected-tab provider. Does not add a DOM element.
TabList
Tab list element. Owns a DOM element.
Tab
Native button with tab role. Owns a DOM element.
TabPanel
Panel for a matching tab. Owns a DOM element.
Step by step
- 1
Add the main part
Start Tabs with a starting value.
- 2
Add the supporting parts
Give each Tab and its TabPanel the same tab id.
- 3
Make the behavior clear
Put the Tab elements together inside TabList.
Exampletsx <Tabs defaultValue="one"><TabList><Tab tab="one">One</Tab></TabList><TabPanel tab="one">Panel one</TabPanel></Tabs>
Keyboard
- →
- Moves to next tab.
- ←
- Moves to previous tab.
- Home
- Moves to first tab.
- End
- Moves to last tab.
Forms and accessibility
No native form behavior.
Accessibility checklist
- Keep tab names short and distinct.
- Ensure each Tab has a matching TabPanel key.
- Do not use tabs to hide unrelated page navigation.
API reference
import { Tab, TabList, TabPanel, Tabs } from "@comp0/react";Tabs
Context onlySelected-tab provider.
| Prop | Type | Description |
|---|---|---|
value | string | Controlled selected tab. |
defaultValue | string | Initial selected tab. |
onChange | (value: string) => void | Receives the next selected tab. |
TabList
DOM elementTab list element.
| Prop | Type | Description |
|---|---|---|
aria-label | string | Names the tab list for assistive technology. |
orientation | "horizontal" | "vertical" | Arrow-key axis and aria-orientation. |
Tab
DOM elementNative button with tab role.
| Prop | Type | Description |
|---|---|---|
tab | string | Identity that pairs this tab with its panel. |
disabled | boolean | Disables the tab. |
TabPanel
DOM elementPanel for a matching tab.
| Prop | Type | Description |
|---|---|---|
tab | string | The tab this panel belongs to. |
Style hooks
Attributes that appear while a state is true. Target them with Tailwind data variants such as data-open:bg-zinc-100, or with any CSS selector.
[data-selected]on Tab, TabPanel
- This tab or panel is selected.