Skip to content
ArcadiaDesign
ThemeSystem follows your device

TSX

One option is always chosen, and pressing the current one does nothing. At md the choice is a solid pill, white with night-ink text at night and night ink with white text by day, inside a track ringed at 10%; sm keeps a quiet thumb for toolbars. The thumb is measured from the pressed item and moves on the morph spring (--ease-morph); on first paint it appears in place. Use it for two to five options; beyond that, use a Menu. An item's icon sits beside its label, framed and stroked by the label's text; an icon-only item draws it standalone (16, 14 at sm). The thumb marks the selection, never the glyph.

The solid pill is an ink layer holding a copy of the labels in the inverse colour, clipped to the pressed item, so the pill and its inverted text move as one, mid-slide included, and look the same on any surface. A blend mode would invert whatever sits behind the control, and drop the pill inside a fading dialog or a blurred page swap.

Segmented Control or Tabs? A Segmented Control picks a value: a setting, a filter, a view. When each option has its own panel of content, use Tabs with the segmented look, which adds the tab roles.

Examples

Icon only

An icon-only item's label becomes its aria-label and its title.

A hint per choice

When a choice's label cannot say what it does, its item takes a hint: a tooltip on that segment, and its aria-description.

The sentence waits there instead of sitting under the control.

Stretch

stretch shares the full width equally, for a control that heads a panel.

Kind and size

rootStyle takes where the control sits (margins, self-alignment, flex and grid placement, size bounds) and the knobs below, each a token of its kind. A colour, a raw length or any other property is a type error: a look that comes up twice becomes a variant.

TSX
--segmented-item-h
Ref<Control>Default var(--control-sm)
Item height.
--segmented-item-px
Ref<Space>Default var(--space-2-5)
Item inline padding (a labelled item adds --space-0-5).
--segmented-pad
Ref<Space>Default var(--space-0-75)
Track padding around the items.
--segmented-solid
PaintDefault var(--bg-inverse)
The solid choice's fill (SegmentedControl at md).
--segmented-solid-fg
PaintDefault var(--text-inverse)
The solid choice's label colour (SegmentedControl at md).

--segmented-solid and --segmented-solid-fg paint the solid choice at md. Tabs with the segmented look take the same knobs on their TabsList.

A toggle group: one tab stop, with arrow keys moving between the options. Give the control an aria-label (or aria-labelledby on a visible label, as in a settings row) so it is announced as "Theme" rather than a bare group.

←→
Move focus between options
EnterSpace
Choose the focused option

SegmentedControl

itemsrequired
readonly SegmentedItem<V>[]
value
V
defaultValue
V
onValueChange
(value: V) => void
size
"sm" | "md"Default "md"
md: 24px items in a 30px track, the choice a solid ink pill with inverse text. sm: 20px items with 12/16 text and a quiet thumb, for toolbars.
stretch
boolean
Items share the full width equally.
disabled
boolean
Disables every item.
rootStyle
SegmentedStyle
Typed StyleX override: where the control sits and its --segmented-* knobs.
className
string
A product's hook class, retiring: new code uses rootStyle (ui.lint kit-classname counts the rest).

Rest props go to <div> props.