import ClearableAutocomplete from "@wikicasa-dev/components/UIKit/Autocomplete/ClearableAutocomplete";
Use for any search-as-you-type field: the place search ("Cerca comune, zona o indirizzo") in a hero or header, or a field in a form, where you style the trigger yourself. It is a bare <input> with no label, border or validation: you supply the look through class props and slots. After a selection, a clear button appears right after the typed text.
It is the search-as-you-type component for every case, forms included: style the trigger to match the other fields of the form. It replaces the legacy BaseAutocomplete.
onInputChangeCb(query) runs 300 ms after typing stops and must resolve to { id, label }[]; stale responses are discarded automatically. v-model is the selected option, or null. v-model:inputValue is the raw text; v-model:open the list state.
Usage
<script setup lang="ts">
import { ref } from "vue";
import ClearableAutocomplete from "@wikicasa-dev/components/UIKit/Autocomplete/ClearableAutocomplete";
import type { AccessibleSelectOptions } from "@wikicasa-dev/components";
type Place = AccessibleSelectOptions<{ province: string }, number>;
const PLACES: Place[] = [
{ id: 1, label: "Milano", province: "MI" },
{ id: 2, label: "Milano Marittima", province: "RA" },
{ id: 3, label: "Monza", province: "MB" },
];
// Mock search: replace with your data source
const searchPlaces = async (q: string) =>
PLACES.filter((p) => p.label.toLowerCase().startsWith(q.toLowerCase()));
const place = ref<Place | null>(null);
</script>
<template>
<ClearableAutocomplete
v-model="place"
placeholder="Cerca comune, zona o indirizzo"
:on-input-change-cb="searchPlaces"
trigger-wrapper-classes="search-trigger"
:clear-button="{ offset: 10 }"
>
<template #option-content="{ option }">
{{ option.label }} <small>({{ option.province }})</small>
</template>
<template #loading-state>
<li style="padding: 10px 20px">Caricamento…</li>
</template>
</ClearableAutocomplete>
</template>
Do / Don't
- Do always set
placeholder: the input has no label, so the placeholder is the only text that tells users (and screen readers) what to type. - Do style the field via
triggerWrapperClasses(row containing icons + input),inputWrapperClasses,inputClassesanddropdownClasses; put icons inleft-icon/right-iconand a custom clear glyph inclear-icon(default "X"). - Do use
onOptionSelectedCb(option, { trigger })to react to a choice;triggeris"click"or"enter". - Do call the exposed
clearSuggestions()when you hide (not unmount) the component, andfocus()/select()to move focus into it. - Do set
:enable-keyboard-controller="false"only if a parent handles arrow keys itself. - Don't call a real API in mockups; use a mock function like the one above.
- Don't expect
aria-*or other attributes to reach the<input>: onlyclassis forwarded (to the root).
Styling hooks
.uikit-clearable-autocomplete:--input-paddingand--input-margin(both0) for the<input>..uikit-clear-btn { --bg-color }(defaulttransparent); alsoclearButton.classes,width,height,offset(gap after the text, px).- The list uses
BaseDropDown's.uikit-dropdown-contentvariables (--dropdown-max-height, borders, radii).
API
Generated from the component's types. Do not edit by hand.
Props
| Name | Type | Default | Required | Description |
|---|---|---|---|---|
dataCy |
string |
|||
placeholder |
string |
|||
enableKeyboardController |
boolean |
true |
||
triggerWrapperClasses |
ClassTypeProp |
|||
inputWrapperClasses |
ClassTypeProp |
|||
inputClasses |
ClassTypeProp |
|||
hiddenTextClasses |
ClassTypeProp |
|||
dropdownClasses |
ClassTypeProp |
|||
clearButton |
{ classes?: ClassTypeProp; offset?: number | undefined; width?: number | undefined; height?: number | undefined; dataCy?: string | undefined; } |
|||
keepState |
Nullable<"open" | "closed"> |
|||
disableCb |
boolean |
false |
||
onInputChangeCb |
(v: string) => Promise<AccessibleSelectOptions<TPayload, TID>[]> |
yes | ||
onOptionSelectedCb |
Nullable<(v: AccessibleSelectOptions<TPayload, TID>, meta: ClearableAutocompleteSelectionMeta) => void> |
|||
open |
boolean |
false |
||
modelValue |
Nullable<AccessibleSelectOptions<TPayload, TID>> |
null |
||
inputValue |
string |
"" |
Events
| Name | Payload |
|---|---|
input |
[InputEvent] |
click |
[MouseEvent] |
keydown |
[KeyboardEvent] |
inputClick |
[MouseEvent] |
update:modelValue |
[value: Nullable<AccessibleSelectOptions<TPayload, TID>>] |
update:open |
[value: boolean] |
update:inputValue |
[value: string] |
v-model
v-model:open(boolean)v-modelbindsmodelValue(Nullable<AccessibleSelectOptions<TPayload, TID>>)v-model:inputValue(string)
Slots
| Name | Slot props |
|---|---|
left-icon |
|
clear-icon |
|
right-icon |
|
loading-state |
|
option-content |
{ option: AccessibleSelectOptions<TPayload, TID>; idx: number; } |
Exposed (template ref)
None.