Select
A native dropdown for choosing one option from a list.
import { ... } from '@corndev/ui' HTML
<label class="corn-label" for="plan">Plan</label>
<select id="plan" class="corn-select" data-size="md">
<option>Choose…</option>
</select>
Classes
| Class |
|---|
.corn-select |
Attributes
| Attribute | Values |
|---|---|
data-size | sm|md|lg |
data-error | present or absent |
data-full-width | present or absent |
Vanilla JS
Required for behaviour — adds given options, builds the entries from data and reports the chosen value as given — a number as a number, null for the empty entry — rather than as a string.
import { createSelect } from '@corndev/ui';
import '@corndev/ui/theme';
const el = document.querySelector('#target');
const instance = createSelect(el, { /* options */ });
Options
| Option | Type | Default | Description |
|---|---|---|---|
options | Array<SelectOption|SelectGroup|string|number> | undefined | Build the <option>s from data, replacing the element’s own: strings, numbers, { label, value, disabled }, or { group, items } as <optgroup>. Values are compared with ===. Without it, the element’s markup is left alone. |
value | * | undefined | The chosen value, with options. null — or '', unless an option has that value — selects the empty entry, which is there whenever the value is null. A value the list does not contain is shown as its own entry, marked “(not in the list)”, rather than as whichever option happens to be first. Pass it to update() to set the value from outside. |
onChange | (value: *, option: SelectOption|null) => void | undefined | With options: called with the chosen value and its option, or null, null for the empty entry — the value as given, a number as a number. |
placeholder | string | undefined | With options: an empty first entry showing this text, selected while the value is null. It cannot be chosen back unless clearable. |
clearable | boolean | false | With options: the empty entry can be chosen, returning the field to null. Without a placeholder it reads blank. |
size | 'sm'|'md'|'lg' | 'md' | |
disabled | boolean | false | |
error | boolean | false | |
fullWidth | boolean | false |
React
Select — from @corndev/ui-react.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
options | Array<SelectOption|SelectGroup|string|number> | undefined | The choices, in place of children: strings, numbers, { label, value, disabled }, or { group, items }. Values are compared with ===. |
value | * | undefined | The chosen value (controlled), with options. null — or '', unless an option has that value — selects the empty entry, which is there whenever the value is null. A value the list does not contain is shown as its own entry, marked “(not in the list)”, rather than as whichever option happens to be first. |
defaultValue | * | undefined | Initially chosen (uncontrolled), with options. |
onChange | ((value: *, option: SelectOption|null) => void) | React.ChangeEventHandler<HTMLSelectElement> | undefined | With options: called with the chosen value and its option, or null, null for the empty entry. With children: the native change event. |
placeholder | string | undefined | With options: an empty first entry showing this text, selected while the value is null. It cannot be chosen back unless clearable. |
clearable | boolean | false | With options: the empty entry can be chosen, returning the field to null. Without a placeholder it reads blank. |
size | 'sm'|'md'|'lg' | 'md' | |
disabled | boolean | false | |
error | boolean | false | |
fullWidth | boolean | false | |
children | React.ReactNode | undefined | Option elements, when not using options. |
className | string | undefined |
Default
<Label htmlFor="plan">Plan</Label>
<Select id="plan">
<option value="">Choose an option</option>
<option value="a">Option A</option>
<option value="b">Option B</option>
</Select>Sizes
<Select size="sm" aria-label="Small">...</Select>
<Select size="md" aria-label="Medium">...</Select>
<Select size="lg" aria-label="Large">...</Select>Error state
<Select error aria-label="Plan">...</Select>Disabled
<Select disabled aria-label="Plan">...</Select>Full width
<Select fullWidth aria-label="Plan">...</Select>From data
Pass options instead of children — the same shapes as Combobox and
SegmentedControl, so one list can feed any of them:
<Select
aria-label="Type"
options={['any', { label: 'Integer', value: 1 }, { group: 'Text', items: ['string', 'uuid'] }]}
placeholder="Choose a type"
clearable
value={type}
onChange={setType}
/>
onChangereceives the value, as given —1comes back as the number1, not the string a<select>reports — and the option it came from. With children,onChangeis still the native event.- Groups render as
<optgroup>, and{ disabled: true }disables one entry. - The field always shows the value it holds. While the value is
nullthere is an empty first entry —placeholdergives it text — which cannot be chosen back unless the field isclearable. A value the list does not contain is shown as its own entry, marked “(not in the list)”, rather than as whichever option comes first — a<select>left to itself shows the first option either way. clearablelets the empty entry be chosen, which callsonChange(null, null)—null, not'', so a document field is cleared rather than set to an empty string.
It is still a native <select>: the browser’s own list, keyboard and form
submission, where each option submits its value as text.