Tabs
Compound tab interface with roving tabindex, automatic activation, and vertical/horizontal orientation.
Preview
Switch the framework picker (top-right of the panel) to render the same demo live in React, Vue, or Angular — same class names, ARIA, and visual output across all three.
Installation
Sisyphos UI ships unified packages for React, Vue, and Angular. Pick the one that matches your stack — every framework exports the same component classes, ARIA semantics, and CSS tokens.
$ pnpm add @sisyphos-ui/reactThen import the bundled stylesheet once at app entry: import "@sisyphos-ui/react/styles.css";
Usage
import { useState } from "react";
import { Tabs } from "@sisyphos-ui/react";
export const Settings = () => {
const [tab, setTab] = useState("profile");
return (
<Tabs value={tab} onValueChange={setTab}>
<Tabs.List>
<Tabs.Trigger value="profile">Profile</Tabs.Trigger>
<Tabs.Trigger value="billing">Billing</Tabs.Trigger>
</Tabs.List>
<Tabs.Panel value="profile">Profile content.</Tabs.Panel>
<Tabs.Panel value="billing">Billing content.</Tabs.Panel>
</Tabs>
);
};Pill variant
Vertical orientation
Arrow keys walk Up/Down; Home/End jump to first/last.
Full width
`fullWidth` stretches triggers evenly — pairs well with the `soft` variant.
With icons
Each `Tabs.Trigger` accepts an `icon` prop rendered before the label.
API
| Prop | Type | Default | Description |
|---|---|---|---|
| value | string | — | Active tab value (controlled). Matches the `value` shared by a `Tabs.Trigger` / `Tabs.Panel` pair. |
| defaultValue | string | — | Initial active tab value (uncontrolled). |
| onValueChange | (value: string) => void | — | Called with the new value when the active tab changes. |
| orientation | "horizontal" | "vertical" | "horizontal" | Layout direction — also switches the arrow-key axis. |
| fullWidth | boolean | false | Stretch triggers to fill the list width. |
| variant | "underline" | "pill" | "soft" | "underline" | Visual treatment of the trigger list and animated indicator. |
| size | "sm" | "md" | "lg" | "md" | Trigger size scale. |
The full API including refs, ARIA attributes, and HTML passthroughs lives in the package README on npm.
Accessibility
Adheres to the Tabs WAI-ARIA design pattern.
- Roving tabindex — only the active trigger sits in the tab order (
tabIndex={0}); the rest are-1. Tabs.Listrendersrole="tablist"witharia-orientation; triggers arerole="tab"witharia-selectedandaria-controlswired to their panel.Tabs.Panelrendersrole="tabpanel"witharia-labelledbypointing back at its trigger, andtabIndex={0}so panel content is reachable.- Inactive panels stay mounted but
hidden; setforceMount={false}onTabs.Panelto unmount them.
Keyboard interactions
| Key | Action |
|---|---|
| ArrowRightthenArrowLeft | Horizontal orientation: select and focus the next / previous tab (wraps at the edges). |
| ArrowDownthenArrowUp | Vertical orientation: select and focus the next / previous tab (wraps at the edges). |
| Home | Selects the first tab. |
| End | Selects the last tab. |
| Tab | Moves focus out of the tab list, into the active panel. |