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.
Basic usage
<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. |
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.
Patterns
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.
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.
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.