Select
Basic
Grouped
Small
Searchable
Custom Items
Uses renderItem to add colored dots.
Rich Items (Cars)
Each row shows drivetrain and horsepower. The trigger displays only the car name.
Last Selected
Select a value, close, then reopen — the last pick is shown at the bottom.
Last Selected (Custom)
Same feature with a custom footer via renderLastSelected.
Loading
Disabled
Select
A select dropdown built on Radix UI Select. Supports groups, labels, separators, disabled states, and two trigger sizes.
Usage
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectSeparator,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
<Select value={value} onValueChange={setValue}>
<SelectTrigger className="w-50">
<SelectValue placeholder="Pick one" />
</SelectTrigger>
<SelectContent>
<SelectItem value="apple">Apple</SelectItem>
<SelectItem value="banana">Banana</SelectItem>
</SelectContent>
</Select>Select (root) props
| Prop | Type | Default | Description |
|---|---|---|---|
| value | string | — | Controlled selected value. |
| defaultValue | string | — | Uncontrolled default value. |
| onValueChange | (value: string) => void | — | Callback when the selected value changes. |
| renderItem | (entry: { value: string; label: string }) => ReactNode | — | Custom render function for each SelectItem's content. Receives the item's value and label. The return replaces the default text inside the item row — selection indicator and focus styles are preserved. |
| disabled | boolean | false | Disables the entire select. |
| open | boolean | — | Controlled open state of the dropdown. |
| onOpenChange | (open: boolean) => void | — | Callback when the open state changes. |
| selectId | string | — | Unique identifier for the select instance. Used as the cookie key for persisting the last selected value. |
| enableLastSelected | boolean | false | When true (and selectId is set), persists the last selected value in a cookie and shows a suggestion footer in the dropdown. |
| renderLastSelected | (entry: { value: string; label: string }) => ReactNode | — | Custom render function for the last-selected footer content. Receives the saved entry. The return value is placed inside the footer button — you provide the inner content, the component handles the click behavior. |
SelectTrigger props
| Prop | Type | Default | Description |
|---|---|---|---|
| size | "sm" | "default" | "default" | Trigger height. sm = 32px, default = 36px. |
| loading | boolean | false | Shows a skeleton shimmer overlay and disables the trigger. Useful while data is being fetched. |
| className | string | — | Additional CSS classes. |
SelectValue props
| Prop | Type | Default | Description |
|---|---|---|---|
| placeholder | string | — | Text shown when no value is selected. |
SelectItem props
| Prop | Type | Default | Description |
|---|---|---|---|
| value* | string | — | The value for this option. |
| searchValue | string | — | Custom string to match against when filtering. Defaults to children text or value. |
| disabled | boolean | false | Disables this individual item. |
| className | string | — | Additional CSS classes. |
SelectContent props
| Prop | Type | Default | Description |
|---|---|---|---|
| searchable | boolean | false | Renders a search input at the top of the dropdown to filter items. Forces popper positioning. |
| searchPlaceholder | string | "Search..." | Placeholder text for the search input. Only used when searchable is true. |
| position | "item-aligned" | "popper" | "item-aligned" | Positioning strategy for the dropdown. Forced to popper when searchable. |
| align | "start" | "center" | "end" | "center" | Alignment of the content relative to the trigger. |
| className | string | — | Additional CSS classes. |