Select
Use the select component to let users choose an option from a long list. For shorter lists (fewer than 7 options), consider using radios instead.
Default Select (Radix UI)
Built with Radix UI primitives for full accessibility and consistent styling across all browsers. The dropdown is fully customisable with CSS.
import * as Select from '@radix-ui/react-select';
import { ChevronDown, Check } from 'lucide-react';
<div className="form-group">
<label className="form-label">Sort by</label>
<Select.Root>
<Select.Trigger className="radix-select-trigger">
<Select.Value placeholder="Select an option" />
<Select.Icon className="radix-select-icon">
<ChevronDown size={20} />
</Select.Icon>
</Select.Trigger>
<Select.Portal>
<Select.Content className="radix-select-content" position="popper" sideOffset={4}>
<Select.Viewport className="radix-select-viewport">
<Select.Item className="radix-select-item" value="published">
<Select.ItemText>Recently published</Select.ItemText>
<Select.ItemIndicator className="radix-select-item-indicator">
<Check size={16} />
</Select.ItemIndicator>
</Select.Item>
...
</Select.Viewport>
</Select.Content>
</Select.Portal>
</Select.Root>
</div>With Hint Text
Select the county where you currently reside.
<div className="form-group">
<label className="form-label">Where do you live?</label>
<Select.Root>
<Select.Trigger className="radix-select-trigger">
<Select.Value placeholder="Select a county" />
...
</Select.Trigger>
...
</Select.Root>
<span className="form-hint">Select the county where you currently reside.</span>
</div>With Option Groups
Use Select.Group and Select.Label to group related options.
<Select.Viewport className="radix-select-viewport">
<Select.Group>
<Select.Label className="radix-select-label">Government</Select.Label>
<Select.Item className="radix-select-item" value="cabinet">
<Select.ItemText>Cabinet Office</Select.ItemText>
...
</Select.Item>
...
</Select.Group>
<Select.Separator className="radix-select-separator" />
<Select.Group>
<Select.Label className="radix-select-label">Services</Select.Label>
...
</Select.Group>
</Select.Viewport>Pre-selected Value
Use defaultValue to set an initial selection.
<Select.Root defaultValue="kah">
<Select.Trigger className="radix-select-trigger">
<Select.Value />
...
</Select.Trigger>
...
</Select.Root>Error State
<div className="form-group form-group-error">
<label className="form-label">Where do you live?</label>
<span className="form-error-message">Select a county</span>
<Select.Root>
<Select.Trigger className="radix-select-trigger">
...
</Select.Trigger>
...
</Select.Root>
</div>Disabled State
<Select.Root disabled>
<Select.Trigger className="radix-select-trigger">
<Select.Value placeholder="Cannot be changed" />
...
</Select.Trigger>
...
</Select.Root>Controlled Select
Use controlled components when you need to manage state in React.
const [value, setValue] = useState('');
<Select.Root value={value} onValueChange={setValue}>
<Select.Trigger className="radix-select-trigger">
<Select.Value placeholder="Select an option" />
...
</Select.Trigger>
...
</Select.Root>When to Use Select
Use select when:
- There are more than 6-7 options
- The list of options is familiar to users (e.g., countries, months)
- Screen space is limited
Consider alternatives when:
- There are fewer than 7 options — use radios
- Users can select multiple options — use checkboxes
- Users might need to enter a value not in the list — use text input with autocomplete
Accessibility
- Built with Radix UI primitives for full WAI-ARIA compliance
- Always include a label associated with the select trigger
- Use
placeholderfor the initial prompt - Full keyboard navigation: Arrow keys to navigate, Enter to select, Escape to close
- Clear focus states with yellow outline
- Screen reader announces selected value and available options
CSS Classes
/* Radix select trigger (visible button) */
.radix-select-trigger { }
.radix-select-icon { }
/* Dropdown content */
.radix-select-content { }
.radix-select-viewport { }
/* Items */
.radix-select-item { }
.radix-select-item-indicator { }
/* Groups */
.radix-select-label { }
.radix-select-separator { }
/* Error state */
.form-group-error { }
.form-error-message { }Installation
npm install @radix-ui/react-select lucide-react