docs / patterns / segmented-control

SegmentedControl

a small row of options with one picked at a time, the selection carried by a sliding indicator instead of a restyle. it switches a view in place; the page stays put.

intensity · structuresrsc · client

provenance

authored in usva

layer

core / patterns

intensity

structures · organizes a region, stays out of the content

composition

sits in a Toolbar, a PageHeader, or above the region it switchestwo to five short segments, icons optionalnever for navigation between pages, that is Tabs or linksno long labels. a segment that wraps is a Select

a11y

role="radiogroup" with a radio per segment · roving tabindex, arrows / Home / End move and select · the indicator is aria-hiddenjest-axe
live demo · try it out
customize
sizesegment height and padding
orientationrow, or a stacked column
usagecopy
import { SegmentedControl } from "@usva-ui/react/patterns/segmented-control";

<SegmentedControl
  items={[
    { value: "board", label: "Board" },
    { value: "list", label: "List" },
    { value: "calendar", label: "Calendar" },
  ]}
  defaultValue="board"
/>

props

proptypedefaultnotes
itemsSegmentedControlItem[]the segments: { value, label, icon? }. the icon is decorative.
valuestringthe controlled selected value.
defaultValuestringuncontrolled start. falls back to the first item.
onValueChange(value: string) => voidfires on click and on arrow-key moves.
size"sm" | "md""md"segment height and padding.
orientation"horizontal" | "vertical""horizontal"vertical stacks the segments and slides the indicator on the y axis.

get it

bun add @usva-ui/reactcopy
usagecopy
import { SegmentedControl } from "@usva-ui/react/patterns/segmented-control";

<SegmentedControl
  items={[
    { value: "board", label: "Board" },
    { value: "list", label: "List" },
  ]}
  value={view}
  onValueChange={setView}
/>