Select
Single-choice listbox styled like Input, with groups, icons and disabled options. Native-select keyboard (arrows, typeahead even while closed), flips above the trigger near the viewport edge, submits via a hidden input.
"use client";import { useState } from "react";import { Field } from "@/components/ui/field";import { Select } from "@/components/ui/select";const roles = [ { value: "admin", label: "Admin" }, { value: "moderator", label: "Moderator" }, { value: "member", label: "Member" },];export function RolePicker() { const [role, setRole] = useState("member"); return ( <Field label="Role"> <Select name="role" options={roles} value={role} onValueChange={setRole} /> </Field> );}<Select>
Single-choice listbox styled like Input. Keyboard matches a native select: Up, Down, Home, End, typeahead (also while closed), Enter or Space to pick, Esc to cancel.
options*SelectGroup[] | SelectOption[]Flat options, or labeled groups of options.
aria-describedbystringIds of hint or error text; Field fills it in.
aria-invalidbooleanError styling; Field sets it from
error.aria-labelstringAccessible name when there is no visible label.
defaultValuestringValue at first render (uncontrolled).
disabledbooleanBlocks opening.
idstringPair with <Label htmlFor>, or let <Field> fill it in.
namestringSubmits the value with a form, through a hidden input.
onValueChange(value: string) => voidCalled with the picked value.
placeholderstringTrigger text when nothing is picked.
requiredbooleanForm submit needs a value.
valuestringControlled value; pair with
onValueChange.
| Prop | Type | Default |
|---|---|---|
options*Flat options, or labeled groups of options. | SelectGroup[] | SelectOption[] | — |
aria-describedbyIds of hint or error text; Field fills it in. | string | — |
aria-invalidError styling; Field sets it from | boolean | — |
aria-labelAccessible name when there is no visible label. | string | — |
defaultValueValue at first render (uncontrolled). | string | — |
disabledBlocks opening. | boolean | — |
idPair with <Label htmlFor>, or let <Field> fill it in. | string | — |
nameSubmits the value with a form, through a hidden input. | string | — |
onValueChangeCalled with the picked value. | (value: string) => void | — |
placeholderTrigger text when nothing is picked. | string | — |
requiredForm submit needs a value. | boolean | — |
valueControlled value; pair with | string | — |
- type SelectOption
- { value: string; label: string; icon?: ReactNode; disabled?: boolean }
- type SelectGroup
- { label: string; options: SelectOption[] }
* required. Every component also takes className.