Skip to content
Status
Stable
Accessibility
Reviewed
Package
tenet-ui@0.5.0
Source
Tabs.tsx
Import
import { Tabs } from 'tenet-ui';

When to use: switching between peer views of the same context without navigating away (an entity’s Overview / Issues / Settings). For navigation between pages use links; for a small either/or use a SegmentedControl.

  • Compose Tabs.List (give it an aria-label) with Tabs.Tabs, and one Tabs.Panel per tab value. Tab value must match its Panel value.
  • Control it with value + onChange, or leave uncontrolled with defaultValue.
  • Keep tab labels short (one or two words). Don’t overflow a dozen tabs — that’s navigation, not tabs.
  • Keyboard and ARIA are handled: arrows move (selection follows focus), Home/End jump, roles + aria-controls/aria-labelledby are wired. Don’t rebuild this with buttons that toggle display:none divs.
  • ✅ <Tabs defaultValue="overview"><Tabs.List aria-label="Sections">…</Tabs.List><Tabs.Panel value="overview">…</Tabs.Panel></Tabs>
  • ❌ <button onClick> + conditionally rendered divs with no roles/keyboard.
  • ❌ Tabs as primary site navigation.
1 story for Tabs, open in Storybook

The full matrix (all args, controls, accessibility panel) is in Storybook.

Tabs

PropTypeDefaultDescription
valuestringNoneControlled active tab value.
defaultValuestringNoneUncontrolled initial active tab value.
onChange(value: string) => voidNoneCalled when the active tab changes.
childrenReactNodeNone
classNamestringNone

Tabs.List

PropTypeDefaultDescription
aria-labelstringNoneAccessible name for the tablist.
childrenReactNodeNone

Tabs.Tab

PropTypeDefaultDescription
value *stringNoneValue this tab selects — must match a Tabs.Panel value.
disabledbooleanfalseDisable this tab.
childrenReactNodeNone

* required

Tabs.Panel

PropTypeDefaultDescription
value *stringNoneValue this panel is shown for.
childrenReactNodeNone

* required