Select
Accessible select based on react-aria-components (custom listbox, not a
native <select>). Token-driven; invalid state flows from the RAC form
context via group-data-[invalid]. label/description render inside so
RAC links the accessible name — this component is the field, which is why
there is no separate SelectField to compose those around it. Compose options
with SelectItem.
import { Select } from "@evolve-storefront/ui/select";Design notes
The error message is rendered here rather than composed, for the same reason:
children belongs to the options, so a caller has nowhere to put a
FieldError the way a TextField caller does. RAC renders nothing when the
field is valid.
Preview
Usage
<Select name="country" label={t("country")} placeholder={t("pickCountry")} onValueChange={setCountry}> {countries.map((country) => ( <SelectItem key={country.code} id={country.code}> {country.name} </SelectItem> ))}</Select>;Props
| Prop | Type | Description |
|---|---|---|
data-component? | undefined | Not a caller's to rename — see |
name? | string | |
autoComplete? | string | The autofill hint for the hidden native select, such as |
value? | string | |
defaultValue? | string | |
onValueChange? | ((value: string) => void) | Hands over the chosen value. Not |
disabled? | boolean | |
required? | boolean | |
invalid? | boolean | |
children? | ReactNode | |
label? | ReactNode | RAC-linked visible label. Rendered inside the select so RAC wires the accessible name. |
description? | ReactNode | |
labelClassName? | string | |
placeholder? | string | |
placement? | SelectPlacement |
Any other props go to the root element, like on a plain HTML element.
Change the layout
Pass children to Select to arrange its parts yourself. Every part is exported from @evolve-storefront/ui/select.
SelectItemA single option inside Select.
| Prop | Type | Description |
|---|---|---|
id | string | The value reported by |
disabled? | boolean | |
textValue? | string | Announced instead of the children when the option is not plain text. |
Any other props go to the root element, like on a plain HTML element.
Examples
VariantsThe states side by side: a chosen value, invalid, and disabled.
<Select name="country" label={t("country")} defaultValue={address.country}>{options}</Select>// Marks the field without a reason; prefer validationErrors on the Form.<Select name="country" label={t("country")} invalid={!country}>{options}</Select><Select name="country" label={t("country")} defaultValue="nl" disabled>{options}</Select>With ErrorThe real path: a Form supplies validationErrors keyed by field name, and RAC routes the entry to the select's own FieldError.
// The Form routes the error to the select by its name.<Form validationErrors={validationErrors}> <Select name="country" label={t("country")} required> {options} </Select></Form>;
