SvAutoComplete
A free-text input with a live-filtered suggestion list. Unlike SvComboBox, it accepts any value - the suggestions are just shortcuts - and it emits the raw text string.
SvAutoComplete is the "search box with hints" control: the user can type
anything, and matching suggestions drop down as they go. It is controlled through
value + onChange (both strings), the popover portals out of any scroll
container, and minChars gates when the list appears. Suggestions can be plain
strings or { value, label } objects, so the shown label and the inserted value
can differ.
Related: SvComboBox · SvTagsInput · Selection overview
Installation
Add it with the CLI - this drops a ready-to-edit SvAutoComplete starter into your app:
Prefer to see it first? npx @svgrid/ui try auto-complete opens it in a throwaway sandbox - no project needed.
Or install the package and import it directly. SvAutoComplete ships free in
@svgrid/grid (dependency-free):
import { SvAutoComplete } from '@svgrid/grid'
Example
Open the live example: Autocomplete (Selection)
<script lang="ts">
import { SvAutoComplete } from '@svgrid/grid'
const cities = ['Amsterdam', 'Berlin', 'Copenhagen', 'Dublin']
let value = $state('')
</script>
<SvAutoComplete label="City" suggestions={cities}
{value} onChange={(v) => (value = v)} placeholder="Search a city" />
Props
| Prop | Type | Default | Description |
|---|---|---|---|
value |
string |
'' |
The current text value. |
onChange |
(value: string) => void |
- | Fires with the text on every edit or suggestion pick. |
suggestions |
ReadonlyArray<string | ListOption> |
[] |
Suggestion shortcuts - strings or { value, label }. |
minChars |
number |
1 |
Chars typed before suggestions appear. |
placeholder |
string |
- | Input placeholder. |
resizable |
boolean |
false |
Add a bottom drag grip so the user can resize the open suggestion panel (hidden on an upward flip). |
size |
sm | md | lg |
md |
Control height and font size. |
disabled |
boolean |
false |
Blocks interaction. |
label |
string |
- | Visible field label, wired to the control. |
hint |
string |
- | Helper text under the control. |
error |
string |
- | Error message; announced and styled when set. |
required |
boolean |
false |
Marks the field required. |
invalid |
boolean |
false |
Applies the invalid state. |
name |
string |
- | Emits a hidden input carrying the text for form posts. |
dir |
ltr | rtl | auto |
auto |
Text direction. |
ariaLabel |
string |
- | Accessible name when there is no visible label. |
id |
string |
- | Root id; label/hint/error ids derive from it. |
Object suggestions use the shared ListOption shape;
the label is shown and the value is inserted.
Examples
Distinct label and inserted value
Use { value, label } suggestions when the visible hint differs from the text you
want in the field:
<SvAutoComplete label="Command"
suggestions={[{ value: 'is:open ', label: 'is:open - unresolved' }]}
{value} onChange={(v) => (value = v)} />
Gate the list until it is useful
Raise minChars so suggestions only appear once the query narrows things down:
<SvAutoComplete suggestions={tags} minChars={2} />
Free text is always valid
Because any typed value is accepted, bind the string straight into your model - no "must match an option" check. Reach for SvComboBox when you need to constrain the value to the list.
Suggestions from your own data
The control just takes a suggestions array, so build it reactively from any
source - recent searches, a fetched list, deduped history - while the user can
still type anything:
<script lang="ts">
import { SvAutoComplete } from '@svgrid/grid'
let value = $state('')
const history = ['invoices', 'inventory', 'insights']
// Narrow the history to what has been typed so far.
const suggestions = $derived(
value ? history.filter((h) => h.startsWith(value.toLowerCase())) : history,
)
</script>
<SvAutoComplete label="Search" {suggestions}
{value} onChange={(v) => (value = v)} placeholder="Search…" />
Tip:
onChangefires the raw text on every keystroke, so debounce any expensive side effect (a fetch, a route change) you drive from it rather than running it inline.
Resizable panel
Set resizable to give the open suggestion panel a bottom drag grip; drag it to
grow or shrink the list, and the height sticks for the session. The grip hides on
an upward flip. The same prop is on SvComboBox and
SvDropDownList.
<SvAutoComplete resizable {suggestions} label="City" />
Open the live example: Resizable dropdowns (Selection)
Accessibility
- The input is a
role="combobox"witharia-expanded; the suggestion panel is arole="listbox"with a roving active option. - Type to filter,
ArrowUp/ArrowDownto move,Enterto accept the active suggestion,Escapeto dismiss - typed text is kept either way. label,hint, anderrorare wired viaaria-describedby; passariaLabelwhen there is no visible label.
More examples
Autocomplete - headless
createAutocomplete drives SvAutoComplete and a custom suggestion-list render over one text value.
Open the live example: Autocomplete - headless (Headless Editors)
Sizes
Every control takes the same three sizes, so a dense toolbar and a roomy form can share components.
<script lang="ts">
import { SvAutoComplete } from '@svgrid/grid'
let autoComplete = $state('')
</script>
<SvAutoComplete bind:value={autoComplete} size="sm" />
<SvAutoComplete bind:value={autoComplete} size="md" />
<SvAutoComplete bind:value={autoComplete} size="lg" />
In a form
The shared field props behave the same on every editor: label names it, hint explains it, and error plus invalid mark it - which is why a validated form does not need per-component handling.
<script lang="ts">
import { SvAutoComplete } from '@svgrid/grid'
let autoComplete = $state('')
</script>
<SvAutoComplete
bind:value={autoComplete}
label="Label"
hint="A short hint"
required
/>
<SvAutoComplete
bind:value={autoComplete}
label="Label"
error="Something is wrong"
invalid
/>
See also
- Selection overview - the whole picker family at a glance.
- SvComboBox - the same UI, but the value must come from the list.
- SvTagsInput - multiple free-text tokens instead of one value.
Live examples
- Autocomplete - SvAutoComplete: a free-text search field with live suggestion shortcuts (any value accepted) - city search and a filter-syntax helper.
- Resizable dropdowns - Built-in browser bounds detection - every picker panel (SvDropDownList / SvComboBox / SvAutoComplete) opens downward when there is room and flips upward automatically near the window edge. Plus a `resizable` prop that adds a bottom drag grip to the open panel (drag to grow/shrink; height sticks for the session; grip hides on an upward flip). A switch compares fixed-height vs resizable. Theme-aware (light/dark).
- Autocomplete - headless - createAutocomplete drives SvAutoComplete and a custom suggestion-list render over one text value.