Select

Select displays a collapsible list of options and allows a user to select one of them.

Country
<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/select

Usage

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

Model
Project

Async Loading

API Reference

Select

A select displays a collapsible list of options and allows a user to select one of them.

PropType
boolean
ReactNode | function
boolean
string
M
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.

PropType
ReactNode | function

SelectContent

Contains the list of options, displayed in a popover when the select is open.

PropType
Placement
boolean
DragAndDropHooks<NoInfer<T>>
"grid" | "stack"
Orientation
ReactNode | function
Iterable<T>
function
readonly any[]
SelectionMode
SelectionBehavior
Iterable<Key> | "all"
Iterable<Key> | "all"
function
Iterable<Key>
boolean
boolean
boolean
boolean
"clearSelection" | "none"

Last updated on 7/7/2026