Components
Combobox
A searchable select for long option lists.
Default
<Label htmlFor="typeface-trigger">Editor typeface</Label>
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger render={<Button id="typeface-trigger" variant="outline" role="combobox" className="w-56 justify-between" />}>
buena mono Regular
<ChevronsUpDown className="opacity-50" />
</PopoverTrigger>
<PopoverContent className="w-56 p-0">
<Command>
<CommandInput placeholder="Search styles..." />
<CommandList>
<CommandGroup heading="buena mono">…</CommandGroup>
<CommandGroup heading="buena sans">…</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover> States
Disabled
Invalid
Pick a style before publishing.
Clearable
{/* Disabled */}
<Button variant="outline" role="combobox" disabled className="w-52 justify-between">
buena mono Regular
<ChevronsUpDown className="opacity-50" />
</Button>
{/* Invalid */}
<Button variant="outline" role="combobox" aria-invalid="true" className="w-52 justify-between border-error">
Select a style
</Button>
<p className="text-xs text-error">Pick a style before publishing.</p>
{/* Clearable */}
{value && (
<button aria-label="Clear selection" onClick={() => setValue("")}>
<X className="size-4" />
</button>
)} With prefix icons & custom items
<CommandItem value={style.value} onSelect={setValue}>
<Hash className="size-4 text-text-tertiary" />
<span className="flex flex-col">
<span>{style.label}</span>
<span className="text-xs text-text-tertiary">{style.meta}</span>
</span>
<Check className={cn("ml-auto", value === style.value ? "opacity-100" : "opacity-0")} />
</CommandItem> Multiple with chips
const [values, setValues] = useState(["mono-regular"]);
<PopoverTrigger render={<Button role="combobox" className="h-auto min-h-9" />}>
{values.map((v) => (
<span className="rounded-md border px-1.5 py-0.5 text-xs">
{label(v)}
<button onClick={() => remove(v)}><X className="size-3" /></button>
</span>
))}
</PopoverTrigger>
{/* items toggle in/out of the array instead of closing */}
<CommandItem onSelect={() => toggle(style.value)}>
{style.label}
<Check className={values.includes(style.value) ? "opacity-100" : "opacity-0"} />
</CommandItem> Multiple keeps selections in an array so
the list stays open as you add styles, and each pick renders as a removable
chip in the trigger (upstream's
ComboboxChips / ComboboxChip).
This popover-backed combobox is the shadcn Popup variant, and its
CommandInput is the Input Group (search field + list).
cmdk auto-highlights the first match as you type (Auto
Highlight). Leave value unmanaged for the Uncontrolled
pattern, resize the trigger with the size prop (Sizes), and
drop the same <Command> inside
<DialogContent> to use it inside a Modal.
Markdown for agents: /design/combobox.md · spec: /design.md