<!-- https://getkonjo.com/design/components/segmented-control · source: docs/design/components/segmented-control.md -->

# Segmented control

A connected track of equal segments that switches a view in place. The chosen segment is red.

```kata-specimen
segmented-states
```

> Source: [`SegmentedControl.tsx`](../../../src/components/ui/SegmentedControl.tsx).

## When to use it

- Two to four short, mutually exclusive views of the same content: Upcoming / Past, Week /
  Month / Year, the lanes of the coaching hub.
- When switching is instant and loses nothing.

Not for five or more options, or labels longer than a word or two — use chips or a sheet. Not
for navigation to a different screen. Not for a form value that is submitted later — use chips
inside the form so the choice stays visible.

## Anatomy

| Part | Token |
|---|---|
| Track | `surface.card` fill, 1px `border.control`, `radius.pill` |
| Track inset | `spacing.s2` padding, `spacing.s4` between segments |
| Segment | equal width, `spacing.s8` padding, `radius.pill` |
| Label | 13/500, `text.secondary`; selected `brand.onRed` |
| Selected fill | `brand.red` |
| Count | an 18pt pill after the label, `spacing.s6` gap; `border.default` fill on `surface.card` (the track), with `text.secondary`, inverted to `brand.onRed` with `brand.red` text on the selected segment |

## States

- **Selected**: the red fill. Only one segment is selected at any time.
- **Focus**: a 2px `border.focus` ring just inside the focused segment — the track packs
  segments 4pt apart, so a ring outside one would land on its neighbour. Web keyboard focus only.
- **Pressed**: the segment drops to `opacity.pressed` 0.85.
- **Disabled, loading, error**: none. If a view has nothing in it, show its empty state after
  the switch rather than hiding the segment.

## Content

- One word per segment where possible, two at most. Labels are held to one line inside equal
  segments — the one place Kata allows a single line — so a long label is a design bug.
- A count says how many are waiting, not a total for decoration. Zero hides the count.

## Accessibility

- Each segment is role `button` with `accessibilityState={{ selected }}` and the label as its
  name, so "Upcoming, selected" is read.
- `brand.onRed` on `brand.red` is 5.00:1 in both themes. `border.control` on `surface.card` is
  3.53:1 in light and 3.16:1 in dark, so the track's edge clears the 3:1 a control boundary owes.
- Each segment is about 38pt tall drawn; the 2pt track inset and a 44pt row around it bring the
  target to size.

## Do and don't

```kata-specimen
segmented-count
```

## Code

```tsx
import { SegmentedControl } from '../../components/ui';

<SegmentedControl
  options={[
    { value: 'upcoming', label: 'Upcoming', testID: 'events-upcoming' },
    { value: 'past', label: 'Past', testID: 'events-past' },
  ]}
  value={view}
  onChange={setView}
  testID="events-view"
/>
```
