Tabs
Composable tabs with roving keyboard focus, automatic activation, and horizontal or vertical layout.
import { Tabs } from "@ps1ui/core";Basic
<Tabs defaultValue="overview">
<TabList aria-label="doc sections">
<Tab value="overview">Overview</Tab>
<Tab value="install">Install</Tab>
<Tab value="api">API</Tab>
</TabList>
<TabPanel value="overview">
A monospace UI toolkit for building terminal-inspired dashboards.
</TabPanel>
<TabPanel value="install">Install with pnpm add @ps1ui/core.</TabPanel>
<TabPanel value="api">See the Props table on each component's page.</TabPanel>
</Tabs>With a disabled tab
<Tabs defaultValue="overview">
<TabList aria-label="doc sections">
<Tab value="overview">Overview</Tab>
<Tab value="install" disabled>Install</Tab>
<Tab value="api">API</Tab>
</TabList>
<TabPanel value="overview">Overview content.</TabPanel>
<TabPanel value="install">Install content.</TabPanel>
<TabPanel value="api">API content.</TabPanel>
</Tabs>Vertical orientation
<Tabs defaultValue="overview" orientation="vertical">
<TabList aria-label="doc sections">
<Tab value="overview">Overview</Tab>
<Tab value="install">Install</Tab>
<Tab value="api">API</Tab>
</TabList>
<TabPanel value="overview">Overview content.</TabPanel>
<TabPanel value="install">Install content.</TabPanel>
<TabPanel value="api">API content.</TabPanel>
</Tabs>Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | Controlled selected value. When set, the tabs ignore their internal state. |
defaultValue | string | — | Uncontrolled initial value. Omit both `value` and `defaultValue` and the group falls back to the first enabled `<Tab>` in DOM order so the tablist stays keyboard-reachable (WAI-ARIA APG requires the first tab to hold `tabindex=0` when nothing is otherwise selected). |
onValueChange | (value: string) => void | — | Fired with the newly-selected value whenever the user activates a different `<Tab>`. |
orientation | "horizontal" | "vertical" | "horizontal" | Layout axis for the tab list. Horizontal maps ArrowLeft / ArrowRight to previous / next; vertical maps ArrowUp / ArrowDown. Also drives `aria-orientation` on the tablist and the vertical padding modifier on every child `<TabPanel>`. |
disabled | boolean | false | Disable every `<Tab>` inside the group. Precedence is asymmetric: a per-tab `disabled={true}` still opts that tab in when the group is enabled, but a per-tab `disabled={false}` cannot opt out of a group-wide disable. |
All native <div> attributes are also accepted.
TabList Props
All native <div> attributes are also accepted.
Tab Props
| Prop | Type | Default | Description |
|---|---|---|---|
value* | string | — | Identifier for this tab. Matched against `<Tabs value>` / `<Tabs defaultValue>` to derive `aria-selected`, and against a sibling `<TabPanel value>` to wire up `aria-controls` / `aria-labelledby`. |
selected | boolean | — | Standalone fallback for `aria-selected` when the tab is rendered outside a `<Tabs>` context (e.g. static docs demos). Ignored inside `<Tabs>` — the group's `value` is the source of truth there. |
All native <button> attributes are also accepted except type.
TabPanel Props
| Prop | Type | Default | Description |
|---|---|---|---|
value* | string | — | Identifier matched against `<Tabs value>` — when equal, the panel is shown; otherwise it renders with the native `hidden` attribute so it drops out of the a11y tree and layout. Also links back to its owning `<Tab>` via `aria-labelledby`. |
All native <div> attributes are also accepted.