Skip to content

Tabs

Compound tab interface with roving tabindex, automatic activation, and vertical/horizontal orientation.

Data Display·Available inReactVueAngular·View as Markdown

Preview

tsx
Render a visual preview of the component here.

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/react

Then import the bundled stylesheet once at app entry: import "@sisyphos-ui/react/styles.css";

Usage

Idiomatic usage in each supported framework
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

tsx
Dashboard overview…

Vertical orientation

Arrow keys walk Up/Down; Home/End jump to first/last.

tsx
Manage your display name, avatar, and public handle.

Full width

`fullWidth` stretches triggers evenly — pairs well with the `soft` variant.

tsx
Today's metrics — good for active monitoring.

With icons

Each `Tabs.Trigger` accepts an `icon` prop rendered before the label.

tsx
Invite, remove, and manage member roles.

API

PropTypeDefaultDescription
valuestringActive tab value (controlled). Matches the `value` shared by a `Tabs.Trigger` / `Tabs.Panel` pair.
defaultValuestringInitial active tab value (uncontrolled).
onValueChange(value: string) => voidCalled with the new value when the active tab changes.
orientation"horizontal" | "vertical""horizontal"Layout direction — also switches the arrow-key axis.
fullWidthbooleanfalseStretch 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.List renders role="tablist" with aria-orientation; triggers are role="tab" with aria-selected and aria-controls wired to their panel.
  • Tabs.Panel renders role="tabpanel" with aria-labelledby pointing back at its trigger, and tabIndex={0} so panel content is reachable.
  • Inactive panels stay mounted but hidden; set forceMount={false} on Tabs.Panel to unmount them.

Keyboard interactions

KeyAction
ArrowRightthenArrowLeftHorizontal orientation: select and focus the next / previous tab (wraps at the edges).
ArrowDownthenArrowUpVertical orientation: select and focus the next / previous tab (wraps at the edges).
HomeSelects the first tab.
EndSelects the last tab.
TabMoves focus out of the tab list, into the active panel.
Need more?View on npm →
Was this page helpful?