# Option group (goodtabs UI)

Single or multi choice pills on a muted track or laid out loose, from an options array.

## Install

```bash
npx shadcn@latest add https://ui.goodtabs.co/r/option-group.json
```

Or, with the @goodtabs namespace configured in components.json: `npx shadcn@latest add @goodtabs/option-group`

## Usage

```tsx
import { OptionGroup } from "@/components/ui/option-group"

<OptionGroup
  aria-label="Billing period"
  value={period}
  onValueChange={setPeriod}
  options={[{ value: "monthly", label: "Monthly" }, { value: "yearly", label: "Yearly" }]}
/>
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| options | `{ value: string; label: ReactNode; icon?: ReactNode; disabled?: boolean }[]` |  | The choices, in order. |
| type | `"single" | "multiple"` | `"single"` | One choice at a time, or any number. Sets the shape of value. |
| value, defaultValue | `string | string[]` |  | A string for single, an array for multiple. Controlled or uncontrolled. |
| onValueChange | `(value: string | string[]) => void` |  | Fires with the new value, typed to match type. |
| variant | `"track" | "pills"` | `"track"` | On a muted track like segmented tabs, or loose pills with a gap. |
| size | `"sm" | "default"` | `"default"` | 28px or 32px pills. |
| disabled | `boolean` | `false` | Disables every option. |

## When to use

- Two to six short choices that should all be visible: period, layout, plan, pricing filter
- Multi select filters where a select would hide the current state
- Inside a toolbar or a card header next to a title

## When not to use

- Switching views with their own content panels: use segmented tabs
- Long labels or more than six options: use a select or checkboxes
- One on or off setting: use a switch

## Notes for agents

- Built on shadcn's ToggleGroup, so it is radix underneath: single lets the user deselect by clicking the active pill
- onValueChange is a function, so a controlled OptionGroup must be rendered from a client component
- Pass aria-label on the group; a non string label on an option falls back to its value as the aria-label
- Selected is bg-primary text-primary-foreground, unselected is quiet text; nothing else is coloured

Docs: https://ui.goodtabs.co/components/option-group