Select
The Select component provides you with dropdown menus and choices.
Import
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@nostromo/ui-core'
// or
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@nostromo/ui-core/select'Usage
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@nostromo/ui-core'
export default function Example() {
const [value, setValue] = React.useState('')
return (
<Select value={value} onValueChange={setValue}>
<SelectTrigger>
<SelectValue placeholder="Select an option" />
</SelectTrigger>
<SelectContent>
<SelectItem value="option1">Option 1</SelectItem>
<SelectItem value="option2">Option 2</SelectItem>
</SelectContent>
</Select>
)
}Live Examples
Live Example
View Code
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@nostromo/ui-core'
export default function SelectExample() {
return (
<Select>
<SelectTrigger>
<SelectValue placeholder="Select an option" />
</SelectTrigger>
<SelectContent>
<SelectItem value="option1">Option 1</SelectItem>...
With Label
Live Example
View Code
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Label } from '@nostromo/ui-core'
export default function SelectWithLabel() {
return (
<div className="space-y-2">
<Label htmlFor="country">Country</Label>
<Select>
<SelectTrigger id="country">
<SelectValue placeholder="Select country" />
</SelectTrigger>...
Accessibility
Keyboard Navigation
- Arrow Keys: Navigate through options
- Enter/Space: Selects the focused option
- Escape: Closes the dropdown
- Tab: Moves focus to the next element
- Home/End: Moves to first/last option
ARIA Attributes
- role="combobox": Identifies the select as a combobox
- aria-expanded: Indicates if the dropdown is open
- aria-haspopup: Indicates the presence of a popup
- aria-activedescendant: References the currently focused option
- aria-labelledby: References the label element
Focus Management
- Focus trap: Prevents focus from escaping the dropdown
- Focus restoration: Returns focus to the trigger when closed
- Focus indicators: Clear visual focus states
Screen Reader Support
- Option announcements: Selected options are announced
- State changes: Open/close states are announced
- Navigation hints: Keyboard navigation is described
Examples
// Accessible select with proper labeling
<Select>
<SelectTrigger aria-labelledby="country-label">
<SelectValue placeholder="Select a country" />
</SelectTrigger>
<SelectContent>
<SelectItem value="us" aria-describedby="us-description">
United States
</SelectItem>
<SelectItem value="ca" aria-describedby="ca-description">
Canada
</SelectItem>
</SelectContent>
</Select>
<label id="country-label" className="sr-only">
Select your country
</label>Best Practices
Do ✅
- Always provide a
SelectValuewith placeholder - Use
Labelcomponent for form integration - Provide unique
valueprops for eachSelectItem - Use controlled mode (
value+onValueChange) for form libraries - Handle disabled states appropriately
Don't ❌
- Don't forget to handle form submission with
nameprop - Don't use Select for navigation (use links instead)
- Don't create too many options (consider search/filtering)
- Don't forget keyboard navigation support
Props
Select
| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
value | string | undefined | No | Selected value (controlled) |
defaultValue | string | undefined | No | Default selected value (uncontrolled) |
onValueChange | (value: string) => void | undefined | No | Callback when value changes |
disabled | boolean | false | No | Whether the select is disabled |
name | string | undefined | No | Name for form submission |
required | boolean | false | No | Whether the select is required |
children | React.ReactNode | undefined | No | Select content (SelectTrigger, SelectContent) |
SelectTrigger
| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
variant | "default" | "outline" | "ghost" | "default" | No | Visual variant |
size | "sm" | "default" | "lg" | "default" | No | Size of the trigger |
className | string | undefined | No | Additional CSS classes |
children | React.ReactNode | undefined | No | Trigger content (usually SelectValue) |
asChild | boolean | false | No | Render as child element |
SelectValue
| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
placeholder | string | undefined | No | Placeholder text when no value selected |
className | string | undefined | No | Additional CSS classes |
SelectContent
| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
position | "popper" | "item-aligned" | "popper" | No | Positioning strategy |
side | "top" | "right" | "bottom" | "left" | "bottom" | No | Side of trigger to align to |
align | "start" | "center" | "end" | "start" | No | Alignment relative to trigger |
className | string | undefined | No | Additional CSS classes |
children | React.ReactNode | undefined | No | Select items |
SelectItem
| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
value | string | - | Yes | Item value (must be unique) |
disabled | boolean | false | No | Whether the item is disabled |
className | string | undefined | No | Additional CSS classes |
children | React.ReactNode | undefined | No | Item content |