NativeSelect
A styled native <select> that keeps platform form/keyboard behavior with a custom chevron and focus ring
Category: inputs · WCAG 2.2-AA · inputs, select, native, form, dropdown
Sizes
- sm
- md
- lg
States
- default
- focus
- disabled
- invalid
Props
| Prop | Type | Default | Description |
|---|---|---|---|
options | NativeSelectOption[] | — | Options to render. Alternatively pass <option> children. |
children | React.ReactNode | — | Raw <option> children (used when options is not provided). |
size | 'sm' | 'md' | 'lg' | md | Visual size of the component (e.g. 'sm', 'md', 'lg'). |
invalid | boolean | — | Marks the control as invalid for error styling and a11y. |
placeholder | string | — | Placeholder rendered as a disabled, hidden first option. |
value | string | — | The controlled value. |
defaultValue | string | — | The initial value when uncontrolled. |
onChange | React.ChangeEventHandler<HTMLSelectElement> | — | Called when the selected value changes. |
disabled | boolean | — | When true, disables the control and removes it from the tab order. |
className | string | — | Additional CSS class names merged onto the root element. |
Design tokens
--cascivo-color-surface--cascivo-color-border--cascivo-color-border-strong--cascivo-color-accent--cascivo-color-destructive--cascivo-color-text-muted--cascivo-radius-field--cascivo-focus-ring
When to use
- A standard single-choice dropdown where native behavior and form integration matter most
- Mobile-first forms that should use the platform picker UI
- Pairing with a Field/Label inside a regular HTML form
When not to use
- Multi-select, search/typeahead, or rich option rendering — use the custom Select/Combobox
- A handful of mutually exclusive options where radios read better
How to build an accessible NativeSelect in React →
Examples
Basic
<NativeSelect
placeholder="Choose a country"
options={[
{ value: 'us', label: 'United States' },
{ value: 'de', label: 'Germany' },
]}
onChange={(e) => setCountry(e.target.value)}
/>Option children
<NativeSelect size="sm" defaultValue="light" aria-label="Theme">
<option value="light">Light</option>
<option value="dark">Dark</option>
</NativeSelect>Invalid
<NativeSelect invalid placeholder="Required" options={countries} />