The Bits UI primitive integration, keyboard-navigation tests, and prop documentation for Combobox were contributed by Teddy (@uhteddy).
Installation
Barrel
import { Combobox } from "kumo-svelte"; Granular
import { Combobox } from "kumo-svelte/components/combobox";Usage
<script lang="ts"> import { Combobox } from 'kumo-svelte'; const fruits = ['Apple', 'Banana', 'Cherry', 'Date', 'Elderberry']; let value = $state<string | null>(null);</script><Combobox bind:value items={fruits}> <Combobox.TriggerInput placeholder="Select a fruit" /> <Combobox.Content> <Combobox.Empty /> <Combobox.List> {#snippet children(item)} <Combobox.Item value={item}>{item}</Combobox.Item> {/snippet} </Combobox.List> </Combobox.Content></Combobox>Examples
Sizes
The Combobox supports four size variants that match the Input component: xs, sm, base (default), and lg.
Size also applies to TriggerValue (searchable inside variant):
Searchable Item (Inside)
A searchable select component inside popup that allows users to filter and select.
Searchable Select with Placeholder
Use TriggerValue with a placeholder prop to create a searchable Select-style field.
The placeholder is displayed until a value is selected.
Custom Trigger
Use Combobox.Trigger with a render prop to replace the default input-like trigger with your own element. Pair with Combobox.Value to display the selected value. Useful for account switchers, sidebar navigation, or anywhere the default chrome doesn't fit.
Grouped
Group items into categories using the Group and GroupLabel components.
Multiple
Allow users to select multiple options from the list.
With Field
Add label and description using the built-in Field wrapper.
Disabled
Pass the disabled prop to prevent interaction. Works with both TriggerInput and TriggerValue.
Disabled Items
Pass the disabled prop to an individual Combobox.Item to make it non-selectable. Disabled rows are rendered with a muted style and skipped during keyboard navigation selection.
Error State
Display validation errors with the error prop.
Filtering
Filtering is case- and accent-insensitive by default, powered by Intl.Collator under the hood. For string items, no custom filter is needed.
When filtering on a property of object items, use Combobox.useFilter() to
preserve the built-in accent-insensitive matching:
<script lang="ts"> import { Combobox } from "kumo-svelte"; const { contains } = Combobox.useFilter(); const languages = [ { value: "pt", label: "Portuguese", emoji: "🇵🇹" }, { value: "es", label: "Spanish", emoji: "🇪🇸" } ]; const filter = (item, query) => contains(item.label, query);</script><Combobox items={languages} {filter}> <!-- ... --></Combobox> To disable filtering entirely (for example, when results come from a server),
pass filter={null}:
<Combobox items={results} filter={null}> <!-- ... --></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 class to Combobox.Content:
// Shorter dropdown (200px)<Combobox.Content class="max-h-[200px]">// Taller dropdown (500px)<Combobox.Content class="max-h-[500px]">// Use Tailwind presets<Combobox.Content class="max-h-64"> // 256px<Combobox.Content class="max-h-96"> // 384px (same as default)API Reference
Combobox
Root component for the searchable select.
| Prop | Type | Default | Description |
|---|---|---|---|
| size | 'xs' | 'sm' | 'base' | 'lg' | "base" | Size preset. |
| items * | unknown[] | - | Array of items to display in the dropdown. |
| value | unknown | - | Controlled value. |
| children | Snippet | - | Child snippet rendered by the component. |
| class | string | - | Additional classes merged onto the root element. |
| label | string | Snippet | - | Visible label content. |
| required | boolean | - | Marks the field as required. |
| labelTooltip | string | Snippet | - | Optional help content for the label. |
| description | string | Snippet | - | Supporting description text. |
| error | FieldError | - | Validation error message or matcher. |
| onValueChange | (value: unknown) => void | - | Called when the value changes. |
| multiple | boolean | false | Enables multiple selection. |
| onOpenChange | (open: boolean) => void | - | Called when open state changes. |
| disabled | boolean | false | Prevents interaction with the field. |
| defaultValue | unknown | - | Initial value. |
| filter | ((item: ComboboxItem, query: string) => boolean) | null | - | Custom filter function. Set to null to disable filtering. |
| isItemEqualToValue | (item: unknown, value: unknown) => boolean | - | Custom value equality matcher function. |
Combobox.Content
Dropdown container for the list.
| Prop | Type | Default | Description |
|---|---|---|---|
| align | 'start' | 'center' | 'end' | "start" | Alignment of the popup relative to the trigger. |
| alignOffset | number | string | - | Offset along the alignment axis. |
| side | 'top' | 'right' | 'bottom' | 'left' | "bottom" | Side of the trigger where the popup is placed. |
| sideOffset | number | string | 4 | Offset between the popup and the trigger. |
Combobox.Item
Individual selectable option.
| Prop | Type | Default | Description |
|---|---|---|---|
| value * | ComboboxItem | - | Controlled value. |
| disabled | boolean | - | Disables the component. |
Additional Sub-components
- `Combobox.TriggerInput` - Single-select input trigger
- `Combobox.TriggerValue` - Button trigger showing selected value
- `Combobox.TriggerMultipleWithInput` - Multi-select with chips
- `Combobox.Input` - Search input inside dropdown
- `Combobox.List` - List container with render prop
- `Combobox.Group` - Group container for categorized items
- `Combobox.GroupLabel` - Header label for a group
- `Combobox.Collection` - Items container within a group
- `Combobox.Chip` - Selected item chip
- `Combobox.Empty` - Empty state message