Skip to content
Protocore Design Systemv1.6.9

/// Inputs

SegmentedControl

Compact single-select toggle — a bordered row of mono uppercase segments where the active one inverts to a solid fill.

import { SegmentedControl } from "@protocore/pds";
View as Markdown

Basics

Pass items and control the selection via value / onValueChange. Exactly one segment is always active — onValueChange never fires with an empty value.

Icon segments

Segments accept any ReactNode label. For icon-only segments, give each icon an aria-label and the control an aria-label for the group.

Disabled segment

Disable a single segment with disabled on the item, or the whole control with the top-level disabled prop.

When to use it

Use a SegmentedControl for 2–4 short, mutually-exclusive options that switch a view or scope in place — a time range, a layout mode, an environment. It's the compact cousin of RadioGroup: prefer RadioGroup when options are longer or need descriptions, and Select once they outgrow a row. It differs from FilterBar in intent — a segmented control picks one *mode*, while a FilterBar toggles filters (often many) over a collection. It is not a Switch: use Switch for a single on/off setting.

Usage

Do

  • Keep to 2–4 segments with short, parallel labels.
  • Give the control an `aria-label`, especially with icon-only segments.
  • Use it to switch a view or scope that updates immediately.
  • Keep exactly one segment meaningful as the default selection.

Don't

  • Don't exceed ~4 segments — the row gets cramped; use Select or RadioGroup.
  • Don't use long or wrapping labels; a segment is not a menu item.
  • Don't use it for multi-select — that's a FilterBar or Checkbox set.
  • Don't use it for a binary on/off setting — that's a Switch.

Accessibility

KeysAction
TabMove focus into the group, landing on the active segment.
Arrow Left / RightMove to and select the previous / next enabled segment.
Home / EndMove to and select the first / last enabled segment.
Space / EnterSelect the focused segment.
  • Built on Radix ToggleGroup (`type="single"`) with radiogroup semantics and roving tabindex — one Tab stop.
  • Disabled segments are skipped during arrow navigation.
  • Icon-only segments must carry their own label; the control needs an `aria-label` for the group name.

SegmentedControl props

PropTypeDefaultDescription
aria-labelstringAccessible name for the radio group (required for icon-only segments).
classNamestring
defaultValuestringUncontrolled initial selected value.
disabledbooleanDisable the whole control.
items *SegmentedControlItem[]The segments, left to right.
onValueChange((value: string) => void)Fired with the newly-selected value (never with an empty string — a segmented control always keeps one segment active).
styleCSSProperties
valuestringControlled selected value.

Related

  • RadioGroupOne-of-many selection with sharp square markers; the active option carries the accent fill.
  • SelectInput-styled trigger plus an overlay panel for choosing one value from a list; flat or compound API.
  • SwitchBoxy 36×20 toggle for an instant on/off setting; ink track when on, canvas thumb.
  • ChipAn interactive filter toggle — mono uppercase ghost outline that inverts to the primary fill when selected.