Select

Selects let users choose a single option from a list anchored to a trigger.

The Select component is a Base UI component.

<Select>
<SelectTrigger className="max-w-256">
<SelectValue placeholder="Select a font" />
</SelectTrigger>
<SelectContent>
<SelectItem value="sans">Sans-serif</SelectItem>
<SelectItem value="serif">Serif</SelectItem>
<SelectItem value="mono">Monospace</SelectItem>
</SelectContent>
</Select>

Groups

Use SelectGroup with a SelectGroupLabel to label related options, and SelectSeparator to divide sections.

<Select>
<SelectTrigger className="max-w-256">
<SelectValue placeholder="Select a font" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectGroupLabel>Proportional</SelectGroupLabel>
<SelectItem value="sans">Sans-serif</SelectItem>
<SelectItem value="serif">Serif</SelectItem>
</SelectGroup>
<SelectSeparator />
<SelectGroup>
<SelectGroupLabel>Fixed width</SelectGroupLabel>
<SelectItem value="mono">Monospace</SelectItem>
</SelectGroup>
</SelectContent>
</Select>

Icons

Options can include an icon before their label and a supporting description. Use the whole option object as the SelectItem value, and pass a render function to SelectValue so the trigger can render the selected option the same way. Provide itemToStringValue on Select to convert the object to a string for form submission, and set label on SelectItem for keyboard text navigation.

const MODELS = [
{
description: "Max",
icon: Claude.Color,
label: "Fable 5",
value: "fable-5",
},
{
description: "High Fast",
icon: Grok,
label: "Grok 4.5",
value: "grok-4.5",
},
{
description: "Medium",
icon: OpenAI,
label: "GPT-5.6 Sol",
value: "gpt-5.6-sol",
},
{
description: "Fast",
icon: Gemini.Color,
label: "Gemini 2.5 Pro",
value: "gemini-2.5-pro",
},
]
return (
<Select defaultValue={MODELS[0]} itemToStringValue={(item) => item.value}>
<SelectTrigger className="max-w-288">
<SelectValue placeholder="Select a model">
{(model) => (
<Row className="items-center">
{model.icon && <model.icon className="mr-8" size={18} />}
<span className="truncate">{model.label}</span>
{model.description && (
<span className="text-13 text-gray-9 font-400 ml-6 truncate">
{model.description}
</span>
)}
</Row>
)}
</SelectValue>
</SelectTrigger>
<SelectContent>
{MODELS.map((model) => (
<SelectItem key={model.value} label={model.label} value={model}>
<Row className="items-center">
{model.icon && <model.icon className="mr-8" size={18} />}
<span className="truncate">{model.label}</span>
{model.description && (
<span className="text-13 text-gray-9 font-400 ml-6 truncate">
{model.description}
</span>
)}
</Row>
</SelectItem>
))}
</SelectContent>
</Select>
)

Size

The SelectTrigger comes with 5 sizes: 32, 36, 40 (default), 44, and 48.

<Select>
<SelectTrigger size={32}>
<SelectValue placeholder="Size 32" />
</SelectTrigger>
<SelectContent>{/* ... */}</SelectContent>
</Select>
<Select>
<SelectTrigger size={36}>
<SelectValue placeholder="Size 36" />
</SelectTrigger>
<SelectContent>{/* ... */}</SelectContent>
</Select>
<Select>
<SelectTrigger size={40}>
<SelectValue placeholder="Size 40" />
</SelectTrigger>
<SelectContent>{/* ... */}</SelectContent>
</Select>
<Select>
<SelectTrigger size={44}>
<SelectValue placeholder="Size 44" />
</SelectTrigger>
<SelectContent>{/* ... */}</SelectContent>
</Select>
<Select>
<SelectTrigger size={48}>
<SelectValue placeholder="Size 48" />
</SelectTrigger>
<SelectContent>{/* ... */}</SelectContent>
</Select>

Rounded

Use the rounded prop to give the trigger fully rounded corners.

<Select>
<SelectTrigger className="max-w-256" rounded>
<SelectValue placeholder="Select a font" />
</SelectTrigger>
<SelectContent>
<SelectItem value="sans">Sans-serif</SelectItem>
<SelectItem value="serif">Serif</SelectItem>
<SelectItem value="mono">Monospace</SelectItem>
</SelectContent>
</Select>

Disabled

Use the disabled prop on SelectItem to prevent a single option from being selected, or the disabled prop on Select to disable the entire control.

<Select>
<SelectTrigger className="max-w-256">
<SelectValue placeholder="Select a font" />
</SelectTrigger>
<SelectContent>
<SelectItem value="sans">Sans-serif</SelectItem>
<SelectItem value="serif">Serif</SelectItem>
<SelectItem disabled value="cursive">
Cursive
</SelectItem>
</SelectContent>
</Select>
<Select disabled>
<SelectTrigger className="max-w-256">
<SelectValue placeholder="Select a font" />
</SelectTrigger>
</Select>

State

By default, Select is an uncontrolled component that manages its own state. Use the defaultValue prop to set the initially selected option.

<Select defaultValue="sans">
<SelectTrigger>
<SelectValue placeholder="Select a font" />
</SelectTrigger>
<SelectContent>
<SelectItem value="sans">Sans-serif</SelectItem>
<SelectItem value="serif">Serif</SelectItem>
</SelectContent>
</Select>

Use value and onValueChange props if you need to access or control the state.

const [font, setFont] = useState(null)
return (
<Select onValueChange={setFont} value={font}>
<SelectTrigger>
<SelectValue placeholder="Select a font" />
</SelectTrigger>
<SelectContent>
<SelectItem value="sans">Sans-serif</SelectItem>
<SelectItem value="serif">Serif</SelectItem>
</SelectContent>
</Select>
)