NativeSelect
The platform <select> with Merid styling. You get the full native keyboard, the operating system's picker on mobile and form participation without any JavaScript.
<NativeSelect aria-label="Country" placeholder="Choose a country">
<option value="tr">Türkiye</option>
<option value="de">Germany</option>
<option value="nl">Netherlands</option>
</NativeSelect>Import
import { NativeSelect } from "@merid/react";Examples
Sizes
sm is 36px, md 46px (default) and lg 50px — the same heights as Input, so they line up in a row.
<NativeSelect aria-label="Small" size="sm" defaultValue="a">…</NativeSelect>
<NativeSelect aria-label="Medium" size="md" defaultValue="a">…</NativeSelect>
<NativeSelect aria-label="Large" size="lg" defaultValue="a">…</NativeSelect>In a Field
Inside a Field the select picks up its id, aria-describedby, required and disabled from context — no manual wiring.
You can change plans at any time.
<Field label="Plan" description="You can change plans at any time." required>
<NativeSelect placeholder="Select a plan">
<option value="free">Free</option>
<option value="team">Team</option>
<option value="business">Business</option>
</NativeSelect>
</Field>Invalid and disabled
A Field error sets aria-invalid on the select and links the message. Outside a Field pass invalid directly.
Pick a region to continue.
<Field label="Region" error="Pick a region to continue.">
<NativeSelect placeholder="Select a region">…</NativeSelect>
</Field>
<Field label="Currency" disabled>
<NativeSelect defaultValue="eur">
<option value="eur">EUR</option>
</NativeSelect>
</Field>Controlled
Use value and onChange exactly as with a native select.
Current value: weekly
const [value, setValue] = useState("weekly");
<Field label="Digest frequency">
<NativeSelect value={value} onChange={(e) => setValue(e.target.value)}>
<option value="daily">Daily</option>
<option value="weekly">Weekly</option>
<option value="monthly">Monthly</option>
</NativeSelect>
</Field>API reference
The ref and all native select attributes go to the <select>, except className and style, which are applied to the outer wrapper. The native size attribute is replaced by the size prop below.
| Prop | Type | Default | Description |
|---|---|---|---|
size | "sm" | "md" | "lg" | "md" | Height: sm 36px, md 46px, lg 50px. |
invalid | boolean | – | Forces the invalid style (`data-invalid`) and `aria-invalid`. Inside a Field, derived from its error. |
placeholder | string | – | Adds a disabled, hidden `value=""` first option, shown whenever the value is `""` (uncontrolled start or a controlled `value=""`). |
children | ReactNode | – | option and optgroup elements. |
Styling
| Hook | Values |
|---|---|
.mrd-native-select | Wrapper <span>; receives className and style |
.mrd-native-select__control | The <select> |
.mrd-native-select__chevron | Decorative chevron icon |
data-size | sm · md · lg (on the wrapper) |
data-invalid | On the control when invalid; drives the danger border (aria-invalid carries the semantics) |
Component variable: --mrd-input-height, shared with Input.
Accessibility
- It is a real
<select>, so screen readers announce it as a combobox or list box with its options, and mobile browsers open the native picker. - Give it a name: a surrounding Field, a
LabelwithhtmlFor, oraria-label. Theplaceholderoption is not a label.
| Key | Action |
|---|---|
| Tab | Moves focus to the select. |
| Space | Opens the option list (platform dependent). |
| ↑↓ | Changes the selected option. |
| A–Z | Jumps to the first option starting with the typed character. |
Guidelines
Do
Use NativeSelect for plain lists of known options, especially in forms used on phones.
Avoid
Put rich content, icons or search inside it — reach for Select instead.
Do
Use a placeholder that prompts a choice, like “Select a plan”, when there is no sensible default.
Avoid
Rely on the placeholder as the only label.
Related
- Select — custom listbox with richer options.
- Field — label, description and error wiring.
- Input — single-line text with the same sizes.
- SegmentedControl — for two to five visible options.