Input · AutoComplete

AutoComplete

The input box is automatically filled.

When to use

Used to provide input suggestions to the input box and perform automatic completion operations

The difference with the searchable Select component:

  • AutoComplete is essentially an enhanced Input component that provides input suggestions, while Select is a selector
  • When you click to expand, Select will clear all the values in the input box, and AutoComplete will keep the last selected value
  • Select's selected item rendering (the #selectedItem slot) can be any node, while the renderSelectedItem of AutoComplete may only return a string

Demos

How to import

<script setup lang="ts">
    import { AutoComplete } from '@fibrous/semi-ui-vue';
</script>

Basic usage

Monitor user input through @search, pass input suggestions through data, and maintain control with v-model, which updates when the input box changes/selects an input item

Code
<script setup lang="ts">
    import { ref } from 'vue';
    import { IconSearch } from '@fibrous/semi-icons-vue';
    import { AutoComplete } from '@fibrous/semi-ui-vue';

    const stringData = ref<string[]>([]);
    const value = ref<string | number>('');

    const handleStringSearch = (input: string) => {
        stringData.value = input ? ['gmail.com', '163.com', 'qq.com'].map((domain) => `${input}@${domain}`) : [];
    };

    const handleChange = (input: string | number) => {
        console.log('onChange', input);
    };
</script>

<template>
    <AutoComplete v-model="value" :data="stringData" placeholder="搜索... " showClear style="width: 200px" @change="handleChange" @search="handleStringSearch">
        <template #prefix>
            <IconSearch />
        </template>
    </AutoComplete>
</template>

Custom option rendering

When you need to customize the rendering of candidates, data can be passed in an array of objects (each Object contains two keys, label and value; value is the value selected by the candidate, and label is the text displayed by the candidate, which falls back to value when missing)
The content of a candidate can be customized through the #item="{ item, index }" slot: item is the data item as given, so keep only data in the items and write the markup in the slot

Code
<script setup lang="ts">
    import { ref } from 'vue';
    import { IconSearch } from '@fibrous/semi-icons-vue';
    import { AutoComplete, Avatar } from '@fibrous/semi-ui-vue';

    interface ListItem {
        name: string;
        email: string;
        abbr: string;
        color: 'amber' | 'indigo' | 'blue' | 'cyan';
        value?: string;
        label?: string;
    }

    const list: ListItem[] = [
        { name: '夏可漫', email: 'xiakeman@example.com', abbr: 'XK', color: 'amber' },
        { name: '申悦', email: 'shenyue@example.com', abbr: 'SY', color: 'indigo' },
        { name: '曲晨一', email: 'quchenyi@example.com', abbr: 'CY', color: 'blue' },
        { name: '文嘉茂', email: 'wenjiamao@example.com', abbr: 'JM', color: 'cyan' },
    ];

    const data = ref<ListItem[]>([]);

    const handleStringSearch = (value: string) => {
        data.value = value ? list.map((item) => ({ ...item, value: item.name, label: item.email })) : [];
    };

    const renderSelectedItem = (option: ListItem) => option.email;
</script>

<template>
    <AutoComplete aria-label="搜索邮箱" :data="data" :renderSelectedItem="renderSelectedItem" showClear style="width: 280px" @search="handleStringSearch">
        <template #prefix>
            <IconSearch />
        </template>
        <template #item="{ item }">
            <Avatar :color="item.color" size="small">{{ item.abbr }}</Avatar>
            <div style="margin-left: 4px">
                <div style="font-size: 14px; margin-left: 4px">{{ item.name }}</div>
                <div style="margin-left: 4px">{{ item.email }}</div>
            </div>
        </template>
    </AutoComplete>
</template>

Get user input value from @search, update data dynamically, update loading

Size

The size of the input box can be set by setting size, optional small, default (default), large





Code
<script setup lang="ts">
    import { AutoComplete } from '@fibrous/semi-ui-vue';

    const data = [1, 2, 3, 4];
</script>

<template>
    <div>
        <AutoComplete :data="data" placeholder="small" size="small" style="width: 200px" />
        <br />
        <br />
        <AutoComplete :data="data" placeholder="default" size="default" style="width: 200px" />
        <br />
        <br />
        <AutoComplete :data="data" placeholder="large" size="large" style="width: 200px" />
    </div>
</template>

The position of the drop-down menu

The position of the drop-down menu can be set by setting position, and the optional values refer to Tooltip position

Code
<script setup lang="ts">
    import { ref } from 'vue';
    import { AutoComplete } from '@fibrous/semi-ui-vue';

    const data = ref<string[]>([]);

    const change = (input: string) => {
        data.value = input ? ['gmail.com', '163.com', 'qq.com'].map((domain) => `${input}@${domain}`) : [];
    };
</script>

<template>
    <div>
        <AutoComplete :data="data" placeholder="选项菜单在上方显示" position="top" style="width: 200px; margin: 10px" @search="change" />
        <AutoComplete :data="data" placeholder="选项菜单在右侧显示" position="rightTop" style="width: 200px; margin: 10px" @search="change" />
    </div>
</template>

Disabled

Code
<script setup lang="ts">
    import { AutoComplete } from '@fibrous/semi-ui-vue';

    const data = [1, 2, 3, 4];
</script>

<template>
    <AutoComplete :data="data" disabled placeholder="禁用下拉菜单" style="width: 200px" />
</template>

Validate status

Different verification states can be set to show different styles





Code
<script setup lang="ts">
    import { AutoComplete } from '@fibrous/semi-ui-vue';
</script>

<template>
    <AutoComplete aria-label="Warning status" defaultValue="ies" validateStatus="warning" />
    <br />
    <br />
    <AutoComplete aria-label="Error status" defaultValue="ies" validateStatus="error" />
    <br />
    <br />
    <AutoComplete aria-label="Default status" defaultValue="ies" />
</template>

Custom empty content

Can set up custom display empty content

Code
<script setup lang="ts">
    import { ref } from 'vue';
    import { IllustrationNoContent } from '@fibrous/semi-illustrations-vue';
    import { AutoComplete, Empty } from '@fibrous/semi-ui-vue';

    const data = ref<number[]>([]);
    const loading = ref(false);

    const fetchData = (input: string) => {
        loading.value = true;
        setTimeout(() => {
            data.value = input ? Array.from({ length: 5 }, () => Math.random()) : [];
            loading.value = false;
        }, 1000);
    };
</script>

<template>
    <AutoComplete aria-label="搜索" :data="data" :loading="loading" @search="fetchData">
        <template #emptyContent>
            <Empty style="padding: 12px; width: 300px">
                <template #image>
                    <IllustrationNoContent style="width: 150px; height: 150px" />
                </template>
                <template #description>暂无内容</template>
            </Empty>
        </template>
    </AutoComplete>
</template>

API reference

Props

PropertyDescriptionTypeDefault
modelValueCurrent value of the input, bound with v-model. Passing it makes the component controlled; undefined leaves it uncontrolled.string | numberundefined
modelModifiersThe trim and number v-model modifiers, passed by Vue for v-model.trim and v-model.number.ModelModifiersundefined
defaultValueInitial value of the input when uncontrolled.string | numbersemiGlobalDefault("AutoComplete", "defaultValue")
dataData source of the candidates: an array of strings, numbers or objects. An object item uses value as the picked value and label as its text (value when label is missing); its disabled, class, style and data-* fields go to the matching row. Use the item slot for markup. Changing the array in place updates the list as well.T[]semiDefault("AutoComplete", "data", []) as T[]
autofocusWhether to focus the input after mount.booleansemiDefault("AutoComplete", "autofocus", false)
autoAdjustOverflowWhether the dropdown flips automatically when it would be clipped.booleansemiGlobalDefault("AutoComplete", "autoAdjustOverflow")
defaultActiveFirstOptionWhether the first candidate is highlighted when the panel opens, so that Enter picks it directly.booleansemiDefault("AutoComplete", "defaultActiveFirstOption", false)
defaultOpenWhether the dropdown panel is open on mount.booleansemiGlobalDefault("AutoComplete", "defaultOpen")
disabledWhether the component is disabled.booleansemiGlobalDefault("AutoComplete", "disabled")
dropdownClassNameClass name of the dropdown list, applied to the role="listbox" element.stringsemiGlobalDefault("AutoComplete", "dropdownClassName")
dropdownMatchSelectWidthWhether the minimum width of the dropdown equals the width of the input.booleansemiDefault("AutoComplete", "dropdownMatchSelectWidth", true)
dropdownStyleInline style of the dropdown list, applied to the role="listbox" element.StyleValuesemiGlobalDefault("AutoComplete", "dropdownStyle")
insetLabelIdThe id of the insetLabel element, which names the combobox and the listbox. When omitted, the component generates one while an insetLabel is rendered.stringundefined
loadingWhether the dropdown shows a loading spinner in place of the candidates and the empty content.booleansemiDefault("AutoComplete", "loading", false)
maxHeightMaximum height of the dropdown list; a number is in px.string | numbersemiDefault("AutoComplete", "maxHeight", 300)
motionWhether the dropdown animates when it shows and hides.booleansemiDefault("AutoComplete", "motion", true)
selectWithObjectA boolean attribute, not an event: when true, the select event receives the data item without internal fields instead of its value.booleansemiDefault("AutoComplete", "selectWithObject", false)
placeholderPlaceholder of the input.stringsemiGlobalDefault("AutoComplete", "placeholder")
positionPosition of the dropdown; the values are those of the Tooltip position. Unset, it is bottomLeft, or bottomRight when the ConfigProvider direction is rtl.Type"top" | "bottom" | "left" | "right" | "topLeft" | "topRight" | "leftTop" | "leftBottom" | "rightTop" | "rightBottom" | "bottomLeft" | "bottomRight" | "leftTopOver" | "rightTopOver" | "leftBottomOver" | "rightBottomOver"semiGlobalDefault("AutoComplete", "position")
renderSelectedItemThe text the input shows for a picked item; it must return a string. A string or number item receives { value, label }, an object item the item itself. It stays a function prop because the foundation calls it outside rendering.Type((option: AutoCompleteSelectedItem<T>) => string)undefined
showClearWhether to show the clear button when there is content.booleansemiDefault("AutoComplete", "showClear", false)
sizeSize of the input.SizesemiDefault("AutoComplete", "size", "default")
stopPropagationWhether click, mousedown and focus in/out events on the dropdown stop propagating.string | booleansemiDefault("AutoComplete", "stopPropagation", true)
validateStatusValidation status; it only affects the style."default" | "error" | "warning" | "success"semiDefault("AutoComplete", "validateStatus", "default")

Events

EventDescriptionCallback parameters
update:modelValueEmitted when the input text changes or a candidate is picked, for v-model to write back. It fires before change.[value: string | number]
changeEmitted when the input text changes or a candidate is picked. It is a component event and hides the native change event of the input.[value: string | number]
searchEmitted as the user types, with the typed text.[inputValue: string]
selectEmitted when a candidate is picked, with its value, or with the item without internal fields when selectWithObject is set.[value: string | number | AutoCompleteDataItem]
clearEmitted after the clear button is used.[]
focusEmitted once when the focus enters the component. It is a component event and hides the native focus event.[event: FocusEvent]
blurEmitted once when the focus leaves the component. It is a component event and hides the native blur event.[event: FocusEvent]
dropdownVisibleChangeEmitted when the dropdown shows or hides, with its visibility. It also fires with false when the component is deactivated inside KeepAlive.[visible: boolean]
keydownEmitted after the component has handled the key, with the KeyboardEvent. It hides the native keydown event.[event: KeyboardEvent]

Slots

SlotDescriptionScope parameters
prefixPrefix content of the input.any
suffixSuffix content of the input.any
insetLabelInset label of the input. It is not rendered, and does not name the component, when prefix or trigger is used.any
clearIconCustom clear icon, effective when showClear is true.any
emptyContentContent shown in the dropdown when data is empty.any
itemContent of a candidate row. item is the data item as given and index is its position among the rendered items; without it the row shows the label.TypeAutoCompleteItemSlotProps<T>
triggerReplaces the input. Its parameters are value, inputValue, placeholder, disabled, autofocus, size, validateStatus, showClear, insetLabelId, onChange (updates the input text, emits search and change and opens the list), onClear, onFocus, onBlur, controlAttrs (the aria-* attributes given to the component, for the focusable element of the custom trigger) and componentProps. With it, id lands on the root element.TypeAutoCompleteTriggerSlotProps<T>

Exposes

NameDescriptionType
None

id, name, and aria-describedby, aria-errormessage, aria-invalid, aria-label, aria-labelledby, aria-required land on the input (role="combobox"), so a <label for> finds it. class, style, data-* and other undeclared attributes and listeners (for example @click) land on the root div, whose tabindex is fixed to -1. With #trigger there is no input: id lands on the root div, name lands nowhere, and the aria-* attributes reach the focusable element of the custom trigger through the controlAttrs slot parameter.

Object items of data:

FieldDescriptionType
valueThe value after pickingstring | number
labelThe text of the candidate, falling back to value; use the #item slot for markupstring | number
disabledWhether the candidate is disabledboolean
classClass of the candidate rowstring | object | array
styleStyle of the candidate rowStyleValue

Other fields are kept as they are and show up in item of the #item slot and in the payload of @select (when selectWithObject is set). Fields starting with data- land on the candidate row. A string or number item reaches renderSelectedItem as { value, label }.

AutoComplete exposes the following members through a template ref, typed as AutoCompleteHandle:

MemberDescriptionType
nativeElementRead-only. The root div that wraps the input or the custom trigger, null before mountHTMLDivElement | null

Accessibility

Keyboard and Focus

  • AutoComplete's input box has role="combobox" and is linked to the options panel through aria-expanded, aria-controls, aria-autocomplete="list" and aria-activedescendant
  • The combobox takes its name from, in order: aria-labelledby, aria-label, the rendered insetLabel (the combobox's aria-labelledby points at it, with an id the component generates when insetLabelId is not given; with a prefix the insetLabel is not rendered and does not name it). The listbox uses the same name source. AutoComplete has no default name: with none of these, name the input with aria-label or aria-labelledby; a <label for> names only the input and leaves the listbox unnamed
  • AutoComplete's input box can be focused, and once focused, keyboard users can use Up Arrow or Down Arrow to open the options panel; when data is empty the panel shows emptyContent (nothing when it is not provided), and a loading spinner while loading
  • AutoComplete also supports opening and closing panels via Enter key
  • If the user sets the defaultActiveFirstOption property to true, the first option is highlighted by default when the options panel is opened
  • If the drop-down menu is open:
    • Use Esc to close the menu
    • Use Tab to close the menu; the focus moves on to the next focusable element as usual
    • Use Up Arrow or Down Arrow to toggle options; the highlighted option (the one aria-activedescendant points at) has aria-selected="true"
    • The focused option can be selected with the Enter key and the panel will be collapsed
    • After picking an option with the mouse, the focus stays in the input
  • With showClear and a value, the clear button is the same as Input's: a native button named "Clear input" from the locale; from the input, Tab moves to it, and Enter or Space clears and puts the focus back in the input

Content Guidelines

  • Content needs to be presented clearly so that users can clearly perceive the options available
  • Limit the number of options displayed at one time

Design Token

These are the component's internal Sass variables and cannot be overridden. To customize styles, override the --semi-* CSS variables (see the Design Token page) or write unlayered CSS rules.
Sass variableValueUsage
$transition_duration-autoComplete_option-bgvar(--semi-transition_duration-none)选择器-选项-动画持续时间
$transition_function-autoComplete_option-bgvar(--semi-transition_function-easeIn)选择器-选项-过渡曲线
$transition_delay-autoComplete_option-bgvar(--semi-transition_delay-none)选择器-选项-延迟时间
$spacing-autoComplete_loading_wrapper-paddingTop$spacing-tight加载搜索结果时的顶部内边距
$spacing-autoComplete_loading_wrapper-paddingBottom$spacing-tight加载搜索结果时的底部内边距
$color-autoComplete_option-icon-defaulttransparent自动完成菜单选项图标颜色 - 默认态
$color-autoComplete_option-bg-hovervar(--semi-color-fill-0)自动完成菜单选项背景颜色 - 悬停态
$color-autoComplete_option-bg-activevar(--semi-color-fill-1)自动完成菜单选项背景颜色 - 按下态
$color-autoComplete_option_disabled-textvar(--semi-color-disabled-text)禁用自动完成菜单选项文字颜色
$width-autoComplete_option_tick$width-icon-small自动完成菜单项选中对勾图标大小
$spacing-autoComplete_option_tick-marginRight$spacing-tight自动完成菜单选中对勾右侧外边距
$spacing-autoComplete_option-paddingLeft$spacing-base-tight自动完成菜单项左侧内边距
$spacing-autoComplete_option-paddingRight$spacing-base-tight自动完成菜单项右侧内边距
$spacing-autoComplete_option-paddingTop$spacing-tight自动完成菜单项顶部内边距
$spacing-autoComplete_option-paddingBottom$spacing-tight自动完成菜单项底部内边距
$spacing-autoComplete_option_first-marginTop$spacing-extra-tight自动完成第一个菜单项顶部外边距
$spacing-autoComplete_option_last-marginBottom$spacing-extra-tight自动完成最后一个菜单项顶部外边距
$radius-autoComplete_option0px自动完成待选项圆角
$color-autoComplete_option_main-textvar(--semi-color-text-0)自动完成菜单选项文本颜色