Skip to content

Inputs

Segmented control

A compact row of mutually exclusive options, for switching views, filters or modes in place. The selected background slides between segments, and it behaves like a radio group: one tab stop, arrow keys to move.

On this page

Usage

components/ui/segmented-control.tsx
import { SegmentedControl } from "@/components/ui/segmented-control"; export function Example() {  return (    <SegmentedControl      aria-label="View"      defaultValue="list"      options={[        { value: "list", label: "List" },        { value: "board", label: "Board" },      ]}    />  );}

Examples

View switcher

Sizes

32, 36 and 40px tall, matching buttons and inputs.

Icon only

Leave out label and give each option an aria-label.

Full width

In context

A controlled control driving a pricing card.

$24 / seat / month

Billed $288 per seat each year.

Props

  • optionsrequiredSegmentedOption[]default: —{ value, label?, icon?, aria-label?, disabled? } for each segment.
  • value / defaultValuestringdefault: —Controlled or initial value. Defaults to the first option.
  • onValueChange(value: string) => voiddefault: —Called when the selection changes.
  • aria-labelstringdefault: —Names the group. Or use aria-labelledby.
  • size"sm" | "md" | "lg"default: "md"Height 32 / 36 / 40px.
  • fullWidthbooleandefault: falseFill the container; segments share the width.
  • disabledbooleandefault: —Disable every segment.

Accessibility

  • Uses the radio group pattern: role="radiogroup" with role="radio" segments and aria-checked.
  • Only the selected segment is in the tab order. Arrow keys move and select (wrapping around), Home and End jump to the ends; disabled segments are skipped.
  • Icon-only segments need an aria-label each; the icon is decorative.
  • Use it for a handful of short options that change the view in place. For page sections, use Tabs; for form answers, use RadioGroup.

Suggested