# Segmented control

> One of a few options side by side: the thumb is thrown to the new segment while its width eases to the new label.

Segmented controls usually blink their highlight from one segment to the next. Here the thumb is one surface thrown to the new segment with a slight overshoot while its width eases to the new label; it gives a little under the finger. It is a radiogroup, so arrow keys move and select.

## Install

```bash
npx shadcn@latest add https://hairlineui.com/r/segmented-control.json
```

Needs React 19, Tailwind CSS v4 and shadcn/ui theme variables (any style, light and dark). Icons from lucide-react.

- npm: none
- Hairline UI components it needs (the CLI installs them too): `ui-interaction-motion`
- Docs and live preview: https://hairlineui.com/ui/segmented-control
- Registry item (source): https://hairlineui.com/r/segmented-control.json

## Usage

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

<SegmentedControl label="View" defaultValue="week" options={[
  { value: "day", label: "Day" },
  { value: "week", label: "Week" },
  { value: "month", label: "Month" },
]} />
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `options` | `SegmentOption[]` | – | value, label, icon, ariaLabel, disabled. |
| `value / defaultValue` | `string` | – | Chosen value. |
| `onValueChange` | `(value: string) => void` | – | Called on choice. |
| `label` | `string` | – | Accessible name. |
| `size` | `"sm" \| "md"` | `"md"` | 28px or 36px tall. |
| `block` | `boolean` | `false` | Fill the parent with equal segments. |

## States

- **pick**: The thumb is thrown to the new segment (440ms, slight overshoot) and its width eases (400ms).
- **press**: The thumb scales to 0.97 under the finger.
- **keys**: Arrows move and select; Home and End jump.

## What it handles

Tabs, toggle groups and segmented controls get mixed up; this is the single-choice one, with radio semantics and one tab stop.

- **One thrown thumb**: Measured from layout, retargets mid-flight, first placement without motion.
- **Radio semantics**: role="radiogroup", arrows select, one tab stop.
- **Icons or text**: Icon-only segments take an ariaLabel.
- **Block**: Equal segments that fill the parent.

## Replaces

toggle group for single choice, sliding highlight

## Where it fits

- **View switches**: Day, week and month on a calendar.
- **Billing period**: Monthly or yearly above a price.
- **Chart ranges**: 7d, 30d, 90d on a dashboard card.
- **Editor modes**: Write and preview with icons.

## Notes

- Reduced motion: the thumb moves at once.
- Use Tabs when each choice shows its own panel.

License: MIT (https://hairlineui.com/license#components)
