<script lang="ts">
import * as Autocomplete from "kumo-svelte/components/autocomplete";
const fruits = ["Apple", "Apricot", "Banana", "Blueberry", "Cherry", "Mango"];
</script>
<Autocomplete.Root>
<Autocomplete.InputGroup placeholder="Search fruits…" />
<Autocomplete.Content>
<Autocomplete.List>
{#each fruits as fruit (fruit)}
<Autocomplete.Item value={fruit}>{fruit}</Autocomplete.Item>
{/each}
<Autocomplete.Empty>No fruits found.</Autocomplete.Empty>
</Autocomplete.List>
</Autocomplete.Content>
</Autocomplete.Root>
Import
import * as Autocomplete from "kumo-svelte/components/autocomplete"; When to use
Use Autocomplete when the input value can be free-form text and suggestions are optional hints. Use Combobox instead when the selected value must come from the predefined list.
Usage
<script lang="ts">
import * as Autocomplete from "kumo-svelte/components/autocomplete";
const fruits = ["Apple", "Banana", "Cherry"];
</script>
<Autocomplete.Root>
<Autocomplete.InputGroup placeholder="Search fruits…" />
<Autocomplete.Content>
<Autocomplete.List>
{#each fruits as fruit (fruit)}
<Autocomplete.Item value={fruit}>{fruit}</Autocomplete.Item>
{/each}
<Autocomplete.Empty>No fruits found.</Autocomplete.Empty>
</Autocomplete.List>
</Autocomplete.Content>
</Autocomplete.Root> Controlled
Bind value or pass onValueChange for controlled usage.
<script lang="ts">
import * as Autocomplete from "kumo-svelte/components/autocomplete";
const fruits = ["Apple", "Apricot", "Banana", "Blueberry", "Cherry", "Mango"];
let value = $state("");
</script>
<div class="flex flex-col gap-3 w-80">
<Autocomplete.Root bind:value>
<Autocomplete.InputGroup placeholder="Type a fruit…" />
<Autocomplete.Content>
<Autocomplete.List>
{#each fruits as fruit (fruit)}
<Autocomplete.Item value={fruit}>{fruit}</Autocomplete.Item>
{/each}
<Autocomplete.Empty>No fruits found.</Autocomplete.Empty>
</Autocomplete.List>
</Autocomplete.Content>
</Autocomplete.Root>
{#if value}
<p class="text-sm text-kumo-subtle">Value: <span class="font-medium text-kumo-default">{value}</span></p>
{/if}
</div>
With Field
Add label, description, and required to enable the built-in Field wrapper.
Start typing to filter countries
<script lang="ts">
import * as Autocomplete from "kumo-svelte/components/autocomplete";
const countries = [
{ code: "us", label: "United States", value: "United States" },
{ code: "gb", label: "United Kingdom", value: "United Kingdom" },
{ code: "de", label: "Germany", value: "Germany" },
{ code: "fr", label: "France", value: "France" },
{ code: "jp", label: "Japan", value: "Japan" },
];
interface Props {
error?: string;
}
let { error }: Props = $props();
</script>
<div class="w-80">
<Autocomplete.Root
label="Country"
description={error ? undefined : "Start typing to filter countries"}
{error}
required
>
<Autocomplete.InputGroup placeholder="Search countries…" />
<Autocomplete.Content>
<Autocomplete.List>
{#each countries as country (country.code)}
<Autocomplete.Item value={country.value} label={country.label}>
{country.label}
</Autocomplete.Item>
{/each}
<Autocomplete.Empty>No countries found.</Autocomplete.Empty>
</Autocomplete.List>
</Autocomplete.Content>
</Autocomplete.Root>
</div>
Error State
Display validation errors with the error prop.
Please enter a valid country
<script lang="ts">
import * as Autocomplete from "kumo-svelte/components/autocomplete";
const countries = [
{ code: "us", label: "United States", value: "United States" },
{ code: "gb", label: "United Kingdom", value: "United Kingdom" },
{ code: "de", label: "Germany", value: "Germany" },
{ code: "fr", label: "France", value: "France" },
{ code: "jp", label: "Japan", value: "Japan" },
];
</script>
<div class="w-80">
<Autocomplete.Root label="Country" error="Please enter a valid country">
<Autocomplete.InputGroup placeholder="Search countries…" />
<Autocomplete.Content>
<Autocomplete.List>
{#each countries as country (country.code)}
<Autocomplete.Item value={country.value} label={country.label}>
{country.label}
</Autocomplete.Item>
{/each}
<Autocomplete.Empty>No countries found.</Autocomplete.Empty>
</Autocomplete.List>
</Autocomplete.Content>
</Autocomplete.Root>
</div>
Grouped
Group items into categories using Autocomplete.Group and Autocomplete.GroupLabel.
<script lang="ts">
import * as Autocomplete from "kumo-svelte/components/autocomplete";
const servers = [
{
value: "North America",
items: [
{ label: "US East", value: "us-east" },
{ label: "US West", value: "us-west" },
{ label: "Canada", value: "canada" },
],
},
{
value: "Europe",
items: [
{ label: "Germany", value: "germany" },
{ label: "France", value: "france" },
{ label: "United Kingdom", value: "uk" },
],
},
];
</script>
<Autocomplete.Root>
<Autocomplete.InputGroup placeholder="Select region…" />
<Autocomplete.Content>
<Autocomplete.List>
{#each servers as region (region.value)}
<Autocomplete.Group>
<Autocomplete.GroupLabel>{region.value}</Autocomplete.GroupLabel>
{#each region.items as item (item.value)}
<Autocomplete.Item value={item.label} label={item.label}>{item.label}</Autocomplete.Item>
{/each}
</Autocomplete.Group>
{/each}
<Autocomplete.Empty>No regions found.</Autocomplete.Empty>
</Autocomplete.List>
</Autocomplete.Content>
</Autocomplete.Root>
Sizes
The size prop on Autocomplete.InputGroup supports xs, sm, base, and lg.
<script lang="ts">
import * as Autocomplete from "kumo-svelte/components/autocomplete";
const fruits = ["Apple", "Apricot", "Banana", "Blueberry", "Cherry", "Mango"];
</script>
<div class="flex flex-wrap items-center gap-4">
<Autocomplete.Root>
<Autocomplete.InputGroup size="xs" placeholder="xs" />
<Autocomplete.Content>
<Autocomplete.List>
{#each fruits as fruit (fruit)}
<Autocomplete.Item value={fruit}>{fruit}</Autocomplete.Item>
{/each}
<Autocomplete.Empty>No fruits found.</Autocomplete.Empty>
</Autocomplete.List>
</Autocomplete.Content>
</Autocomplete.Root>
<Autocomplete.Root>
<Autocomplete.InputGroup size="sm" placeholder="sm" />
<Autocomplete.Content>
<Autocomplete.List>
{#each fruits as fruit (fruit)}
<Autocomplete.Item value={fruit}>{fruit}</Autocomplete.Item>
{/each}
<Autocomplete.Empty>No fruits found.</Autocomplete.Empty>
</Autocomplete.List>
</Autocomplete.Content>
</Autocomplete.Root>
<Autocomplete.Root>
<Autocomplete.InputGroup size="base" placeholder="base (default)" />
<Autocomplete.Content>
<Autocomplete.List>
{#each fruits as fruit (fruit)}
<Autocomplete.Item value={fruit}>{fruit}</Autocomplete.Item>
{/each}
<Autocomplete.Empty>No fruits found.</Autocomplete.Empty>
</Autocomplete.List>
</Autocomplete.Content>
</Autocomplete.Root>
<Autocomplete.Root>
<Autocomplete.InputGroup size="lg" placeholder="lg" />
<Autocomplete.Content>
<Autocomplete.List>
{#each fruits as fruit (fruit)}
<Autocomplete.Item value={fruit}>{fruit}</Autocomplete.Item>
{/each}
<Autocomplete.Empty>No fruits found.</Autocomplete.Empty>
</Autocomplete.List>
</Autocomplete.Content>
</Autocomplete.Root>
</div>
Custom Filtering
For advanced matching or async search, keep filtered items in application state and render that list.
<Autocomplete.Root>
<Autocomplete.InputGroup placeholder="Search countries…" />
<Autocomplete.Content>
<Autocomplete.List>
{#each filteredCountries as country (country.value)}
<Autocomplete.Item value={country.value} label={country.label}>
{country.label}
</Autocomplete.Item>
{/each}
<Autocomplete.Empty>No countries found.</Autocomplete.Empty>
</Autocomplete.List>
</Autocomplete.Content>
</Autocomplete.Root> API Reference
Autocomplete
| Prop | Type | Default |
|---|---|---|
| allowDeselect | boolean | true |
| children | Snippet | — |
| defaultValue | string | "" |
| description | Snippet | string | — |
| disabled | boolean | false |
| error | string | { message: Snippet | string; match: FieldErrorMatch } | — |
| label | Snippet | string | — |
| labelTooltip | Snippet | — |
| name | string | — |
| onOpenChange | (open: boolean) => void | — |
| onValueChange | (value: string) => void | — |
| open | boolean | false |
| required | boolean | — |
| size | KumoAutocompleteSize | KUMO_AUTOCOMPLETE_DEFAULT_VARIANTS.size |
| value | string | defaultValue |
Autocomplete.Content
| Prop | Type | Default |
|---|---|---|
| children | Snippet | — |
| class | string | — |
| container | PortalProps["to"] | — |
| sideOffset | number | 4 |
Autocomplete.Empty
| Prop | Type | Default |
|---|---|---|
| children | Snippet | — |
| class | string | — |
Autocomplete.Group
| Prop | Type | Default |
|---|---|---|
| children | Snippet | — |
Autocomplete.GroupLabel
| Prop | Type | Default |
|---|---|---|
| children | Snippet | — |
| class | string | — |
Autocomplete.Input
| Prop | Type | Default |
|---|---|---|
| aria-label | string | — |
| autocomplete | HTMLInputAttributes["autocomplete"] | — |
| class | string | — |
| clearOnDeselect | boolean | — |
| defaultValue | string | — |
| disabled | boolean | — |
| id | string | — |
| name | string | — |
| onblur | (event: FocusEvent & { currentTarget: HTMLInputElement }) => void | — |
| onfocus | (event: FocusEvent & { currentTarget: HTMLInputElement }) => void | — |
| oninput | (event: Event & { currentTarget: HTMLInputElement }) => void | — |
| onkeydown | (event: KeyboardEvent & { currentTarget: HTMLInputElement }) => void | — |
| onValueChange | (value: string) => void | — |
| placeholder | string | — |
| required | boolean | — |
| size | KumoAutocompleteSize | — |
Autocomplete.Item
| Prop | Type | Default |
|---|---|---|
| children | Snippet | — |
| disabled | boolean | false |
| label | string | — |
| value* | string | — |
Autocomplete.List
| Prop | Type | Default |
|---|---|---|
| children | Snippet | — |
| class | string | — |
Autocomplete.Separator
| Prop | Type | Default |
|---|---|---|
| class | string | — |