# Autocomplete

> A free-text field with a portalled panel of matching suggestions — any typed value is valid; the panel only ever helps finish it faster.

- Package: `fancy-ui-svelte` (Svelte 5 + Tailwind CSS v4)
- Category: Forms
- Tags: autocomplete, suggestions, typeahead, listbox, form, compound, accessibility
- Docs: https://fancy-ui.rama.app/docs/components/autocomplete
- Source: https://github.com/RamaHerbin/fancy-ui/tree/main/src/lib/fancy-ui/autocomplete

## Import

```svelte
<script lang="ts">
  import { Autocomplete } from 'fancy-ui-svelte';
</script>
```

Setup (once per project): `npm install fancy-ui-svelte`, then add `@import "fancy-ui-svelte/tailwind.css";` after `@import "tailwindcss";` in your main CSS file. Full guide: https://fancy-ui.rama.app/llms.txt

React: `import { Autocomplete } from 'fancy-ui-react';` (same prop names; `class` becomes `className`, snippets become `ReactNode`).

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `suggestions` (required) | `string[]` | — | Candidate strings offered as the user types. |
| `value` | `string` | `""` | The free-text value, bindable. |
| `onValueChange` | `(value: string) => void` | — | Called with the new value on every keystroke. |
| `onSelect` | `(suggestion: string) => void` | — | Called only when a suggestion is committed via click or Enter — never from plain typing. |
| `placeholder` | `string` | — | Shown while the field is empty. |
| `disabled` | `boolean` | `false` | Blocks focus and typing; excluded from form submission. |
| `required` | `boolean` | `false` | Native required. |
| `invalid` | `boolean` | `false` | Drives the error border and aria-invalid. |
| `id` | `string` | — | Element id. |
| `name` | `string` | — | Native name, read on form submission. |
| `label` | `string` | — | Accessible name — for a control with no visible Label next to it. |
| `minLength` | `number` | `1` | Characters required before suggestions appear. |
| `maxSuggestions` | `number` | `8` | Maximum number of suggestions shown at once. |
| `class` | `string` | — | Additional CSS classes. |
| `ref` | `HTMLInputElement \| null` | `null` | Bindable reference to the input element. |
| `sound` | `boolean` | `false` | Plays the select cue when a suggestion is committed, once the user has enabled sound |

## Examples

### Basic Usage

A city field with six candidate suggestions.

```svelte
<script lang="ts">
	import { Autocomplete } from "fancy-ui-svelte";

	const cities = ["Paris", "Parma", "Prague", "London", "Lisbon", "Lyon"];
	let city = $state("");
</script>

<Autocomplete
	sound
	suggestions={cities}
	bind:value={city}
	label="City"
	placeholder="Type a city…"
/>
```

### Min Length

Suggestions stay hidden until the third character.

```svelte
<script lang="ts">
	// Suggestions stay hidden until the third character — useful for a long
	// candidate list where a one- or two-letter query would match too much
	// to be a useful shortcut.
	import { Autocomplete } from "fancy-ui-svelte";

	const cities = ["Paris", "Parma", "Prague", "London", "Lisbon", "Lyon"];
	let city = $state("");
</script>

<Autocomplete
	sound
	suggestions={cities}
	bind:value={city}
	minLength={3}
	label="City (3+ characters)"
	placeholder="Type at least 3 characters…"
/>
```

### With FormField

Wrapped in FormField — required and the error message driven by context.

```svelte
<script lang="ts">
	// FormField supplies controlId, aria-describedby and aria-invalid to
	// Autocomplete through context — no id or invalid prop needed here.
	import { FormField } from "fancy-ui-svelte";
	import { Autocomplete } from "fancy-ui-svelte";

	const cities = ["Paris", "Parma", "Prague", "London", "Lisbon", "Lyon"];
	let city = $state("");
</script>

<FormField
	label="City"
	required
	error={city ? undefined : "Enter a city before continuing."}
	class="w-full max-w-sm"
>
	<Autocomplete sound suggestions={cities} bind:value={city} />
</FormField>
```
