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>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>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>)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>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>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>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>)