# Choice Chips

> Pills for short tags, like teams, plans, and days of the week. Pick several by default, with a check that springs in, or pick one with the arrow keys.

- Name: `choice-chips`
- Status: beta
- Categories: forms
- File: the install writes `choice-chips.tsx` to your `ui` alias, `@/components/ui` by default.
- Other registry items: `@arbokui/field-frame`. The install adds them.
- Gallery: https://arbokui.com/components/choice-chips
- Registry item: https://arbokui.com/r/choice-chips.json

## Install

1. Add the registry to `components.json`. Do this first, once:

   ```bash
   npx shadcn@latest registry add "@arbokui=https://arbokui.com/r/{name}.json"
   ```

   The command writes this entry. You can also add it by hand:

   ```json
   {
     "registries": {
       "@arbokui": "https://arbokui.com/r/{name}.json"
     }
   }
   ```

   Without this step, the shadcn CLI looks up `@arbokui` in a public list that Arbokui does not control.

2. Add the theme once per app. It replaces your color tokens with ones checked for contrast:

   ```bash
   npx shadcn@latest add @arbokui/theme
   ```

3. Add the component:

   ```bash
   npx shadcn@latest add @arbokui/choice-chips
   ```

## Use it for

- Short tags only: teams, plans, days of the week. One or two words each.
- Pick several by default. Each chip is a checkbox, a Tab stop of its own, and Space ticks it.
- Pass multiple={false} to pick one. The chips become a radio group: one Tab stop, and the arrows move and choose.
- In a single choice, pressing the chosen chip again clears it, so the value can be null.
- Set max to cap how many can be picked. Say the cap in the label, like "Teams · up to 3". The rest dim once it is reached.
- Set error when the form is sent with nothing picked, like "Pick at least one team".

## Avoid it for

- An option with a hint, a price, or a consequence. Use a selection card.
- A long list, or one people search. Use a combobox.
- Turning one setting on or off. Use a switch.
- Free tags people make up. These chips only offer the options you pass.

## Props

- `options`: `Array<string | { id: string; label: string; count?: number }>`. The chips. A string is its own id and label. count shows a muted number after the label.
- `multiple`: `boolean`. Default `true`. Pick several, as checkboxes. false picks one, as a radio group, and value becomes one id or null.
- `value`: `string[] | string | null`. The ids picked: an array, or one id or null when multiple is false. Use it with onValueChange.
- `defaultValue`: `string[] | string | null`. The ids picked at first render, when you do not control them.
- `onValueChange`: `(value: string[] | string | null) => void`. Called with the ids picked, or with one id or null when multiple is false.
- `max`: `number`. Most that can be picked. Once it is reached, the rest dim and do nothing when pressed.
- `label`: `ReactNode`. Names the group, above it. Pressing it focuses the group's Tab stop.
- `hint`: `ReactNode`. A short note under the chips. It describes the group.
- `error`: `ReactNode`. Replaces the hint, in red, rings the open chips in red, and is announced once.
- `size`: `"sm" | "md" | "lg"`. Default `"md"`. Chip height and text size: 28, 32, or 36px at the default density.
- `disabled`: `boolean`. Default `false`. Blocks every chip, and dims the label.
- `className`: `string`. Classes for the frame. id, ref, and aria-\* land on the group.

## Accessibility

- Several answers: a group of checkboxes. Each chip is a Tab stop, and Space ticks it.
- One answer: a radio group. Tab lands on the chosen chip, or the first. The arrows move and choose, and wrap. Home and End jump to the ends.
- The label names the group, and the hint or error describes it. An error is announced once when it appears.
- Once max is reached, the rest are aria-disabled, so they stay findable with the keys.
- Focusing the group itself, as a form does with its first error, moves focus to its Tab stop.
- A chosen chip shows by its fill and, with several answers, a check. In forced-colors mode, where fills are gone, a single answer shows the check too.

## Examples

### Several answers

```tsx
<ChoiceChips
  label="Teams · up to 3"
  options={["Design", "Engineering", "Support", "Marketing"]}
  defaultValue={["Engineering"]}
  max={3}
/>
```

### One answer

```tsx
<ChoiceChips
  multiple={false}
  label="Plan"
  options={["Starter", "Team", "Business", "Scale", "Enterprise"]}
  defaultValue="Team"
/>
```
