# Segmented control

A row of buttons for switching between two to five related options, such as views or periods. Exactly one is pressed. To show different panels, use [Tabs](/components/tabs.md).

```tsx
// demo.tsx
import {Stack, Text, SegmentedControl} from '@earendil-works/elanor-react';
import {useState} from 'react';

export default function SegmentedControlDemo() {
  const [period, setPeriod] = useState(['monthly']);

  return (
    <Stack gap="small" align="start">
      <SegmentedControl.Root
        aria-label="Billing period"
        value={period}
        onValueChange={(next) => {
          if (next.length > 0) setPeriod(next);
        }}
      >
        <SegmentedControl.Item value="monthly">Monthly</SegmentedControl.Item>
        <SegmentedControl.Item value="yearly">Yearly</SegmentedControl.Item>
      </SegmentedControl.Root>
      <Text role="status">{period[0] === 'yearly' ? '$120 per year' : '$12 per month'}</Text>
    </Stack>
  );
}
```

## Usage

```tsx
import {SegmentedControl} from '@earendil-works/elanor-react';

<SegmentedControl.Root aria-label="Billing period" defaultValue={['monthly']}>
  <SegmentedControl.Item value="monthly">Monthly</SegmentedControl.Item>
  <SegmentedControl.Item value="yearly">Yearly</SegmentedControl.Item>
</SegmentedControl.Root>;
```

The value is an array with one item, as in Base UI Toggle Group. Pressing the selected item would clear it; ignore empty values in `onValueChange` to keep one selected, as the demo does.

## Density

Use `compact` on Root beside compact controls, such as Dropdown filters in a [search and filter bar](/components/search-and-filter-bar.md). Each item's touch target keeps the default height, as on compact Dropdown triggers.

```tsx
// density.tsx
import {SegmentedControl, Stack} from '@earendil-works/elanor-react';

export default function SegmentedControlDensity() {
  return (
    <Stack direction="row" gap="large" wrap="wrap">
      {(['default', 'compact'] as const).map((density) => (
        <SegmentedControl.Root
          key={density}
          density={density}
          aria-label={density === 'default' ? 'Billing period, default' : 'Billing period, compact'}
          defaultValue={['monthly']}
        >
          <SegmentedControl.Item value="monthly">Monthly</SegmentedControl.Item>
          <SegmentedControl.Item value="yearly">Yearly</SegmentedControl.Item>
        </SegmentedControl.Root>
      ))}
    </Stack>
  );
}
```

## API

### `SegmentedControl.Root`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `orientation` | `'horizontal'` | - | Only horizontal is supported. |
| `multiple` | `false` | - | One item is pressed at a time. |
| `density` | `'compact' \| 'default'` | `'default'` | `compact` removes the items' block padding but keeps their touch target height. |

Also accepts Base UI [`ToggleGroup`](https://base-ui.com/react/components/toggle-group.md) props.

### `SegmentedControl.Item`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `type` | `'submit' \| 'reset' \| 'button'` | `'button'` |  |

Also accepts Base UI [`Toggle`](https://base-ui.com/react/components/toggle.md) props.
