The Select component provides a comprehensive dropdown selection interface with support for single and multiple selection, autocomplete, and custom styling.
Basic usage
import { Select } from '@raystack/apsara';
function App() {
return (
<Select>
<Select.Trigger>
<Select.Value placeholder="Select an option" />
</Select.Trigger>
<Select.Content>
<Select.Item value="option1">Option 1</Select.Item>
<Select.Item value="option2">Option 2</Select.Item>
<Select.Item value="option3">Option 3</Select.Item>
</Select.Content>
</Select>
);
}
Select (Root)
The controlled value of the select. Use string for single selection, string array for multiple selection.
onValueChange
(value: string | string[]) => void
Callback fired when the selected value changes.
The default value for uncontrolled usage.
Controls the open state of the select dropdown.
The default open state for uncontrolled usage.
Callback fired when the open state changes.
Whether multiple selections are allowed.
Enables autocomplete/search functionality.
autocompleteMode
'auto' | 'manual'
default:"'auto'"
The autocomplete filtering mode. ‘auto’ filters automatically, ‘manual’ requires custom filtering logic.
Controlled search value for autocomplete mode.
Callback fired when the search value changes.
Default search value for uncontrolled autocomplete.
Select.Trigger
size
'small' | 'medium'
default:"'medium'"
The size of the select trigger.
variant
'outline' | 'text'
default:"'outline'"
The visual variant of the trigger.
Props to customize the dropdown chevron icon.
Additional CSS classes to apply to the trigger.
Select.Item
The value of the select item.
Whether the item is disabled.
Single selection
function SingleSelect() {
const [value, setValue] = useState('');
return (
<Select value={value} onValueChange={setValue}>
<Select.Trigger>
<Select.Value placeholder="Choose a fruit" />
</Select.Trigger>
<Select.Content>
<Select.Item value="apple">Apple</Select.Item>
<Select.Item value="banana">Banana</Select.Item>
<Select.Item value="orange">Orange</Select.Item>
</Select.Content>
</Select>
);
}
Multiple selection
function MultiSelect() {
const [values, setValues] = useState([]);
return (
<Select multiple value={values} onValueChange={setValues}>
<Select.Trigger>
<Select.Value placeholder="Choose fruits" />
</Select.Trigger>
<Select.Content>
<Select.Item value="apple">Apple</Select.Item>
<Select.Item value="banana">Banana</Select.Item>
<Select.Item value="orange">Orange</Select.Item>
<Select.Item value="grape">Grape</Select.Item>
</Select.Content>
</Select>
);
}
With groups and labels
<Select>
<Select.Trigger>
<Select.Value placeholder="Select a food" />
</Select.Trigger>
<Select.Content>
<Select.Group>
<Select.Label>Fruits</Select.Label>
<Select.Item value="apple">Apple</Select.Item>
<Select.Item value="banana">Banana</Select.Item>
</Select.Group>
<Select.Separator />
<Select.Group>
<Select.Label>Vegetables</Select.Label>
<Select.Item value="carrot">Carrot</Select.Item>
<Select.Item value="potato">Potato</Select.Item>
</Select.Group>
</Select.Content>
</Select>
With autocomplete
<Select autocomplete>
<Select.Trigger>
<Select.Value placeholder="Search and select" />
</Select.Trigger>
<Select.Content>
<Select.Item value="react">React</Select.Item>
<Select.Item value="vue">Vue</Select.Item>
<Select.Item value="angular">Angular</Select.Item>
<Select.Item value="svelte">Svelte</Select.Item>
</Select.Content>
</Select>
Size variants
<Select>
<Select.Trigger size="small">
<Select.Value placeholder="Small select" />
</Select.Trigger>
<Select.Content>
<Select.Item value="1">Option 1</Select.Item>
</Select.Content>
</Select>
<Select>
<Select.Trigger size="medium">
<Select.Value placeholder="Medium select" />
</Select.Trigger>
<Select.Content>
<Select.Item value="1">Option 1</Select.Item>
</Select.Content>
</Select>
Trigger variants
<Select>
<Select.Trigger variant="outline">
<Select.Value placeholder="Outline variant" />
</Select.Trigger>
<Select.Content>
<Select.Item value="1">Option 1</Select.Item>
</Select.Content>
</Select>
<Select>
<Select.Trigger variant="text">
<Select.Value placeholder="Text variant" />
</Select.Trigger>
<Select.Content>
<Select.Item value="1">Option 1</Select.Item>
</Select.Content>
</Select>
With scroll buttons
<Select>
<Select.Trigger>
<Select.Value placeholder="Long list" />
</Select.Trigger>
<Select.Content>
<Select.ScrollUpButton />
<Select.Viewport>
{Array.from({ length: 50 }).map((_, i) => (
<Select.Item key={i} value={`item-${i}`}>
Item {i + 1}
</Select.Item>
))}
</Select.Viewport>
<Select.ScrollDownButton />
</Select.Content>
</Select>
Accessibility
- The Select component is built on Radix UI Select primitive with full keyboard navigation support.
- Supports arrow keys for navigation, Enter/Space for selection, and Escape to close.
- Proper ARIA attributes including
aria-label and aria-haspopup are automatically applied.
- In autocomplete mode, the component uses
aria-haspopup="dialog" for better screen reader support.
- Multiple selection state is indicated with
data-multiselectable attribute.