shadcn.io is an independent project built on shadcn/ui
Until a currency is picked, the button has a destructive border and Please select a currency shows under it. USD, EUR, GBP, JPY, and CAD are the list. Picking one clears the border and the message.
Use it in a form where the combobox cannot be left empty. A whole form of rules belongs on a Field, not on this one message. In React, Base UI does not require a currency. The demo adds the error.
Installation
Anatomy

Usage
<div className="flex flex-col gap-2">
<Combobox items={currencies} onValueChange={setValue} value={value}>
<ComboboxTrigger
aria-invalid={Boolean(error)}
render={
<Button
className={cn(
"w-[200px] justify-between",
error && "border-destructive"
)}
variant="outline"
/>
}
>
<ComboboxValue placeholder="Select currency..." />
</ComboboxTrigger>
<ComboboxContent>
<ComboboxInput placeholder="Search currency..." showTrigger={false} />
<ComboboxEmpty>No currency found.</ComboboxEmpty>
<ComboboxList>
{(item: string) => (
<ComboboxItem key={item} value={item}>
{item}
</ComboboxItem>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>
{error ? <p className="text-destructive text-xs">{error}</p> : null}
</div>FAQ
When does the error show?
Whenever no currency is selected. The message is worked out from the value on every render, so there's no separate error state to keep in sync.
How does the button show the error?
It gets border-destructive while the value is empty, and the message is a text-destructive text-xs paragraph below.
The trigger also gets aria-invalid.
How do I clear the message?
Pick any currency. The value is no longer empty, so the border and the message go away.
Which currencies are listed?
USD, EUR, GBP, JPY and CAD. The search box says Search currency..., and No currency found. shows when nothing matches.
API Reference
Combobox
Sets items={currencies}, onValueChange={setValue}, value={value}, placeholder="Select currency...", placeholder="Search currency..." and showTrigger={false}. The rest is on the Combobox page.
Button
Sets variant="outline". The rest is on the Button page.





