Autocomplete

A text field that suggests matching items as you type, with typo-tolerant ranking.

<tp-autocomplete>
Autocomplete
Default density Compact density Restart from the initial state Show the copyable source

Usage

Autocomplete’s value is the text itself: picking a suggestion replaces the text, and a form receives whatever is typed. When the value must be one of the items, use Select with searchable instead. Supply items as <option> children, and label the field with tp-field or label.

Matching

Prefix matching
Default density Compact density Restart from the initial state Show the copyable source

The default fuzzy matching ranks results by relevance and tolerates typos, so “rasberry” still finds Raspberry. prefix, contains and exact keep the items in their given order and suit codes, names and lists where a typo match would be noise. Matched text is highlighted in every mode. limit keeps the first results. filter ((item, query, text) => boolean) replaces matching with your own predicate, filter = null shows every item, and filteredItems supplies the results yourself.

Groups

Grouped suggestions
Default density Compact density Restart from the initial state Show the copyable source

<optgroup> labels sections of suggestions. show-trigger adds a button that opens the full list, and open-on-input-click opens it on click, which helps when people browse rather than type. Groups keep their labels while their matching suggestions are shown; groups without matches are hidden.

Completion

Inline completion
Default density Compact density Restart from the initial state Show the copyable source

completion-mode="both" fills in the highlighted suggestion as you type, selecting the completed part so typing continues naturally. auto-highlight highlights the first suggestion, so Enter accepts it. show-clear adds a clear button.

Keywords

Searching hidden fields
Default density Compact density Restart from the initial state Show the copyable source

The items property accepts strings, records and groups when the list comes from data. matchFields adds searchable text that is never displayed, such as aliases or keywords. Results can also come from a server through the source property.

Records

Ranking over several fields
Default density Compact density Restart from the initial state Show the copyable source

createIndexSource() builds the same typo-tolerant index the component uses, over any records you pass. Here it searches each article’s title and summary but weights the title three times, so “refund” lists Request a refund before the invoices article that only mentions it. itemToText names each record in the list and the field.

Search source
Default density Compact density Restart from the initial state Show the copyable source

A source’s search(query, context) returns results directly or as a promise, in the order they should appear. search-delay waits for a pause in typing, and each new query aborts the previous one through context.signal. While a request is pending the list is marked busy and keeps the previous suggestions, or shows a loading row when there are none. createRequestSource() wraps a URL and a response mapper into a source for you.

import { createRequestSource } from '@tweakpad/ui'; autocomplete.searchDelay = 250; autocomplete.source = createRequestSource({ url: (query) => `/api/cities?q=${encodeURIComponent(query)}`, map: (response) => response.cities.map((city) => city.name), minLength: 1, });

A failure shows “Suggestions could not be loaded.”.

Results may be plain items or hits { item, score?, terms?, matches? }. Matched ranges come from matches ([{ field: 'text', ranges: [[start, end], …] }]), else from terms, else from the typed words, so a server that reports what matched is highlighted exactly.

Any engine plugs in as a source; the library depends on none of them. For example, with an engine that returns ranked items and match positions:

autocomplete.source = { search(query) { return engine.search(query).map((result) => ({ item: result.item, score: result.score, matches: [ { field: 'text', ranges: result.positions.map(([start, end]) => [start, end + 1]) }, ], })); }, };

Forms

In a form
Default density Compact density Restart from the initial state Show the copyable source
Save profile

With name, the form receives the text, including text that matches no suggestion. required requires text. Enter with nothing highlighted submits the form, and Escape first closes the suggestions, then clears the text. submit-on-item-click submits as soon as a suggestion is picked, which suits a search box that has nothing else to fill in.

Down and Up open the suggestions and move through them; Home and End go to the first and last. Enter accepts the highlighted suggestion; with nothing highlighted the text stands and the owning form submits. Escape first removes a completion, then closes, and while closed clears the text. Typing opens the suggestions; clearing the text closes them unless open-on-input-click is set. Composition (IME) input never navigates or accepts.

Form reset restores default-value.

Accessibility

The input is a combobox with aria-autocomplete matching the completion mode; DOM focus stays in it while the highlight moves through the listbox (aria-activedescendant). Suggestions are options without a selected state. A polite status region announces the result count, loading and errors, in the messages texts.

API Reference

Every element also accepts motion-policy.

Events

EventTypeDescriptiontp-value-changeTpValueChangeEvent<unknown>Cancelable proposal of a new value, before it commits; detail.value, detail.previousValue and detail.reason.tp-field-valueCustomEvent<{ value: unknown; previousValue: unknown; reason: ChangeReason; }>After a value commits; an enclosing Field tracks its dirty state from it.tp-open-changeTpSurfaceOpenChangeEventCancelable proposal to open or close the list; detail.value and detail.reason.tp-open-change-completeCustomEvent<{ open: boolean; }>{ open } after the list finishes opening or closing.tp-search-statusCustomEvent<{ status: SearchStatus; query: string; total: number; }>{ status, query, total } as a search source loads, settles or fails.tp-search-errorCustomEvent<{ error: unknown; query: string; }>{ error, query } when a search source fails.

Slots

SlotDescriptiondefaultNative option, optgroup and hr children, or Select Options, declaring the choices when items is unset.emptyShown in place of the options when none matches the query.

CSS parts

PartDescription::part(select-action-host)The element around each trigger, clear and chip-remove button; style the buttons through their own parts.