A simplified, searchable combobox component for Svelte/SvelteKit, built on top of Shadcn-Svelte components. This component combines the structure of a select dropdown with powerful search functionality.
⚠️ Disclaimer: This component was kind of vibe coded. You assume all risks, as is.
Before using this component, you need the following dependencies:
The Combobox is split into modular sub-components for maximum flexibility:
| Component | Description |
|---|---|
| Root | Popover root wrapper that manages state |
| Trigger | Button that opens/closes the combobox |
| Content | Command root container for the dropdown |
| Input | Search input field with filtering |
| List | Container for all items |
| Empty | Empty state message when no results |
| Group | Groups items together (optional) |
| Item | Individual selectable item |
Perfect for selecting one option from a searchable list.
<script lang="ts">
import * as Combobox from "$lib/components/general/Combobox";
let value = $state("");
let open = $state(false);
const frameworks = [
{ value: "sveltekit", label: "SvelteKit" },
{ value: "nextjs", label: "Next.js" },
{ value: "remix", label: "Remix" },
{ value: "astro", label: "Astro" },
{ value: "nuxt", label: "Nuxt.js" },
];
</script>
<Combobox.Root type="single" bind:value bind:open>
<Combobox.Trigger {open}>
<span class="text-sm">
{frameworks.find(f => f.value === value)?.label || "Select framework..."}
</span>
</Combobox.Trigger>
<Combobox.Content>
<Combobox.Input placeholder="Search frameworks..." />
<Combobox.List>
<Combobox.Empty>No framework found.</Combobox.Empty>
<Combobox.Group>
{#each frameworks as framework}
<Combobox.Item value={framework.value}>
{framework.label}
</Combobox.Item>
{/each}
</Combobox.Group>
</Combobox.List>
</Combobox.Content>
</Combobox.Root>
Enable users to select multiple options at once.
<script lang="ts">
import * as Combobox from "$lib/components/general/Combobox";
let values = $state<string[]>([]);
let open = $state(false);
const frameworks = [
{ value: "sveltekit", label: "SvelteKit" },
{ value: "nextjs", label: "Next.js" },
{ value: "remix", label: "Remix" },
{ value: "astro", label: "Astro" },
{ value: "nuxt", label: "Nuxt.js" },
];
</script>
<Combobox.Root type="multiple" bind:values bind:open>
<Combobox.Trigger {open}>
<span class="text-sm">
{values.length > 0
? `${values.length} framework${values.length > 1 ? 's' : ''} selected`
: "Select frameworks..."}
</span>
</Combobox.Trigger>
<Combobox.Content>
<Combobox.Input placeholder="Search frameworks..." />
<Combobox.List>
<Combobox.Empty>No framework found.</Combobox.Empty>
<Combobox.Group>
{#each frameworks as framework}
<Combobox.Item value={framework.value}>
{framework.label}
</Combobox.Item>
{/each}
</Combobox.Group>
</Combobox.List>
</Combobox.Content>
</Combobox.Root>
The root component manages selection state and popover behavior.
| Prop | Type | Required | Description |
|---|---|---|---|
type |
"single" |
✅ | Sets single selection mode |
value |
string |
❌ | Currently selected value (bindable) |
onValueChange |
(value: string) => void |
❌ | Callback fired when selection changes |
open |
boolean |
❌ | Controls popover open state (bindable) |
| Prop | Type | Required | Description |
|---|---|---|---|
type |
"multiple" |
✅ | Sets multiple selection mode |
values |
string[] |
❌ | Array of selected values (bindable) |
onValuesChange |
(values: string[]) => void |
❌ | Callback fired when selection changes |
open |
boolean |
❌ | Controls popover open state (bindable) |
Note: All standard
Popover.Rootprops are also supported.
The button that opens/closes the combobox.
| Prop | Type | Required | Description |
|---|---|---|---|
open |
boolean |
❌ | Current open state for styling |
Note: All standard Shadcn-Svelte
Buttonprops are supported.
Individual selectable items within the combobox.
| Prop | Type | Required | Description |
|---|---|---|---|
value |
string |
✅ | Unique value for this item |
Note: Selection state is automatically managed via context. All standard
Command.Itemprops are supported.
Command component propsCommand.Input propsCommand.List propsCommand.Empty propsCommand.Group propsThis combobox component offers a different approach compared to the standard Select component:
| Feature | Combobox | Select |
|---|---|---|
| Search | ✅ Built-in with Command | ❌ Not included |
| Structure | Simpler, focused | More comprehensive |
| Scroll Controls | ❌ | ✅ |
| Separators | ❌ | ✅ |
| Labels | ❌ | ✅ |
| Customization | Easier for basic cases | More options out of the box |
| Use Case | Searchable dropdowns | Traditional select inputs |
Empty component to provide helpful feedback when searches return no resultsGroup component is optional but useful for categorizing itemsAs is. No warranties. Use at your own risk.
Enjoy! 🎉