Browse the docs
Select Menu
Custom select with styled options, typeahead, and form participation (a
hidden input submits the value). Focus stays on the trigger's listbox while
aria-activedescendant tracks the highlighted option — the WAI-ARIA
combobox-with-listbox pattern, from the listbox primitive.
The native Select stays the better default — it gets the platform's own dropdown and is correct on touch for free. Reach for this one when options need markup or styling the native popup can't do.
This component needs the listbox primitive — two ways to get it:
- Copy: fetch
/r/primitives/listbox.txt— one file with the shared core embedded — and save it asprimitives/listbox.js. - Install:
npm install @presetui/ui— the primitives are bundled, no second package — then use the Source · npm tab below, whose import already points at@presetui/ui/primitives/listbox.
Submitted as: —
Props
| Prop | Values | Default | Description |
|---|---|---|---|
options | { value, label, disabled? }[] | required | The options. |
value / onValueChange | string / function | — | Controlled selection; defaultValue for uncontrolled. |
placeholder | node | "Select…" | Shown until something is selected. |
name | string | — | Adds a hidden input so the value submits with a form. |
invalid | boolean | false | Danger border and aria-invalid. |
className | string | "" | Applied to the trigger. |
Notes
For grouped options or custom option markup, compose the primitive directly:
SelectRoot, SelectTrigger, SelectValue, SelectContent,
SelectOption, SelectGroup.