Appearance
Autocomplete
SAutocomplete is an input with suggestions from search results. Unlike SSelect with the searchable prop, the options come from outside and change on every keystroke: the component does not filter options again, so results of fuzzy search, transliteration, and index search get through.
It is built on Reka UI Combobox: combobox/listbox/option roles, keyboard navigation, and a portaled panel. The label, hint and error message come from SFormField.
Two v-models
The value and the query are separate: v-model holds the selected value, v-model:search holds what the user typed. The app searches by the latter, usually with a debounce.
v-model:search receives only typed text: the label of the selected option and the text reset on panel close are not written there, so there is no extra request for the label, and the typed text does not disappear when the user leaves the field without picking anything. Writing to it from outside puts the text into the field — this is how a saved form is restored.
The label of the selected value comes from the selected-label prop: after a selection the suggestion list is usually empty, so the label cannot be taken from it. While no value is selected, selected-label does not touch the field text.
The select event fires on every suggestion pick, by mouse or keyboard. Unlike update:modelValue, it also fires when the same suggestion is picked again, so the app can repeat a check in a "picked → server rejected → picked again" scenario.
The Home and End keys stay with the input and move the caret within the text, not through the suggestion list. The arrow keys navigate the list.
Focus inside the component is not leaving the field
Clicking a suggestion does not fire blur: a "left the field without picking" handler would run before the selection, and if it changed the list, the item would vanish between mouse down and mouse up. blur is emitted only when focus leaves the component.
Custom option row
The #option slot replaces the row content, since a suggestion is rarely a single line of text. The #prepend slot places an element inside the frame on the left, usually an icon or a country flag.
Loading and empty results
While a request is in flight, loading shows an indicator instead of the list. When there are no suggestions, the panel shows a placeholder: the empty-text prop sets its text, the #empty slot sets its markup.
SSelect or SAutocomplete
| Situation | Component |
|---|---|
| The full list of options is known in advance | SSelect |
| Many options, search over a ready list | SSelect with searchable |
| Options come from the server and change on every keystroke | SAutocomplete |
| Fuzzy search, transliteration, or index search is needed | SAutocomplete |
API
Props
| Name | Type | Default | Description |
|---|---|---|---|
options* | {
label: string;
value: string;
disabled?: boolean
}[] | required | Current suggestions: the result of the application-side search. The list is not filtered again; whatever arrives is shown (fuzzy search, transliteration, index search). |
selected-label | string | undefined | Label of the selected value. A separate prop, because after a selection the suggestion list is usually empty and the label cannot be taken from it. |
loading | boolean | false | A request is in flight: a loading indicator is shown instead of the list. |
empty-text | string | undefined | Text shown when there are no suggestions (defaults to the locale dictionary). |
label | string | undefined | Field label (rendered via SFormField/SLabel). |
hint | string | undefined | Hint below the field. |
error | string | undefined | Error message. When set, the field is marked invalid. |
invalid | boolean | false | Explicitly marks the field invalid (in addition to error). |
required | boolean | false | Required field: a * marker next to the label. |
disabled | boolean | false | Disables the field. |
placeholder | string | undefined | Placeholder text in an empty field. |
id | string | undefined | Input id. Generated when not set (SSR-safe). |
size | "md" | "sm" | "lg" | "md" | Field size: sm (32px), md (40px) or lg (48px). |
square | boolean | undefined | Square corners: removes the rounding of the frame and the suggestion panel. |
clearable | boolean | true | Shows the clear button: it resets both the selection and the query text. |
clear-icon | string | "x" | Clear button icon: a registry name or a raw path. |
clear-label | string | undefined | Accessible name of the clear button (defaults to the locale dictionary). |
icon | string | undefined | Leading icon inside the field (a registry name or a raw path), drawn on the left. |
aria-label | string | undefined | Accessible name of the field (when there is no visible label). |
max-height | string | number | undefined | Maximum height of the suggestion panel (20rem by default). A number means pixels. The panel
also never grows past the free space to the window edge; the smaller of the two wins. |
flat | boolean | undefined | Removes the shadow. Overridden by the elevation prop when it is set. |
elevation | 0 | 1 | 2 | 3 | 4 | 5 | undefined | Shadow level 0–5 (scale); 0 means no shadow. Overrides flat. |
model-value | string | undefined | Selected value: the suggestion's value. Two-way binding via v-model. |
search | string | "" | The user's query: what they typed. The application searches by it, usually debounced, and
passes the result back into options. The component writes only typed text here (and an empty
string from the clear button): the selected label and the reset on panel close do not get here,
otherwise the query would be indistinguishable from text the component inserted itself. Writing
from outside puts the text into the input, which is how a saved form is restored. |
Events
| Name | Signature | Description |
|---|---|---|
update:modelValue | (value: string | undefined) => void | Emitted when modelValue changes. Used for two-way binding (v-model). |
update:search | (value: string) => void | Emitted when search changes. Used for two-way binding (v-model:search). |
clear | () => void | The value and the query text were cleared with the clear button. |
select | (option: SAutocompleteOption) => void | The user selected a suggestion with the mouse or keyboard. Fires on every selection, including re-selecting the same suggestion, when update:modelValue stays silent because the value did not change. |
Slots
| Name | Description |
|---|---|
prepend | Content at the start of the field, inside the frame (icon, country flag, button). |
append | Content at the end of the field, inside the frame. |
option | List row instead of the label. Receives the scoped props { option, index }. |
empty | Panel content when there are no suggestions. |
loading | Panel content while a request is in flight. |