# Select

> Slug: `select` · Category: Form Controls

## When to use

- Choosing one item from a known list of 5+ options where space is tight.
- Country, state, language, plan tier, billing cycle, or any closed enumeration.

## When NOT to use

- Fewer than 5 options where the choices should always be visible — use `RadioGroup` or `Chips variant="radio"`.
- Type-ahead search of a long list — use `MenuDropdown variant="searching"`.
- Multi-select — use a checkbox list or `Chips variant="toggle"`.
- Rich option content (icons, descriptions, prices) — use `StyledRadioGroup`.

## Variants & decision tree

Wraps the native `<select>` with the floating-label track and Arrow styling. Pass options via the `options` array; per-option `disabled` is supported.

## States

Empty (placeholder visible, label floating), filled, focused, disabled, error (`errorMessage`), with helper text (`supportingText`).

## Props

| Prop | Type | Default | Description |
|---|---|---|---|
| `id` | `string` | — | Required. Select element id. |
| `label` | `string` | — | Required. Floating label. |
| `options` | `SelectOption[]` | — | Required. `[{ label, value, disabled? }]`. |
| `value` | `string` | — | Controlled selection. |
| `defaultValue` | `string` | — | Uncontrolled initial selection. |
| `onChange` | `ChangeEventHandler` | — | Fires with `e.target.value`. |
| `errorMessage` | `string` | — | Inline error text. |
| `supportingText` | `string` | — | Helper text. |
| `inverse` | `boolean` | `false` | Dark-background styling. |
| `active` | `boolean` | `false` | Force active visual for demos. |
| `disabled` | `boolean` | `false` | Disable. |
| `name` | `string` | — | Form submission name. |

## Usage examples

```tsx
// Controlled
const [plan, setPlan] = useState('');
<Select
  id="plan"
  name="plan"
  label="Choose a plan"
  value={plan}
  onChange={(e) => setPlan(e.target.value)}
  options={[
    { label: 'Basic', value: 'basic' },
    { label: 'Pro', value: 'pro' },
    { label: 'Premium', value: 'premium' },
  ]}
/>

// With error and helper text
<Select
  id="country"
  label="Country"
  options={countries}
  errorMessage="Please select a country"
  supportingText="Used for billing"
  required
/>
```

## Composition

Use inside a `<form>` alongside `TextField`, `Checkbox`, etc. Combine with `Button type="submit"`.

## Accessibility

`id` and `label` are required. Arrow renders the `<label htmlFor={id}>` so do not wrap it manually. Per-option `disabled` is honored. `errorMessage` wires `aria-invalid` + `aria-describedby`. The native select preserves all keyboard semantics (typeahead, arrow navigation).

## Do / Don't

- DO use `Select` when option content is plain text and the list is closed.
- DO sort options logically (alphabetical, by frequency, or by recommended order).
- DON'T cram rich content (icons, prices, badges) into option labels — use `StyledRadioGroup` or `MenuDropdown`.
- DON'T leave `label` empty; the floating label IS the field's accessible name.
