Components
Select
View in FigmaA single-select dropdown — a token-styled wrapper over Base UI's Select. Options are flat { value, label } data, so a CMS/query result drops straight in; the trigger matches Input's height and focus ring, and picks up the invalid treatment inside a Field. For a free-text-filterable list, reach for Base UI's Autocomplete/Combobox directly.
Install
npx shadcn@latest add @alix/selectPreview
Usage
<Field label="Owner">
<Select
placeholder="Unassigned"
items={[
{ value: "jp", label: "J. Patel" },
{ value: "rs", label: "R. Silva" },
]}
/>
</Field>Examples
01
Placeholder and selected states
The trigger shows placeholder copy until a default or controlled value resolves to an option.
<Select
placeholder="Select capability"
items={[
{ value: "turnaround", label: "Turnaround" },
{ value: "transactions", label: "Transactions" },
]}
/>
<Select
defaultValue="performance"
items={[
{ value: "performance", label: "Performance improvement" },
{ value: "investigations", label: "Investigations" },
]}
/>02
Disabled select
Disable the root when the value is locked by workflow or permissions.
<Select
disabled
defaultValue="approved"
items={[
{ value: "draft", label: "Draft" },
{ value: "approved", label: "Approved" },
]}
/>03
Form row with search text
Select pairs with Input and Field when a row combines free text with one constrained choice.
<div className="grid gap-4 md:grid-cols-[1fr_14rem_auto] md:items-end">
<Field label="Search term">
<Input placeholder="Engagement or client" />
</Field>
<Field label="Capability">
<Select
placeholder="Any"
items={[
{ value: "turnaround", label: "Turnaround" },
{ value: "performance", label: "Performance" },
{ value: "transactions", label: "Transactions" },
]}
/>
</Field>
<Button variant="outline">Apply</Button>
</div>When to use it
Use it for
- Short, flat option lists where exactly one value should be selected.
- CMS or query-driven options shaped as { value, label } data.
- Field-wrapped form controls that need the same height and focus treatment as Input.
Reach for something else
- Free-text entry or searchable filtering — use Input or InputGroup instead.
- Command lists with actions, links, or separators — use Menu instead.
- Multiple independent choices — use Checkbox instead.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| items | SelectOption[] | — | Options as flat data — { value: string, label: ReactNode }[]. Drives both the popup list and the selected label in the trigger. |
| placeholder | ReactNode | "Select…" | Shown when nothing is selected. |
| value / defaultValue | string | — | Controlled / uncontrolled selected value. |
| onValueChange | (value: string) => void | — | Fires with the new value. Never null — this is a single-select with no clear option. |
| disabled / required | boolean | — | Standard control flags; required is forwarded by Field. |