Segmented Item

One segment. Everything it does not decide, the group decides for it.

import { SegmentedItem } from "@dede-style/ui/segmented", then <SegmentedItem value="start" label="Start" /> inside a Segmented. It takes the radio group name, the selected value, the handler, the size and the disabled state from its parent — so what is left here is the four things one segment owns.

It cannot stand on its own, and that is a property rather than a limitation. Radios are one control because they share a name, so a segment outside a group has nothing to join, no value to compare itself against and nobody to tell. Rendering one alone throws, rather than quietly producing a second control.

The group therefore owns everything shared — size, isDisabled, the selection and the keyboard — and hands them down through context. Those are on Segmented, not here.

Value and label are two things

One is what a form carries. The other is what a reader sees.

value is matched against the group’s value, and it is what a form submits; label is the words on the segment. In a props table those two are the same string, which is exactly why the distinction stays invisible until a real form wants it — start submitted against Start shown is a coincidence of this page, not a rule.

The visible label and the announced one

A track has room for H. A screen reader should still hear Horizontal.

a11yLabel exists as a mechanism rather than a style note. Segments are equal width, so the longest label sets the track — and abbreviating is the honest fix where the alternative is a control twice as wide as the words it holds.

Leave it off whenever the words fit. With no a11yLabel the wrapping <label> names the radio from the text on screen, which is one string doing both jobs — and two copies of a name are two things that can disagree.

A glyph replaces the words

It does not join them, and that is what makes four segments fit.

  • label
  • glyph

Four words will not fit a track this narrow. Four glyphs will. Segments are equal width, so the longest label sets every one of them — and a glyph is a fixed box where a word is however long the word is. That makes it the mechanism by which three and four segments render at all, rather than decoration on a text one.

label then becomes the accessible name rather than disappearing, which is Icon Button’s arrangement exactly — a glyph and a required name, doing the same two jobs.

Icon and text together is not a prop. It is a legitimate thing to want and nothing here wants it, so it stays an addition — the reasoning that gave Button no isIconOnly. If it ever lands the lever belongs on the group rather than on each segment, because a per-segment switch permits a track where one segment shows words and its neighbour does not.