<Select className="w-52">
<Label>Country</Label>
<SelectTrigger />
<SelectContent>
<SelectItem id="us">United States</SelectItem>
<SelectItem id="uk">United Kingdom</SelectItem>
<SelectItem id="fr">France</SelectItem>
<SelectItem id="de">Germany</SelectItem>
<SelectItem id="jp">Japan</SelectItem>
</SelectContent>
</Select>Installation
npx shadcn@latest add @dotui/selectUsage
Use Select to allow users to choose a single option from a collapsible list of options when space is limited.
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
} from '@/components/ui/select'<Select>
<SelectTrigger />
<SelectContent>
<SelectItem>Option 1</SelectItem>
<SelectItem>Option 2</SelectItem>
</SelectContent>
</Select>Anatomy
import {
Select,
SelectTrigger,
SelectContent,
SelectItem,
SelectSection,
SelectSectionHeader,
} from '@/components/ui/select'<Select>
<SelectTrigger />
<SelectContent>
<SelectSection>
<SelectSectionHeader />
<SelectItem />
</SelectSection>
</SelectContent>
</Select>Select holds the state, SelectTrigger opens the popover and shows the current value, SelectContent is the option list, and SelectItem is an option. SelectSection with SelectSectionHeader groups items.
Value
Select selects by key: each SelectItem has an id, and the value is that id. Use defaultSelectedKey for uncontrolled state, or value with onChange to control it.
<Select value={provider} onChange={setProvider}>
<SelectTrigger />
<SelectContent>
<SelectItem id="perplexity">Perplexity</SelectItem>
<SelectItem id="replicate">Replicate</SelectItem>
</SelectContent>
</Select>Selection
Selection is single by default. Pass the M type param as 'multiple' (SelectProps<T, 'multiple'>) and set selectionMode="multiple" on SelectContent to allow selecting several options.
Content
Render items statically as children, or dynamically by passing items to SelectContent with a render function.
<SelectContent items={providers}>
{(item) => <SelectItem id={item.id}>{item.name}</SelectItem>}
</SelectContent>Async loading
Feed a useAsyncList result into SelectContent via items, and wire isLoading and onLoadMore for infinite scrolling. See the Async Loading example.
Validation
Add a Label and a FieldError inside Select, and set isRequired or isInvalid to surface validation.
import { FieldError, Label } from '@/components/ui/field'
;<Select isRequired>
<Label>Provider</Label>
<SelectTrigger />
<SelectContent>
<SelectItem>Perplexity</SelectItem>
</SelectContent>
<FieldError />
</Select>Composition
SelectTrigger wraps Button, SelectContent wraps Popover + ListBox, and SelectItem re-exports ListBoxItem. For full control, drop the wrappers and compose the primitives directly.
import { ChevronDownIcon } from 'lucide-react'
import { Button } from '@/components/ui/button'
import {
ListBox,
ListBoxItem,
ListBoxSection,
ListBoxSectionHeader,
} from '@/components/ui/list-box'
import { Popover } from '@/components/ui/popover'
import { Select, SelectValue } from '@/components/ui/select'<Select>
<Button variant="outline">
<SelectValue placeholder="Select provider" />
<ChevronDownIcon />
</Button>
<Popover placement="bottom start">
<ListBox>
<ListBoxSection>
<ListBoxSectionHeader>AI Providers</ListBoxSectionHeader>
<ListBoxItem id="openai">OpenAI</ListBoxItem>
<ListBoxItem id="anthropic">Anthropic</ListBoxItem>
</ListBoxSection>
</ListBox>
</Popover>
</Select>Examples
Basic
Sectioned List
With Links
Async Loading
API Reference
Select
A select displays a collapsible list of options and allows a user to select one of them.
| Prop | Type | Default | |
|---|---|---|---|
boolean | — | ||
ReactNode | function | — | ||
boolean | — | ||
string | 'Select an item' (localized) | ||
M | 'single' | ||
Key | null | — | ||
Key | null | — | ||
function | — | ||
Iterable<Key> | — | ||
ValueType<M> | — | ||
ValueType<M> | — | ||
function | — | ||
SelectValue
SelectValue renders the current value of a Select, or a placeholder if no value is selected. It is usually placed within the button element.
| Prop | Type | Default | |
|---|---|---|---|
ReactNode | function | — | ||
SelectContent
Contains the list of options, displayed in a popover when the select is open.
| Prop | Type | Default | |
|---|---|---|---|
Placement | 'bottom' | ||
boolean | — | ||
DragAndDropHooks<NoInfer<T>> | — | ||
"grid" | "stack" | 'stack' | ||
Orientation | 'vertical' | ||
ReactNode | function | — | ||
Iterable<T> | — | ||
function | — | ||
readonly any[] | — | ||
SelectionMode | — | ||
SelectionBehavior | 'toggle' | ||
Iterable<Key> | "all" | — | ||
Iterable<Key> | "all" | — | ||
function | — | ||
Iterable<Key> | — | ||
boolean | — | ||
boolean | — | ||
boolean | — | ||
boolean | — | ||
"clearSelection" | "none" | 'clearSelection' | ||
Last updated on 7/7/2026