sc1m/design
ComponentsTabs

Tabs

Tabs component built on Base UI, styled with sc1m tokens.

StableBase UI

Live preview

Color, typography, spacing, and motion tokens.

Installation

pnpm dlx shadcn@latest add @sc1m/tabs

This also merges the token layer and installs src/lib/cn.ts plus @base-ui/react. For the manual route — prerequisites, components.json, and app-level setup — see Installation.

Usage

import {
  Tabs,
  TabsList,
  TabsTab,
  TabsPanel,
} from "@/components/ui/tabs";

Composition

Every part is a separate export. Tabs owns state; the rest are presentational and must appear in this order.

Tabs├── TabsList│   └── TabsTab└── TabsPanel

Example

The preview above, with its source. This is the demo module verbatim, so the code and the thing it renders cannot drift apart.

Color, typography, spacing, and motion tokens.
<Tabs defaultValue="tokens" className="w-96">
  <TabsList>
    {['tokens', 'components', 'patterns'].map((value) => (
      <TabsTab key={value} value={value}>
        {value}
      </TabsTab>
    ))}
  </TabsList>
  <TabsPanel value="tokens">
    Color, typography, spacing, and motion tokens.
  </TabsPanel>
  <TabsPanel value="components">
    Base UI primitives styled with the token layer.
  </TabsPanel>
  <TabsPanel value="patterns">
    Composition patterns built from components.
  </TabsPanel>
</Tabs>

API reference

Each part forwards every prop of its Base UI counterpart; the tables list the ones declared on the part itself. See Base UI's reference for the inherited element props.

Tabs

PropTypeDefaultDescription
valueTabsTab.ValueThe value of the currently active Tab.
defaultValueTabsTab.Value0The default value.
orientationTabsRoot.Orientation'horizontal'The component orientation (layout flow direction).
onValueChange((value: TabsTab.Value, eventDetails: TabsRoot.ChangeEventDetails) => void)Callback invoked when new value is being set.

TabsList

PropTypeDefaultDescription
activateOnFocusbooleanfalseWhether to automatically change the active tab on arrow key focus.
loopFocusbooleantrueWhether to loop keyboard focus back to the first item when the end of the list is reached while using the arrow keys.

TabsTab

PropTypeDefaultDescription
valueTabsTab.ValueThe value of the Tab.
disabledbooleanWhether the Tab is disabled.

TabsPanel

PropTypeDefaultDescription
valueTabsTab.ValueThe value of the TabPanel.
keepMountedbooleanfalseWhether to keep the HTML element in the DOM while the panel is hidden.

Accessibility

Behaviour, focus management, and ARIA wiring come from Base UI's Tabs — see its reference for the full keyboard map.

  • Keyboard focus draws a 2px ring in --ring, never removed — only shown on :focus-visible, so a pointer press does not paint one.

Design tokens

The component reads semantic tokens only — no raw colour, radius, or duration appears in its source. Override the token, not the component.

TokenApplied to
--brand-radius-lgTabsList
--brand-radius-mdTabsList, TabsTab
--fgTabsTab
--fg-mutedTabsTab, TabsPanel
--ringTabsTab
--shadow-raisedTabsList
--surfaceTabsList
--surface-raisedTabsList

Source

src/components/ui/tabs/tabs.tsx — no next/* imports, so it drops into any React 19 + Tailwind v4 app.