FormAutoComplete
A text box that suggests as you type, with suggestions supplied by your app, single or multiple values as chips, and a button for the whole list.
WAI-ARIA tested
Import
import { AutoComplete } from '@vitral/vue';
1<script setup lang="ts">2import { AutoComplete, FilterService, Label, StackPanel } from '@vitral/vue';3import { ref } from 'vue';4 5interface Country {6 name: string;7 code: string;8 region: string;9}10 11const countries: Country[] = [12 { name: 'Angola', code: 'AO', region: 'Africa' },13 { name: 'Argentina', code: 'AR', region: 'Americas' },14 { name: 'Brazil', code: 'BR', region: 'Americas' },15 { name: 'Cabo Verde', code: 'CV', region: 'Africa' },16 { name: 'Canada', code: 'CA', region: 'Americas' },17 { name: 'Chile', code: 'CL', region: 'Americas' },18 { name: 'Colombia', code: 'CO', region: 'Americas' },19 { name: 'France', code: 'FR', region: 'Europe' },20 { name: 'Germany', code: 'DE', region: 'Europe' },21 { name: 'Moçambique', code: 'MZ', region: 'Africa' },22 { name: 'Peru', code: 'PE', region: 'Americas' },23 { name: 'Portugal', code: 'PT', region: 'Europe' },24 { name: 'Spain', code: 'ES', region: 'Europe' },25 { name: 'São Tomé and Príncipe', code: 'ST', region: 'Africa' },26 { name: 'Uruguay', code: 'UY', region: 'Americas' }27];28 29const match = (query: string) => countries.filter((c) => FilterService.matches(c.name, query, 'contains'));30 31const single = ref<Country | string | null>(null);32const suggestions = ref<Country[]>([]);33</script>34 35<template>36 <StackPanel spacing="0.375rem" style="min-width: 16rem">37 <Label for="ac-country">Country</Label>38 <AutoComplete39 id="ac-country"40 v-model="single"41 :suggestions="suggestions"42 option-label="name"43 placeholder="Type a country"44 @complete="suggestions = match($event.query)"45 />46 <small style="color: var(--vt-text-muted-color)">Value: {{ typeof single === 'string' ? `"${single}"` : (single?.code ?? 'null') }}</small>47 </StackPanel>48</template>
Dropdown and forced selection
1<script setup lang="ts">2import { AutoComplete, FilterService, Label, StackPanel } from '@vitral/vue';3import { ref } from 'vue';4 5interface Country {6 name: string;7 code: string;8 region: string;9}10 11const countries: Country[] = [12 { name: 'Angola', code: 'AO', region: 'Africa' },13 { name: 'Argentina', code: 'AR', region: 'Americas' },14 { name: 'Brazil', code: 'BR', region: 'Americas' },15 { name: 'Cabo Verde', code: 'CV', region: 'Africa' },16 { name: 'Canada', code: 'CA', region: 'Americas' },17 { name: 'Chile', code: 'CL', region: 'Americas' },18 { name: 'Colombia', code: 'CO', region: 'Americas' },19 { name: 'France', code: 'FR', region: 'Europe' },20 { name: 'Germany', code: 'DE', region: 'Europe' },21 { name: 'Moçambique', code: 'MZ', region: 'Africa' },22 { name: 'Peru', code: 'PE', region: 'Americas' },23 { name: 'Portugal', code: 'PT', region: 'Europe' },24 { name: 'Spain', code: 'ES', region: 'Europe' },25 { name: 'São Tomé and Príncipe', code: 'ST', region: 'Africa' },26 { name: 'Uruguay', code: 'UY', region: 'Americas' }27];28 29const match = (query: string) => countries.filter((c) => FilterService.matches(c.name, query, 'contains'));30 31const single = ref<Country | string | null>(null);32const suggestions = ref<Country[]>([]);33</script>34 35<template>36 <StackPanel spacing="0.375rem" style="min-width: 16rem">37 <Label for="ac-forced">Country (from the list only)</Label>38 <AutoComplete39 id="ac-forced"40 v-model="single"41 :suggestions="suggestions"42 option-label="name"43 dropdown44 force-selection45 show-clear46 @complete="suggestions = match($event.query)"47 />48 </StackPanel>49</template>
1<script setup lang="ts">2import { AutoComplete, FilterService, Label, StackPanel } from '@vitral/vue';3import { ref } from 'vue';4 5interface Country {6 name: string;7 code: string;8 region: string;9}10 11const countries: Country[] = [12 { name: 'Angola', code: 'AO', region: 'Africa' },13 { name: 'Argentina', code: 'AR', region: 'Americas' },14 { name: 'Brazil', code: 'BR', region: 'Americas' },15 { name: 'Cabo Verde', code: 'CV', region: 'Africa' },16 { name: 'Canada', code: 'CA', region: 'Americas' },17 { name: 'Chile', code: 'CL', region: 'Americas' },18 { name: 'Colombia', code: 'CO', region: 'Americas' },19 { name: 'France', code: 'FR', region: 'Europe' },20 { name: 'Germany', code: 'DE', region: 'Europe' },21 { name: 'Moçambique', code: 'MZ', region: 'Africa' },22 { name: 'Peru', code: 'PE', region: 'Americas' },23 { name: 'Portugal', code: 'PT', region: 'Europe' },24 { name: 'Spain', code: 'ES', region: 'Europe' },25 { name: 'São Tomé and Príncipe', code: 'ST', region: 'Africa' },26 { name: 'Uruguay', code: 'UY', region: 'Americas' }27];28 29const match = (query: string) => countries.filter((c) => FilterService.matches(c.name, query, 'contains'));30 31const many = ref<Country[]>([]);32const suggestions = ref<Country[]>([]);33</script>34 35<template>36 <StackPanel spacing="0.375rem" style="min-width: 22rem">37 <Label for="ac-many">Countries</Label>38 <AutoComplete id="ac-many" v-model="many" :suggestions="suggestions" option-label="name" multiple fluid @complete="suggestions = match($event.query)" />39 </StackPanel>40</template>
1<script setup lang="ts">2import { AutoComplete, FilterService, Label, StackPanel } from '@vitral/vue';3import { ref } from 'vue';4 5interface Country {6 name: string;7 code: string;8 region: string;9}10 11const countries: Country[] = [12 { name: 'Angola', code: 'AO', region: 'Africa' },13 { name: 'Argentina', code: 'AR', region: 'Americas' },14 { name: 'Brazil', code: 'BR', region: 'Americas' },15 { name: 'Cabo Verde', code: 'CV', region: 'Africa' },16 { name: 'Canada', code: 'CA', region: 'Americas' },17 { name: 'Chile', code: 'CL', region: 'Americas' },18 { name: 'Colombia', code: 'CO', region: 'Americas' },19 { name: 'France', code: 'FR', region: 'Europe' },20 { name: 'Germany', code: 'DE', region: 'Europe' },21 { name: 'Moçambique', code: 'MZ', region: 'Africa' },22 { name: 'Peru', code: 'PE', region: 'Americas' },23 { name: 'Portugal', code: 'PT', region: 'Europe' },24 { name: 'Spain', code: 'ES', region: 'Europe' },25 { name: 'São Tomé and Príncipe', code: 'ST', region: 'Africa' },26 { name: 'Uruguay', code: 'UY', region: 'Americas' }27];28 29const match = (query: string) => countries.filter((c) => FilterService.matches(c.name, query, 'contains'));30 31const grouped = ref<Country | null>(null);32const groupedSuggestions = ref<{ region: string; items: Country[] }[]>([]);33function searchGrouped(query: string) {34 const hits = match(query);35 groupedSuggestions.value = ['Africa', 'Americas', 'Europe']36 .map((region) => ({ region, items: hits.filter((c) => c.region === region) }))37 .filter((g) => g.items.length);38}39</script>40 41<template>42 <StackPanel spacing="0.375rem" style="min-width: 16rem">43 <Label for="ac-grouped">Country by region</Label>44 <AutoComplete45 id="ac-grouped"46 v-model="grouped"47 :suggestions="groupedSuggestions"48 option-label="name"49 option-group-label="region"50 auto-option-focus51 @complete="searchGrouped($event.query)"52 >53 <template #option="{ option }">54 <span style="flex: 1">{{ (option as Country).name }}</span>55 <small style="color: var(--vt-text-muted-color)">{{ (option as Country).code }}</small>56 </template>57 </AutoComplete>58 </StackPanel>59</template>
Plain strings, sizes and states
API
Read from packages/vue/src/components/AutoComplete/types.ts, so it says what the component actually accepts.
Props
Plus pt, dt and unstyled from BaseProps, see pass-through and unstyled mode.
Emits
Slots