Combobox
A searchable single-select with grouped options, custom values, rich snippets, and a native datalist fallback.
registry:ui Registry JSON Value: sveltekit
Value: None
Installation
pnpm dlx shadcn-svelte@latest add https://shadcn.cptckp.com/r/combobox.jsonThe CLI copies the source into your project and installs every dependency listed below.
Import { Combobox } and provide a unique id, form name, and options with label/value pairs. Bind value and optionally open; use group, keywords, and disabled on options. Customize item(option, selected) and selected(option) snippets, or enable allowCustom and clearLabel. The trigger defaults to secondary. Without JavaScript this renders an input and datalist; always validate required values, option membership, and custom text on the server.
Usage
import { Combobox, type ComboboxOption } from '$lib/components/ui/combobox/index.js';example.svelte
svelte
<script lang="ts">
import CheckIcon from '@lucide/svelte/icons/check';
import { Combobox, type ComboboxOption } from '$lib/components/ui/combobox/index.js';
const options = [
{ group: 'Frameworks', label: 'SvelteKit', value: 'sveltekit', description: 'Full-stack Svelte', keywords: 'SvelteKit sveltekit full-stack' },
{ group: 'Frameworks', label: 'Astro', value: 'astro', description: 'Content-driven sites' },
{ group: 'Libraries', label: 'Svelte', value: 'svelte', description: 'Reactive interfaces' },
{ group: 'Libraries', label: 'React', value: 'react', description: 'Component-based interfaces' }
] satisfies (ComboboxOption & { description: string })[];
let framework = $state('sveltekit');
let technology = $state('');
</script>
<div class="grid w-full gap-6 sm:grid-cols-2">
<section class="flex min-w-0 flex-col gap-3">
<label for="framework" class="text-sm font-medium">Grouped selection</label>
<Combobox
id="framework"
name="framework"
{options}
bind:value={framework}
placeholder="Select a framework"
searchPlaceholder="Search frameworks..."
clearLabel="Clear selection"
/>
<p class="text-sm text-muted-foreground">Value: {framework || 'None'}</p>
</section>
<section class="flex min-w-0 flex-col gap-3">
<label for="technology" class="text-sm font-medium">Rich options and custom values</label>
<Combobox
id="technology"
name="technology"
{options}
bind:value={technology}
allowCustom
placeholder="Select or add a technology"
searchPlaceholder="Search or type a new value..."
>
{#snippet item(option, isSelected)}
<div class="flex min-w-0 flex-1 flex-col">
<span class="truncate">{option.label}</span>
<span class="truncate text-xs text-muted-foreground">{option.description}</span>
</div>
{#if isSelected}<CheckIcon />{/if}
{/snippet}
{#snippet selected(option)}
{option.label} ยท {option.group}
{/snippet}
</Combobox>
<p class="text-sm text-muted-foreground">Value: {technology || 'None'}</p>
</section>
</div>Files & dependencies
| Installed as | Source |
|---|---|
| combobox/combobox.svelte | src/lib/registry/ui/combobox/combobox.svelte |
| combobox/combobox.ts | src/lib/registry/ui/combobox/combobox.ts |
| combobox/index.ts | src/lib/registry/ui/combobox/index.ts |
npm dependencies
- @lucide/svelte@^1.28.0
Registry dependencies
- button
- command
- input
- popover