Select
Accessible dropdown select control built on Radix Select primitive with option grouping and viewport collision positioning.
// Radix — @radix-ui/react-select
import { Select } from "@shavin/ui";Default usage
Component Source
const OPTIONS = [
{ value: "a", label: "Option A" },
{ value: "b", label: "Option B" },
{ value: "c", label: "Option C" },
{ value: "d", label: "A longer option label" },
];
const [value, setValue] = useState("b");
<div className="w-56">
<Select
ariaLabel="Demo select"
value={value}
onChange={setValue}
options={OPTIONS}
/>
</div>Long Option List (with viewport scrolling)
Component Source
const LONG_OPTIONS = Array.from({ length: 12 }, (_, i) => ({
value: `opt-${i}`,
label: `Option ${i + 1}`,
}));
const [value, setValue] = useState("opt-3");
<div className="w-56">
<Select ariaLabel="Long list" value={value} onChange={setValue} options={LONG_OPTIONS} />
</div>Select vs Dropdown
Select is a Radix custom listbox — fully styled options, type-ahead, and identical rendering everywhere. Reach for Dropdown instead when you want the native <select> (and its OS mobile picker) for a simple form. See the Dropdown page for the full comparison.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| value | string | — | Active selected option value (controlled). Omit and use `defaultValue` for uncontrolled. |
| defaultValue | string | — | Initial selected value when uncontrolled. |
| options* | (Option | OptionGroup)[] | — | Flat options list or grouped option list. |
| onChange | (v: string) => void | — | Callback fired when user selects an option. |
| onValueChange | (v: string) => void | — | Alias of `onChange` (Radix naming). |
| onItemHighlight | (v: string | null) => void | — | Optional callback fired when an item is hovered/focused for live preview. Passed null on mouseleave/close. |
| ariaLabel | string | — | Accessible ARIA label string. |
| placeholder | string | — | Placeholder text when value is unselected. |
| className | string | — | Optional custom CSS class name for the trigger. |
| contentClassName | string | — | Optional custom CSS class name for the portaled dropdown content. |
| contentStyle | React.CSSProperties | — | Optional custom inline style for the portaled dropdown content. |
| size | "sm" | "md" | "lg" | — | Select trigger size. Heights match Button, TextField and Combobox: sm 32px, md 40px, lg 48px. |
| disabled | boolean | — | Whether the control is disabled. |
* required