Skip to content

Tabs

Status: stableAccessibility reviewedtenet-ui@0.4.0
Import
import { Tabs } from 'tenet-ui';

Source: src/components/Tabs/Tabs.tsx

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
valuestringControlled active tab value.
defaultValuestringUncontrolled initial active tab value.
onChange(value: string) => voidCalled when the active tab changes.
childrenReactNode
classNamestring

Tabs.List

PropTypeDefaultDescription
aria-labelstringAccessible name for the tablist.
childrenReactNode

Tabs.Tab

PropTypeDefaultDescription
value *stringValue this tab selects — must match a Tabs.Panel value.
disabledbooleanfalseDisable this tab.
childrenReactNode

* required

Tabs.Panel

PropTypeDefaultDescription
value *stringValue this panel is shown for.
childrenReactNode

* required