Component

A dropdown for choosing a single value from a list. Supports grouping, portal rendering, and controlled/uncontrolled modes.

View component changelog
preview
React
"use client" import Select from "@radui/ui/Select" const SelectExample = () => { return ( <div className="w-[240px]"> <Select.Root> <Select.Trigger aria-label="Fruit"> <span>Select a fruit...</span> </Select.Trigger> <Select.Portal> <Select.Content> <Select.Group> <Select.Item value="apple"><Select.Indicator />Apple</Select.Item> <Select.Item value="banana"><Select.Indicator />Banana</Select.Item> <Select.Item value="orange"><Select.Indicator />Orange</Select.Item> <Select.Item value="grape"><Select.Indicator />Grape</Select.Item> </Select.Group> </Select.Content> </Select.Portal> </Select.Root> </div> ) } export default SelectExample

Use a controlled value and keep each option's value and label stable when a Select has hundreds of options. This incremental pattern keeps keyboard navigation intact by mounting more rows before focus reaches the boundary.

React
"use client" import * as React from "react" import { flushSync } from "react-dom" import Select from "@radui/ui/Select" const OPTIONS = Array.from({ length: 1000 }, (_, index) => ({ value: `item-${index + 1}`, label: `Item ${index + 1}` })) const PAGE_SIZE = 40 const LargeListSelectExample = () => { const [visibleCount, setVisibleCount] = React.useState(PAGE_SIZE) const [value, setValue] = React.useState("") const selectedLabel = OPTIONS.find((option) => option.value === value)?.label const visibleOptions = OPTIONS.slice(0, visibleCount) const canShowMore = visibleCount < OPTIONS.length const showMore = React.useCallback(() => { setVisibleCount((current) => Math.min(current + PAGE_SIZE, OPTIONS.length)) }, []) const showMoreBeforeNavigation = React.useCallback(() => { flushSync(() => { setVisibleCount((current) => Math.min(current + PAGE_SIZE, OPTIONS.length)) }) }, []) return ( <Select.Root value={value} onValueChange={setValue}> <Select.Trigger> <span>{selectedLabel || "Select an item..."}</span> </Select.Trigger> <Select.Portal> <Select.Content style={{ "--rad-select-content-height": "256px" } as React.CSSProperties} onScroll={(event) => { const target = event.currentTarget const remaining = target.scrollHeight - target.scrollTop - target.clientHeight if (remaining < 48 && canShowMore) { showMore() } }} onKeyDownCapture={(event) => { if (!canShowMore || event.key !== "ArrowDown") { return } const activeValue = document.activeElement?.getAttribute("data-value") const lastVisibleValue = visibleOptions[visibleOptions.length - 1]?.value if (activeValue === lastVisibleValue) { showMoreBeforeNavigation() } }} > <Select.Group> {visibleOptions.map((option) => ( <Select.Item key={option.value} value={option.value} label={option.label} > <Select.Indicator /> {option.label} </Select.Item> ))} </Select.Group> </Select.Content> </Select.Portal> </Select.Root> ) } export default LargeListSelectExample

Import all parts of the component and piece them together

React
import Select from "@radui/ui/Select" export default () => { return ( <Select.Root> <Select.Trigger> <Select.Indicator /> </Select.Trigger> <Select.Portal> <Select.Content> <Select.Group> <Select.Item value="" /> </Select.Group> </Select.Content> </Select.Portal> </Select.Root> ) }

The root Select component.

PropTypeDefault
value
string
--
defaultValue
string
--
open
boolean
--
disabled
boolean
false
onValueChange
function
--
onOpenChange
function
--

A single selectable option.

PropTypeDefault
value*
string
--
disabled
boolean
false
className
string
""
ShortcutDescription
Enter

Opens the select when closed, or selects the highlighted item when the listbox is open.

Space

Opens the select when closed, or selects the highlighted item when the listbox is open.

ArrowDown

Moves focus to the next item in the listbox.

ArrowUp

Moves focus to the previous item in the listbox.

Escape

Closes the listbox without changing the current value.

ReferenceWhat Rad UI follows

Uses select-only combobox semantics for a collapsed trigger with an associated single-selection popup.

Follows listbox option semantics for the popup items and highlighted selection state.