Select
Native select with label, hint, and error wiring.
import { Select } from '@elirobinson/react/components/organisms/Select';Styles: @elirobinson/react/styles/atoms/field.css — already included when you import @elirobinson/react/styles.css.
Show code
import { Select } from '@elirobinson/react/components/organisms/Select';
export default function Basic() {
return (
<Select label="Sport" defaultValue="">
<option value="">Choose a sport</option>
<option value="football">Football</option>
<option value="basketball">Basketball</option>
<option value="rugby">Rugby</option>
<option value="netball">Netball</option>
</Select>
);
}When to use it
Use Select when the options are plain text and few enough to scan — roughly under twenty.
It renders a native <select>, so you get the platform's picker, keyboard support, and
typeahead for free, on every device, without a line of extra code.
Reach for Combobox instead once the list needs search-as-you-type, or an option needs more
than a label — an icon, a description, a secondary line. Reach for RadioGroup when there
are only two to four choices and showing them all at once beats hiding them behind a click.
Hint, error, and disabled
hint and error share one line under the field — passing both shows only the error,
with aria-invalid set on the <select> and the message announced immediately.
Show code
import { Select } from '@elirobinson/react/components/organisms/Select';
export default function States() {
return (
<div className="demo-col">
<Select label="Sport" hint="Filter guides by sport." defaultValue="">
<option value="">Choose a sport</option>
<option value="football">Football</option>
<option value="basketball">Basketball</option>
<option value="rugby">Rugby</option>
</Select>
<Select label="Sport" error="Choose a sport to see matching guides." defaultValue="">
<option value="">Choose a sport</option>
<option value="football">Football</option>
<option value="basketball">Basketball</option>
<option value="rugby">Rugby</option>
</Select>
<Select label="Sport" disabled defaultValue="football">
<option value="football">Football</option>
<option value="basketball">Basketball</option>
</Select>
</div>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
labelrequired | string | — | — |
error | string | — | — |
hint | string | — | — |
Also accepts all SelectHTMLAttributes<HTMLSelectElement> props.
Accessibility
- Renders a native
<select>wired to a real<label>viahtmlFor/id— no ARIA substitute needed for the label relationship. errorsetsaria-invalid="true"on the<select>and renders withrole="alert", so assistive tech announces it as soon as it appears. It also takes over the description slot fromhint— the two never show at once.hintanderrorare wired througharia-describedby, merged with anyaria-describedbyyou pass in yourself rather than overwriting it.- Keyboard: entirely native.
Tabfocuses the control,Enter/Space/Down Arrowopen the option list, arrow keys move through it, and typing jumps to a matching option. None of this is reimplemented — it's the browser's own<select>behavior, which is why it also gets the OS-native picker UI on mobile for free. - The ref forwards to the underlying
<select>element.
Do
- Pass a real label string every time — it is required, and renders as a genuine <label>.
- Use hint for supporting context and error for validation — error automatically replaces the hint so they never stack.
- Trust the native option list for anything under about twenty items.
- Read the value off the native change event, the same as any uncontrolled <select>.
Don't
- Reach for Select when options need icons, descriptions, or search — use Combobox instead.
- Build a custom-styled dropdown on top of a hidden <select> — the native picker is the accessible one.
- Rely on placeholder-only labelling; an empty or missing label leaves the field unannounced.
- Show a validation error without also setting the field to error — the message and the state should move together.