<script lang="ts">
import { Autocomplete } from 'kumo-svelte';
const fruits = [
'Apple',
'Apricot',
'Avocado',
'Banana',
'Blackberry',
'Blueberry',
'Cantaloupe',
'Cherry',
'Coconut',
'Cranberry',
'Date',
'Dragon Fruit',
'Fig',
'Grape',
'Grapefruit',
'Guava',
'Honeydew',
'Kiwi',
'Lemon',
'Lime',
'Lychee',
'Mango',
'Nectarine',
'Orange',
'Papaya',
'Passion Fruit',
'Peach',
'Pear',
'Pineapple',
'Plum',
'Raspberry',
'Strawberry',
'Watermelon'
];
</script>
<Autocomplete items={fruits}>
<Autocomplete.InputGroup placeholder="Search fruits…" />
<Autocomplete.Content>
<Autocomplete.List>
{#snippet children(item)}
<Autocomplete.Item value={item}>{item}</Autocomplete.Item>
{/snippet}
</Autocomplete.List>
</Autocomplete.Content>
</Autocomplete> Installation
Barrel
import { Autocomplete } from 'kumo-svelte'; Granular
import { 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.
Controlled
Pass value and onValueChange for controlled usage.
<script lang="ts">
import { Autocomplete } from 'kumo-svelte';
const fruits = [
'Apple',
'Apricot',
'Avocado',
'Banana',
'Blackberry',
'Blueberry',
'Cantaloupe',
'Cherry',
'Coconut',
'Cranberry',
'Date',
'Dragon Fruit',
'Fig',
'Grape',
'Grapefruit',
'Guava',
'Honeydew',
'Kiwi',
'Lemon',
'Lime',
'Lychee',
'Mango',
'Nectarine',
'Orange',
'Papaya',
'Passion Fruit',
'Peach',
'Pear',
'Pineapple',
'Plum',
'Raspberry',
'Strawberry',
'Watermelon'
];
let value = $state('');
</script>
<div class="flex w-80 flex-col gap-3">
<Autocomplete bind:value items={fruits}>
<Autocomplete.InputGroup placeholder="Type a fruit…" />
<Autocomplete.Content>
<Autocomplete.List>
{#snippet children(item)}
<Autocomplete.Item value={item}>{item}</Autocomplete.Item>
{/snippet}
</Autocomplete.List>
</Autocomplete.Content>
</Autocomplete>
{#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.
<script lang="ts">
import { Autocomplete } from 'kumo-svelte';
const countries = [
{ label: 'United States', value: 'us' },
{ label: 'United Kingdom', value: 'gb' },
{ label: 'Germany', value: 'de' },
{ label: 'France', value: 'fr' },
{ label: 'Japan', value: 'jp' },
{ label: 'China', value: 'cn' },
{ label: 'India', value: 'in' },
{ label: 'Brazil', value: 'br' },
{ label: 'Canada', value: 'ca' },
{ label: 'Australia', value: 'au' }
];
</script>
<div class="w-80">
<Autocomplete
items={countries}
label="Country"
description="Start typing to filter countries"
>
<Autocomplete.InputGroup placeholder="Search countries…" />
<Autocomplete.Content>
<Autocomplete.List>
{#snippet children(item)}
<Autocomplete.Item value={item}>{item.label}</Autocomplete.Item>
{/snippet}
</Autocomplete.List>
</Autocomplete.Content>
</Autocomplete>
</div> Error State
Display validation errors with the error prop.
<script lang="ts">
import { Autocomplete } from 'kumo-svelte';
const countries = [
{ label: 'United States', value: 'us' },
{ label: 'United Kingdom', value: 'gb' },
{ label: 'Germany', value: 'de' },
{ label: 'France', value: 'fr' },
{ label: 'Japan', value: 'jp' },
{ label: 'China', value: 'cn' },
{ label: 'India', value: 'in' },
{ label: 'Brazil', value: 'br' },
{ label: 'Canada', value: 'ca' },
{ label: 'Australia', value: 'au' }
];
</script>
<div class="w-80">
<Autocomplete
items={countries}
label="Country"
error={{ message: 'Please enter a valid country', match: true }}
>
<Autocomplete.InputGroup placeholder="Search countries…" />
<Autocomplete.Content>
<Autocomplete.List>
{#snippet children(item)}
<Autocomplete.Item value={item}>{item.label}</Autocomplete.Item>
{/snippet}
</Autocomplete.List>
</Autocomplete.Content>
</Autocomplete>
</div> Grouped
Group items into categories using Autocomplete.Group and Autocomplete.GroupLabel.
<script lang="ts">
import { Autocomplete } from 'kumo-svelte';
const servers = [
{
label: 'North America',
value: 'North America',
items: [
{ label: 'US East (Virginia)', value: 'us-east-1' },
{ label: 'US West (Oregon)', value: 'us-west-2' },
{ label: 'Canada (Central)', value: 'ca-central-1' }
]
},
{
label: 'Europe',
value: 'Europe',
items: [
{ label: 'EU West (Ireland)', value: 'eu-west-1' },
{ label: 'EU Central (Frankfurt)', value: 'eu-central-1' },
{ label: 'EU North (Stockholm)', value: 'eu-north-1' }
]
},
{
label: 'Asia Pacific',
value: 'Asia Pacific',
items: [
{ label: 'AP Southeast (Singapore)', value: 'ap-southeast-1' },
{ label: 'AP Northeast (Tokyo)', value: 'ap-northeast-1' },
{ label: 'AP South (Mumbai)', value: 'ap-south-1' }
]
}
];
</script>
<Autocomplete items={servers}>
<Autocomplete.InputGroup placeholder="Select region…" />
<Autocomplete.Content>
<Autocomplete.List>
{#snippet children(group)}
<Autocomplete.Group items={group.items}>
<Autocomplete.GroupLabel>{group.label}</Autocomplete.GroupLabel>
<Autocomplete.Collection>
{#snippet children(item)}
<Autocomplete.Item value={item}>{item.label}</Autocomplete.Item>
{/snippet}
</Autocomplete.Collection>
</Autocomplete.Group>
{/snippet}
</Autocomplete.List>
</Autocomplete.Content>
</Autocomplete> Sizes
The size prop on Autocomplete.InputGroup supports four variants matching the
Input component: xs, sm, base (default), and lg.
<script lang="ts">
import { Autocomplete } from 'kumo-svelte';
const fruits = [
'Apple',
'Apricot',
'Avocado',
'Banana',
'Blackberry',
'Blueberry',
'Cantaloupe',
'Cherry',
'Coconut',
'Cranberry',
'Date',
'Dragon Fruit',
'Fig',
'Grape',
'Grapefruit',
'Guava',
'Honeydew',
'Kiwi',
'Lemon',
'Lime',
'Lychee',
'Mango',
'Nectarine',
'Orange',
'Papaya',
'Passion Fruit',
'Peach',
'Pear',
'Pineapple',
'Plum',
'Raspberry',
'Strawberry',
'Watermelon'
];
</script>
<div class="flex flex-wrap items-center gap-4">
<Autocomplete items={fruits.slice(0, 10)}>
<Autocomplete.InputGroup size="xs" placeholder="xs" />
<Autocomplete.Content>
<Autocomplete.List>
{#snippet children(item)}
<Autocomplete.Item value={item}>{item}</Autocomplete.Item>
{/snippet}
</Autocomplete.List>
</Autocomplete.Content>
</Autocomplete>
<Autocomplete items={fruits.slice(0, 10)}>
<Autocomplete.InputGroup size="sm" placeholder="sm" />
<Autocomplete.Content>
<Autocomplete.List>
{#snippet children(item)}
<Autocomplete.Item value={item}>{item}</Autocomplete.Item>
{/snippet}
</Autocomplete.List>
</Autocomplete.Content>
</Autocomplete>
<Autocomplete items={fruits.slice(0, 10)}>
<Autocomplete.InputGroup size="base" placeholder="base (default)" />
<Autocomplete.Content>
<Autocomplete.List>
{#snippet children(item)}
<Autocomplete.Item value={item}>{item}</Autocomplete.Item>
{/snippet}
</Autocomplete.List>
</Autocomplete.Content>
</Autocomplete>
<Autocomplete items={fruits.slice(0, 10)}>
<Autocomplete.InputGroup size="lg" placeholder="lg" />
<Autocomplete.Content>
<Autocomplete.List>
{#snippet children(item)}
<Autocomplete.Item value={item}>{item}</Autocomplete.Item>
{/snippet}
</Autocomplete.List>
</Autocomplete.Content>
</Autocomplete>
</div> 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 Autocomplete.useFilter() to
preserve the built-in accent-insensitive matching:
<script lang="ts"> import { Autocomplete } from "kumo-svelte"; const { contains } = Autocomplete.useFilter(); const languages = [ { value: "pt", label: "Portuguese", emoji: "🇵🇹" }, { value: "es", label: "Spanish", emoji: "🇪🇸" } ]; const filter = (item, query) => contains(item.label, query);</script><Autocomplete items={languages} {filter}> <!-- ... --></Autocomplete> To disable filtering entirely (for example, when results come from a server),
pass filter={null}:
<Autocomplete items={results} filter={null}> <!-- ... --></Autocomplete>API Reference
Autocomplete
Root component. Wraps all sub-components and manages state.
| Prop | Type | Default | Description |
|---|---|---|---|
| items * | unknown[] | - | Array of items to display in the dropdown. |
| value | string | number | string[] | - | Controlled input value. |
| open | boolean | false | Controlled open state. |
| 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. |
| defaultValue | string | number | string[] | - | Uncontrolled default input value. |
| onValueChange | (value: string | number | string[]) => void | - | Called when the value changes. |
| onOpenChange | (open: boolean) => void | - | Called when open state changes. |
Autocomplete.InputGroup
Autocomplete text input with Input component styling.
| Prop | Type | Default | Description |
|---|---|---|---|
| size | 'xs' | 'sm' | 'base' | 'lg' | "base" | Size of the autocomplete input. Matches Input component sizes. |
| placeholder | string | - | Placeholder text. |
Autocomplete.Content
Dropdown popup container.
| Prop | Type | Default | Description |
|---|---|---|---|
| align | 'start' | 'center' | 'end' | "start" | Alignment of the popup relative to the input. |
| alignOffset | number | string | - | Offset along the alignment axis. |
| side | 'top' | 'right' | 'bottom' | 'left' | "bottom" | Side of the input where the popup is placed. |
| sideOffset | number | string | 4 | Offset between the popup and the input. |
Autocomplete.List
Scrollable list container with render prop.
| Prop | Type | Default | Description |
|---|---|---|---|
| No component-specific props. Accepts standard HTML attributes. | |||
Autocomplete.Item
Individual suggestion item in the list.
| Prop | Type | Default | Description |
|---|---|---|---|
| value * | unknown | - | Value associated with this item. |
| disabled | boolean | - | Disables the component. |
Autocomplete.Group
Groups items under a heading.
| Prop | Type | Default | Description |
|---|---|---|---|
| items | AutocompleteItem[] | [] | Items rendered by the component. |
Autocomplete.GroupLabel
Heading label for a group.
| Prop | Type | Default | Description |
|---|---|---|---|
| No component-specific props. Accepts standard HTML attributes. | |||
Autocomplete.Collection
Item container within a group.
| Prop | Type | Default | Description |
|---|---|---|---|
| No component-specific props. Accepts standard HTML attributes. | |||
Autocomplete.Separator
Horizontal divider between items.
| Prop | Type | Default | Description |
|---|---|---|---|
| No component-specific props. Accepts standard HTML attributes. | |||