function App() {
const [value, setValue] = useState<string | null>("Apple");
return (
<Combobox value={value} onValueChange={(v) => setValue(v as any)} items={fruits}>
<Combobox.TriggerInput placeholder="Please select" />
<Combobox.Content>
<Combobox.Empty />
<Combobox.List>
{(item: string) => (
<Combobox.Item key={item} value={item}>
{item}
</Combobox.Item>
)}
</Combobox.List>
</Combobox.Content>
</Combobox>
);
}
const fruits = [
"Apple",
"Orange",
"Banana",
"Grape",
"Strawberry",
"Blueberry",
"Cherry",
"Watermelon",
"Peach",
"Pear",
]; Installation
Barrel
import { Combobox } from "@cloudflare/kumo"; Granular
import { Combobox } from "@cloudflare/kumo/components/combobox"; Searchable Item (Inside)
A searchable select component inside popup that allows users to filter and select.
function App() {
const [value, setValue] = useState<Language | null>(languages[0]);
return (
<Combobox
value={value}
onValueChange={(v) => setValue(v)}
items={languages}
>
<Combobox.TriggerValue className="w-[200px]" />
<Combobox.Content>
<Combobox.Input /> // Add this to make item searchable
<Combobox.Empty />
<Combobox.List>
{(item: Language) => (
<Combobox.Item key={item.value} value={item}>
{item.emoji} {item.label}
</Combobox.Item>
)}
</Combobox.List>
</Combobox.Content>
</Combobox>
);
}
interface Language {
value: string;
label: string;
emoji: string;
}
const languages: Language[] = [
{ value: "en", label: "English", emoji: "🇬🇧" },
{ value: "fr", label: "French", emoji: "🇫🇷" },
{ value: "de", label: "German", emoji: "🇩🇪" },
{ value: "es", label: "Spanish", emoji: "🇪🇸" },
{ value: "it", label: "Italian", emoji: "🇮🇹" },
{ value: "pt", label: "Portuguese", emoji: "🇵🇹" },
]; Grouped
Group items into categories using the Group and GroupLabel components.
function App() {
const [value, setValue] = useState<string | null>("singapore");
return (
<Combobox value={value} onValueChange={(v) => setValue(v as any)} items={server}>
<Combobox.TriggerInput className="w-[200px]" placeholder="Select server" />
<Combobox.Content>
<Combobox.Empty />
<Combobox.List>
{(group: ServerLocationGroup) => (
<Combobox.Group key={group.value} items={group.items}>
<Combobox.GroupLabel>{group.value}</Combobox.GroupLabel>
<Combobox.Collection>
{(item: ServerLocation) => {
return (
<Combobox.Item key={item.value} value={item}>
{item.label}
</Combobox.Item>
);
}}
</Combobox.Collection>
</Combobox.Group>
)}
</Combobox.List>
</Combobox.Content>
</Combobox>
)
}
const server = [
{
value: "Asia",
items: [
{ label: "Japan", value: "japan" },
{ label: "China", value: "china" },
{ label: "Singapore", value: "singapore" },
],
},
{
value: "Europe",
items: [
{ label: "Germany", value: "germany" },
{ label: "France", value: "france" },
{ label: "Italy", value: "italy" },
],
},
];
interface ServerLocation {
label: string;
value: string;
}
interface ServerLocationGroup {
value: string;
items: ServerLocation[];
} Multiple
Allow users to select multiple options from the list.
<Combobox
value={value}
onValueChange={setValue}
items={bots}
isItemEqualToValue={(bot, selected) => bot.value === selected.value}
multiple
>
<Combobox.TriggerMultipleWithInput
className="w-[400px]"
placeholder="Select bots"
renderItem={(selected) => (
<Combobox.Chip key={selected.value}>
{selected.label}
</Combobox.Chip>
)}
inputSide="right"
/>
<Combobox.Content>
<Combobox.Empty />
<Combobox.List>
{(item) => (
<Combobox.Item key={item.value} value={item}>
<Text>{item.label}</Text>
<Text variant="secondary">{item.author}</Text>
</Combobox.Item>
)}
</Combobox.List>
</Combobox.Content>
</Combobox> With Field
Add label and description using the built-in Field wrapper.
Select your preferred database
<Combobox
items={items}
value={value}
onValueChange={setValue}
label="Database"
description="Select your preferred database"
>
<Combobox.TriggerInput placeholder="Select database" />
<Combobox.Content>
<Combobox.Empty />
<Combobox.List>
{(item) => (
<Combobox.Item key={item.value} value={item}>
{item.label}
</Combobox.Item>
)}
</Combobox.List>
</Combobox.Content>
</Combobox> Error State
Display validation errors with the error prop.
<Combobox
items={items}
value={value}
onValueChange={setValue}
label="Database"
error={{ message: "Please select a database", match: true }}
>
<Combobox.TriggerInput placeholder="Select database" />
<Combobox.Content>
<Combobox.Empty />
<Combobox.List>
{(item) => (
<Combobox.Item key={item.value} value={item}>
{item.label}
</Combobox.Item>
)}
</Combobox.List>
</Combobox.Content>
</Combobox> Customizing Dropdown Height
By default, Combobox.Content has a max height of 24rem (384px) or the available viewport space, whichever is smaller. The dropdown scrolls automatically when content exceeds this height.
To customize the max height, pass a className to Combobox.Content:
// Shorter dropdown (200px)
<Combobox.Content className="max-h-[200px]">
// Taller dropdown (500px)
<Combobox.Content className="max-h-[500px]">
// Use Tailwind presets
<Combobox.Content className="max-h-64"> // 256px
<Combobox.Content className="max-h-96"> // 384px (same as default) API Reference
Combobox
Root component for the searchable select.
| Prop | Type | Default | Description |
|---|---|---|---|
| inputSide | "right" | "top" | "right" | Position of the text input relative to chips in multi-select mode. - `"right"` — Input inline to the right of chips - `"top"` — Input above chips |
| items* | T[] | - | Array of items to display in the dropdown |
| value | T | T[] | - | Currently selected value(s) |
| children | ReactNode | - | Combobox content (trigger, content, items) |
| className | string | - | Additional CSS classes |
| label | ReactNode | - | Label content for the combobox (enables Field wrapper) - can be a string or any React node |
| required | boolean | - | Whether the combobox is required |
| labelTooltip | ReactNode | - | Tooltip content to display next to the label via an info icon |
| description | ReactNode | - | Helper text displayed below the combobox |
| error | string | object | - | Error message or validation error object |
| onValueChange | (value: T | T[]) => void | - | Callback when selection changes |
| multiple | boolean | - | Allow multiple selections |
| isItemEqualToValue | (item: T, value: T) => boolean | - | Custom equality function for comparing items |
Combobox.Content
Dropdown container for the list.
| Prop | Type | Default |
|---|---|---|
| className | string | - |
| align | ComboboxBase.Positioner.Props["align"] | - |
| alignOffset | ComboboxBase.Positioner.Props["alignOffset"] | - |
| side | ComboboxBase.Positioner.Props["side"] | - |
| sideOffset | ComboboxBase.Positioner.Props["sideOffset"] | - |
Combobox.Item
Individual selectable option.
| Prop | Type | Default |
|---|
No component-specific props. Accepts standard HTML attributes.
Additional Sub-components
Combobox.TriggerInput- Single-select input triggerCombobox.TriggerValue- Button trigger showing selected valueCombobox.TriggerMultipleWithInput- Multi-select with chipsCombobox.Input- Search input inside dropdownCombobox.List- List container with render propCombobox.Group- Group container for categorized itemsCombobox.GroupLabel- Header label for a groupCombobox.Collection- Items container within a groupCombobox.Chip- Selected item chipCombobox.Empty- Empty state message