Segmented control
A single choice among two to five options: a solid ink pill that slides between them.
import { SegmentedControl } from "@arcadia/ui"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 draws its filled form while the item is selected.
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
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.
| Knob | Takes | Default | Sets |
|---|---|---|---|
Ref<Control> | var(--control-sm) | Item height. | |
Ref<Space> | var(--space-2-5) | Item inline padding (a labelled item adds --space-0-5). | |
Ref<Space> | var(--space-0-75) | Track padding around the items. | |
Paint | var(--bg-inverse) | The solid choice's fill (SegmentedControl at md). | |
Paint | 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 for its own layout rules. Being retired: new code places a control with
rootStyle; the call sites left are counted by ui.lint (kit-classname) and only go down.
Rest props go to <div> props.