When to use
- Known finite choices
- Status filters
- Compact single-choice fields
Select lets users choose one value from a known list. Use it when choices are stable and compact, and when seeing every option at once is not essential.
Start here before choosing examples or props. These notes explain where Select helps, where another pattern is better, and what should stay true in product work.
import { Select } from '@/components/ui/Select';Wraps a native select with label, helper, and error wiring; options are passed as children.
Select states should behave like conventional form controls. The control can change border, surface, and message tone, but it should not move or animate.
Choose the status that best matches the request.
Ready for a user to choose one value from a compact list.
Keyboard users can open and change the selection.
Uses a stable focus ring without moving the control.
Select a status before submitting the request.
Tells users why the current state cannot continue.
Status is locked after final approval.
Shows a value that cannot be changed in the current workflow state.
A select field is more than a collapsed menu. Its label, selected value, option set, and helper text need to work together so the choice is understandable before and after it is made.
Choose the status that best matches the request.
The component accepts every native HTMLSelectElement attribute on top of the design system props below.
| Prop | Type | Default | Description |
|---|---|---|---|
label | ReactNode | — | Visible label rendered above the select. Required for accessibility. |
helper | ReactNode | — | Guidance text below the select. Auto-wired to aria-describedby. |
error | ReactNode | — | Error message. Replaces helper text and sets aria-invalid on the select. |
children | ReactNode | — | Native <option> elements passed as children of the select. |
Select works well when the option set is stable, short enough to scan, and only one value can be chosen.
If users need to compare all options before deciding, use radio buttons instead of a collapsed select.
The selected value should not be responsible for explaining the field. Labels and helper text carry that context.
For large lists, remote results, or typeahead needs, use a combobox/autocomplete pattern when it exists.
What Select does not do yet, and what consumers need to compose themselves.
Agents should choose Select only when the choice set is known, compact, and single-select. Otherwise, use the component or pattern that better matches the task.
import { Select } from '@/components/ui/Select';
<Select
label="Request status"
name="requestStatus"
defaultValue="pending-review"
helper="Choose the status that best matches the request."
>
<option value="pending-review">Pending review</option>
<option value="approved">Approved</option>
<option value="needs-info">Needs information</option>
</Select>Select is a compact choice control, not the default answer for every option list. Use it when compactness matters more than side-by-side comparison.