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

# Tag chip

A pill you pick. Interactive chips filter or choose; readonly chips label a session's tags.

```kata-specimen
chip-states
```

> Source: [`TagChip.tsx`](../../../src/features/train/components/TagChip.tsx), exported from the
> barrel as `TagChip`. Filter rules: [search-filter](../patterns/search-filter.md). Chips vs.
> a sheet: [sheet-picker](../patterns/sheet-picker.md).

## When to use it

- **Interactive**: two to six options that stay visible while you choose (a session's tags), or
  the active filters under a search field.
- **Readonly**: tags shown inside something else that is already pressable, like a session row.

Not as a checkbox — a chip is a value you are picking, a [checkbox](checkbox.md) is a decision
about something already there. Not for seven or more options — use a sheet. Not for a rank:
rank is always rows, because a chip cannot carry a swatch and its ring.

## Anatomy

| Part | Interactive | Selected | Readonly |
|---|---|---|---|
| Fill | `surface.card` | `brand.red` | `surface.tag` |
| Edge | 1px `border.control` | 1px `brand.red` | none |
| Label | `typography.caption` 13/400, `text.primary` | `typography.caption`, `brand.onRed` | `typography.micro` 12/500, `text.secondary` |
| Padding | `spacing.s6` × `spacing.s12` — 32 tall with the edge | same, so selecting never resizes | `spacing.s6` × `spacing.s12` |
| Shape | `radius.pill` | `radius.pill` | `radius.pill` |

A row of chips wraps with `spacing.s8` between them.

## States

- **Default and selected** as drawn. Selected is red because red is Kata's selected state.
- **Pressed**: `opacity.pressed` 0.85.
- **Focus**: a 2px `border.focus` ring, drawn on the page behind the chip — web keyboard focus
  only.
- **Removable filter**: an active filter chip carries its own × and removes itself on tap.
- **Disabled**: none. An option that cannot be chosen is not shown.

## Content

- One or two words, sentence case.
- Chips **wrap**. They never scroll sideways, because a filter you cannot see is a filter you
  forget is on.
- More than two active filters get a "Clear all" text link after them.

## Accessibility

- An interactive chip announces role `button` with `accessibilityState={{ selected }}`. Not
  `checkbox`: every caller toggles a value into a set, and a chip is a value being picked.
- The chip's drawn height is 32pt, under the 44pt target; give it a 44pt row around it.
- `brand.onRed` on `brand.red` is 5.00:1 in both themes, so the selected label is legible.
- A readonly chip's `surface.tag` fill is nearly the page's colour. That is why it is never a
  control: it has no visible edge.

## Do and don't

```kata-specimen
chip-wrap
```

## Code

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

{tags.map((tag) => (
  <TagChip
    key={tag.id}
    variant="interactive"
    label={tag.label}
    selected={chosen.has(tag.id)}
    onPress={() => toggle(tag.id)}
    testID={`session-tag-${tag.id}`}
  />
))}
```
