Tabs
Line tabs for switching between related panels.
import { Tabs } from "@merid/react";
export function Example() {
return (
<Tabs.Root defaultValue="overview">
<Tabs.List aria-label="Project">
<Tabs.Trigger value="overview">Overview</Tabs.Trigger>
<Tabs.Trigger value="activity">Activity</Tabs.Trigger>
<Tabs.Trigger value="settings">Settings</Tabs.Trigger>
<Tabs.Trigger value="billing" disabled>
Billing
</Tabs.Trigger>
</Tabs.List>
<Tabs.Panel value="overview">Three deployments this week, all healthy.</Tabs.Panel>
<Tabs.Panel value="activity">Northwind merged 4 pull requests.</Tabs.Panel>
<Tabs.Panel value="settings">Rename the project or change its region.</Tabs.Panel>
</Tabs.Root>
);
}Import
import { Tabs } from "@merid/react";Anatomy
<Tabs.Root>
<Tabs.List>
<Tabs.Trigger value="a" />
</Tabs.List>
<Tabs.Panel value="a" />
</Tabs.Root>- Root holds the selected value and orientation.
- List is the
role="tablist"; give it anaria-label. - Trigger is one
role="tab"button, linked to its panel byvalue. - Panel is the
role="tabpanel". Inactive panels unmount unlessforceMountis set.
Examples
Controlled
const [tab, setTab] = useState("week");
<Tabs.Root value={tab} onValueChange={setTab}>
<Tabs.List aria-label="Range">
<Tabs.Trigger value="day">Day</Tabs.Trigger>
<Tabs.Trigger value="week">Week</Tabs.Trigger>
<Tabs.Trigger value="month">Month</Tabs.Trigger>
</Tabs.List>
<Tabs.Panel value={tab}>Showing data for one {tab}.</Tabs.Panel>
</Tabs.Root>Vertical
With orientation="vertical", the list stacks and ArrowUp/ArrowDown move between tabs.
<Tabs.Root defaultValue="profile" orientation="vertical">
<Tabs.List aria-label="Account">
<Tabs.Trigger value="profile">Profile</Tabs.Trigger>
<Tabs.Trigger value="security">Security</Tabs.Trigger>
<Tabs.Trigger value="notifications">Notifications</Tabs.Trigger>
</Tabs.List>
<Tabs.Panel value="profile">Name, avatar and time zone.</Tabs.Panel>
<Tabs.Panel value="security">Password and two-factor sign-in.</Tabs.Panel>
<Tabs.Panel value="notifications">Email and in-app alerts.</Tabs.Panel>
</Tabs.Root>API reference
Root
Accepts every <div> attribute except defaultValue and onChange.
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | – | Controlled selected tab value. |
defaultValue | string | "" | Initially selected tab value when uncontrolled. |
onValueChange | (value: string) => void | – | Called when the selected tab changes. |
orientation | "horizontal" | "vertical" | "horizontal" | Arrow-key axis. |
ref | Ref<HTMLDivElement> | – | Forwarded ref to the root element. |
List
Accepts every <div> attribute.
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "line" | "line" | Visual style. Only "line" today. |
ref | Ref<HTMLDivElement> | – | Forwarded ref to the tablist. |
Trigger
Accepts every <button> attribute except value.
| Prop | Type | Default | Description |
|---|---|---|---|
valueRequired | string | – | Value identifying this tab and its panel. |
disabled | boolean | – | Disable the tab; it is skipped by arrow keys. |
ref | Ref<HTMLButtonElement> | – | Forwarded ref to the tab button. |
Panel
Accepts every <div> attribute.
| Prop | Type | Default | Description |
|---|---|---|---|
valueRequired | string | – | Value of the tab that owns this panel. |
forceMount | boolean | false | Keep the panel mounted (hidden) while inactive. |
ref | Ref<HTMLDivElement> | – | Forwarded ref to the panel. |
Styling
| Class | Element |
|---|---|
.mrd-tabs | Root |
.mrd-tabs__list | List |
.mrd-tabs__trigger | Trigger |
.mrd-tabs__panel | Panel |
| Attribute | On | Values |
|---|---|---|
data-orientation | Root | horizontal, vertical |
data-variant | List | line |
data-state | Trigger, Panel | active, inactive |
data-disabled | Trigger | present when disabled |
aria-selected="true" | Trigger | the selected tab (styled with the accent underline) |
Accessibility
Follows the WAI-ARIA Tabs pattern with automatic activation: moving focus selects the tab. Only the selected tab is in the tab order; the panel itself is focusable so keyboard users can reach content without interactive elements.
| Key | Action |
|---|---|
| Tab | Move focus into the tab list (selected tab), then to the panel. |
| ArrowRight | Horizontal: next tab, wrapping. Selects it. |
| ArrowLeft | Horizontal: previous tab, wrapping. Selects it. |
| ArrowDown | Vertical: next tab, wrapping. Selects it. |
| ArrowUp | Vertical: previous tab, wrapping. Selects it. |
| Home | First tab. |
| End | Last tab. |
Guidelines
Do
Use tabs for peer views of the same object, with short one- or two-word labels.
Avoid
Use tabs for sequential steps — use a Stepper — or for switching a small control mode, which is a SegmentedControl.
Do
Keep the tab row on one line; move rarely used views into a menu.
Avoid
Nest a second row of tabs inside a panel.