Home

Segmented control

A few labelled options on a pill track, with a white thumb that glides to the one chosen.

ui.segmented-controlcomponents/ui/segmented-control.tsx

Use case

For the AI

Use it when exactly one of two to five short options is always chosen and the choice changes what is shown: Day, Week and Month over a schedule, 7D, 30D and 90D over a sales figure, Open, Paid and All above invoices. It is controlled: the value lives in state and the view reads it.

Use it when

  • Switching between views of the same content (Day, Week, Month)
  • A date range over a figure or a chart
  • A setting with two to five short options, one always chosen

Use something else when

  • Sections of a page that each have their own panel: Tabs
  • More options than fit on one line, or long labels: Select
  • Icon switches that may combine or may all be off: Toggle group
  • A choice in a form with a sentence for each option: Radio group

Examples

The thumb glides
Large, for a page's views

Code

Import

import { SegmentedControl } from "@/components/ui/segmented-control"

Usage

const [view, setView] = useState<"day" | "week" | "month">("week")

<SegmentedControl
  aria-label="View"
  value={view}
  onValueChange={setView}
  options={[
    { value: "day", label: "Day" },
    { value: "week", label: "Week" },
    { value: "month", label: "Month" },
  ]}
/>

Rules

  • It is controlled: pass value and onValueChange, and keep the value in state.
  • Always pass aria-label naming what is chosen (View, Range).
  • Option labels are short and in Title Case.
  • Each option is { value, label, disabled? }; size is sm, default or lg.
  • The thumb slides to the one picked on the glide in --dur-slide; never swap a fill from one option to the other.
  • It is exactly as tall as a Button of the same size (sm 30px, default 36px, lg 40px): in a row beside buttons, give both the same size, never a segmented control one size up.