Skip to content

Components

SegmentedControl

Status
Stable
Accessibility
Reviewed
Package
tenet-ui@0.5.0
Import
import { SegmentedControl } from 'tenet-ui';

Also accepts every prop of Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValue'>.

When to use: switching between a few (2–5) mutually exclusive views or modes that take effect immediately — a List/Board/Timeline view toggle, a chart range. For many options or free text use Select; for on/off use Switch; for navigating peer content panes use Tabs.

  • Give it an aria-label — it’s an ARIA radiogroup and needs a group name.
  • Control with value + onChange, or uncontrolled with defaultValue (defaults to the first enabled segment).
  • Keep labels to one word where possible; the control is meant to be compact.
  • Keyboard is built in: arrows move and select (selection follows focus), Home/End jump, with a roving tab stop. Don’t rebuild it from styled buttons.
  • Use fullWidth to stretch segments across the container (block is the deprecated 0.3.0 name and warns).
  • Don’t exceed ~5 segments — past that, it gets cramped and a Select is clearer.
  • ✅ <SegmentedControl aria-label="View" options={[{value:'list',label:'List'},{value:'board',label:'Board'}]} defaultValue="list" />
  • ❌ Using it for a long list of options, or for a binary on/off (use Switch).
  • ❌ Omitting aria-label.

See also: Tabs for content panes, Select for long lists, Switch for on/off.

3 stories for SegmentedControl, open in Storybook
  • Default components-segmentedcontrol--default
  • Small components-segmentedcontrol--small
  • With Disabled components-segmentedcontrol--with-disabled

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

PropTypeDefaultDescription
options *SegmentedControlOption[]NoneThe segments to choose from.
valuestringNoneControlled selected value.
defaultValuestringfirst enabled optionUncontrolled initial value.
onChange(value: string) => voidNoneCalled with the newly selected value.
size'small' | 'medium'
SegmentedControlSize
mediumControl height / font scale.
fullWidthbooleanNoneStretch segments to fill the available width.
blockdeprecatedbooleanNoneStretch segments to fill the available width.
Deprecated since 0.5.0. Use fullWidth instead (renamed in 0.4.0). block keeps working until 0.6.0.
aria-labelstringNoneAccessible name for the group (required for screen readers).
classNamestringNone

* requiredDeprecated props keep working for one minor release; the replacement is named in the row.

SegmentedControlOption

MemberTypeDefaultDescription
value *stringNoneValue reported on change.
label *stringNoneVisible label.
disabledbooleanNoneDisable this segment.