SegmentedControl
A pill-shaped single-select toggle for switching between a few views, ranges or modes. It behaves as a radio group: one tab stop, arrow keys to move.
<SegmentedControl
aria-label="Range"
defaultValue="week"
options={[
{ value: "day", label: "Day" },
{ value: "week", label: "Week" },
{ value: "month", label: "Month" },
]}
/>Import
import { SegmentedControl, type SegmentedControlOption } from "@merid/react";Examples
Controlled
Uncontrolled, the control starts on defaultValue or the first enabled option. For controlled use pass value and onValueChange.
value: month
const [value, setValue] = useState("month");
<SegmentedControl aria-label="Range" options={range} value={value} onValueChange={setValue} />Icon segments
When a segment's label is an icon, give the option an ariaLabel.
<SegmentedControl
aria-label="View"
options={[
{ value: "list", label: <ListIcon />, ariaLabel: "List view" },
{ value: "grid", label: <GridIcon />, ariaLabel: "Grid view" },
]}
/>Disabled options, disabled control, full width
<SegmentedControl
aria-label="Plan"
options={[
{ value: "monthly", label: "Monthly" },
{ value: "yearly", label: "Yearly" },
{ value: "lifetime", label: "Lifetime", disabled: true },
]}
/>
<SegmentedControl aria-label="Range" options={range} disabled />
<SegmentedControl aria-label="Range" options={range} fullWidth />API reference
SegmentedControl
The ref and other div attributes go to the role="radiogroup" container.
| Prop | Type | Default | Description |
|---|---|---|---|
optionsRequired | SegmentedControlOption[] | – | The segments. |
value | string | – | Selected value (controlled). |
defaultValue | string | – | Initially selected value (uncontrolled). Defaults to the first enabled option. |
onValueChange | (value: string) => void | – | Called with the new value when the selection changes. |
fullWidth | boolean | false | Stretches segments to fill the container. |
disabled | boolean | false | Disables the whole control. |
SegmentedControlOption
| Prop | Type | Default | Description |
|---|---|---|---|
valueRequired | string | – | Value reported on selection. |
labelRequired | ReactNode | – | Visible content of the segment. |
ariaLabel | string | – | Accessible name when label is not text (e.g. an icon). |
disabled | boolean | – | Makes the segment unselectable and skipped by arrow keys. |
Styling
| Hook | Values |
|---|---|
.mrd-segmented | Pill track; data-full-width when stretched |
.mrd-segmented__item | Each segment <button role="radio"> |
data-state | on · off on each item |
On a tray section or tray card the track switches to --mrd-tray-2 automatically. There are no component variables.
Accessibility
- The container is
role="radiogroup", each segmentrole="radio"witharia-checked. Name the group witharia-labeloraria-labelledby. - Only the selected segment is in the tab order. Arrow keys move and select at once (APG radio group), skipping disabled segments and wrapping at the ends.
| Key | Action |
|---|---|
| Tab | Moves focus to the selected segment. |
| →↓ | Selects the next enabled segment. |
| ←↑ | Selects the previous enabled segment. |
| Home | Selects the first enabled segment. |
| End | Selects the last enabled segment. |
Guidelines
Do
Use two to five short, parallel labels that switch a view in place: Day / Week / Month.
Avoid
Use it for navigation between pages, or for panels with their own content — that is Tabs.