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
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)
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 |
|---|---|---|
| value* | string | — |
| options* | (Option | OptionGroup)[] | — |
| onChange* | (v: string) => void | — |
| onItemHighlight | (v: string | null) => void | — |
| ariaLabel | string | — |
| placeholder | string | — |
| className | string | — |
| contentClassName | string | — |
| contentStyle | React.CSSProperties | — |
| size | "sm" | "md" | — |
* required