Select
Keyboard-friendly listbox with a glowing popover and typeahead.
Built on Icons. Installs @floating-ui/react-dom and motion.
Where your functions run. Pick the one closest to your database.
Installation
npx shadcn@latest add https://neonkit.heyaadi.com/r/select.jsonUsage
import { Select } from "@/components/ui/select"
<Select
label="Region"
defaultValue="fra1"
options={[
{ value: "fra1", label: "Frankfurt" },
{ value: "iad1", label: "Washington, D.C." },
]}
/>Examples
In a form
Give it a name and the value submits with the form through a hidden input.
Sizes
Error and disabled
API reference
Select
Also accepts native button attributes, and the ref points at the trigger. className and style go to the trigger.
| Prop | Type | Default |
|---|---|---|
options | SelectOption[]The choices, in order. | None |
value | stringControlled value. | None |
defaultValue | stringInitial value when uncontrolled. | None |
onValueChange | (value: string) => voidCalled when the user picks a different option. | None |
placeholder | ReactNodeShown while nothing is selected. | "Select…" |
name | stringSubmits the value with a surrounding form. A form reset puts back the starting value. | None |
required | booleanStops an empty submit with the browser's own message, turns the trigger red and shows the neon dot on the label. | false |
label | ReactNodeVisible label. Names both the trigger and the list. | None |
description | ReactNodeHelper text under the trigger. | None |
error | ReactNodeRed invalid state and message. Replaces description. Pass true for the state without a message. | None |
disabled | booleanBlocks opening and leaves the value out of form data. | false |
color | NeonColorPalette name or hex. Falls back to --neon-accent, then cyan. | inherited |
size | "sm"Trigger height and option padding. | "md" |
containerClassName | stringClasses for the outer block with the label, list and message. | None |
SelectOption
| Prop | Type | Default |
|---|---|---|
value | stringUnique value, also the React key. | None |
label | stringShown in the list and the trigger. Typeahead matches against it. | None |
description | stringSecond line, shown in the list only. | None |
icon | ReactNodeShown before the label in the list and the trigger. | None |
disabled | booleanVisible but can't be picked. | false |
Accessibility
- When the browser rejects the field on submit (required, type, pattern), it turns red until it's edited or the form resets. The browser shows its own message.
- Follows the WAI-ARIA select-only combobox pattern: focus stays on the trigger and aria-activedescendant tracks the highlighted option.
- Enter, Space and the arrow keys open the list. Arrows move, Home and End jump, Enter or Space picks, Escape and Tab close.
- Typing letters jumps to the first matching option. Pressing the same letter again cycles through matches.
- Without a visible label, pass aria-label. It names both the trigger and the list.
- The list renders in a portal, flips above the trigger near the bottom of the screen and is never clipped by overflow-hidden ancestors.