feat: autocomplete support option slot
parent
e35730354d
commit
cb3c002e17
|
@ -1,10 +1,10 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders ./components/auto-complete/demo/basic.vue correctly 1`] = `
|
||||
<div style="width: 200px;" class="ant-select ant-select-show-search ant-select-auto-complete ant-select-single ant-select-customize-input ant-select-show-search">
|
||||
<div style="width: 200px;" class="ant-select ant-select-show-search ant-select-auto-complete ant-select-single ant-select-show-search">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" type="search" autocomplete="off" class="ant-input ant-select-selection-search-input" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" aria-activedescendant="rc_select_TEST_OR_SSR_list_0"></span>
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" aria-activedescendant="rc_select_TEST_OR_SSR_list_0" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder">input here</span>
|
||||
</div>
|
||||
<!---->
|
||||
|
@ -39,10 +39,10 @@ exports[`renders ./components/auto-complete/demo/custom.vue correctly 1`] = `
|
|||
`;
|
||||
|
||||
exports[`renders ./components/auto-complete/demo/non-case-sensitive.vue correctly 1`] = `
|
||||
<div style="width: 200px;" class="ant-select ant-select-show-search ant-select-auto-complete ant-select-single ant-select-customize-input ant-select-show-search">
|
||||
<div style="width: 200px;" class="ant-select ant-select-show-search ant-select-auto-complete ant-select-single ant-select-show-search">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" type="search" autocomplete="off" class="ant-input ant-select-selection-search-input" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" aria-activedescendant="rc_select_TEST_OR_SSR_list_0"></span>
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" aria-activedescendant="rc_select_TEST_OR_SSR_list_0" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder">input here</span>
|
||||
</div>
|
||||
<!---->
|
||||
|
@ -51,10 +51,10 @@ exports[`renders ./components/auto-complete/demo/non-case-sensitive.vue correctl
|
|||
`;
|
||||
|
||||
exports[`renders ./components/auto-complete/demo/options.vue correctly 1`] = `
|
||||
<div style="width: 200px;" class="ant-select ant-select-show-search ant-select-auto-complete ant-select-single ant-select-customize-input ant-select-show-search">
|
||||
<div style="width: 200px;" class="ant-select ant-select-show-search ant-select-auto-complete ant-select-single ant-select-show-search">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" type="search" autocomplete="off" class="ant-input ant-select-selection-search-input" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" aria-activedescendant="rc_select_TEST_OR_SSR_list_0"></span>
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" aria-activedescendant="rc_select_TEST_OR_SSR_list_0" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder">input here</span>
|
||||
</div>
|
||||
<!---->
|
||||
|
|
|
@ -26,28 +26,23 @@ Lookup-Patterns - Certain Category.
|
|||
size="large"
|
||||
style="width: 100%"
|
||||
option-label-prop="value"
|
||||
:options="dataSource"
|
||||
>
|
||||
<template #dataSource>
|
||||
<a-select-opt-group v-for="group in dataSource" :key="group.title">
|
||||
<template #label>
|
||||
<span>
|
||||
{{ group.title }}
|
||||
<a
|
||||
style="float: right"
|
||||
href="https://www.google.com/search?q=antd"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
more
|
||||
</a>
|
||||
</span>
|
||||
</template>
|
||||
<a-select-option v-for="opt in group.children" :key="opt.title" :value="opt.title">
|
||||
{{ opt.title }}
|
||||
<span class="certain-search-item-count">{{ opt.count }} people</span>
|
||||
</a-select-option>
|
||||
</a-select-opt-group>
|
||||
<a-select-option key="all" disabled class="show-all">
|
||||
<template #option="item">
|
||||
<template v-if="item.options">
|
||||
<span>
|
||||
{{ item.value }}
|
||||
<a
|
||||
style="float: right"
|
||||
href="https://www.google.com/search?q=antd"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
more
|
||||
</a>
|
||||
</span>
|
||||
</template>
|
||||
<template v-else-if="item.value === 'all'">
|
||||
<a
|
||||
href="https://www.google.com/search?q=ant-design-vue"
|
||||
target="_blank"
|
||||
|
@ -55,7 +50,11 @@ Lookup-Patterns - Certain Category.
|
|||
>
|
||||
View all results
|
||||
</a>
|
||||
</a-select-option>
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ item.title }}
|
||||
<span class="certain-search-item-count">{{ item.count }} people</span>
|
||||
</template>
|
||||
</template>
|
||||
<a-input placeholder="input here">
|
||||
<template #suffix><search-outlined class="certain-category-icon" /></template>
|
||||
|
@ -69,40 +68,43 @@ import { SearchOutlined } from '@ant-design/icons-vue';
|
|||
import { defineComponent, ref } from 'vue';
|
||||
const dataSource = [
|
||||
{
|
||||
title: 'Libraries',
|
||||
children: [
|
||||
value: 'Libraries',
|
||||
options: [
|
||||
{
|
||||
title: 'AntDesign',
|
||||
value: 'AntDesign',
|
||||
count: 10000,
|
||||
},
|
||||
{
|
||||
title: 'AntDesign UI',
|
||||
value: 'AntDesign UI',
|
||||
count: 10600,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Solutions',
|
||||
children: [
|
||||
value: 'Solutions',
|
||||
options: [
|
||||
{
|
||||
title: 'AntDesign UI FAQ',
|
||||
value: 'AntDesign UI FAQ',
|
||||
count: 60100,
|
||||
},
|
||||
{
|
||||
title: 'AntDesign FAQ',
|
||||
value: 'AntDesign FAQ',
|
||||
count: 30010,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Articles',
|
||||
children: [
|
||||
value: 'Articles',
|
||||
options: [
|
||||
{
|
||||
title: 'AntDesign design language',
|
||||
value: 'AntDesign design language',
|
||||
count: 100000,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: 'all',
|
||||
},
|
||||
];
|
||||
export default defineComponent({
|
||||
components: {
|
||||
|
|
|
@ -8,11 +8,11 @@ title:
|
|||
|
||||
## zh-CN
|
||||
|
||||
也可以直接传递 #dataSource 的Option。
|
||||
3.0 以上版本,可以传递 `v-slot:option` 来自定义 Option。
|
||||
|
||||
## en-US
|
||||
|
||||
You could pass `#dataSource` as children of `AutoComplete`, instead of using `dataSource`.
|
||||
For 3.0+, You could pass `v-slot:option` to custom option.
|
||||
</docs>
|
||||
|
||||
<template>
|
||||
|
@ -20,12 +20,12 @@ You could pass `#dataSource` as children of `AutoComplete`, instead of using `da
|
|||
v-model:value="value"
|
||||
style="width: 200px"
|
||||
placeholder="input here"
|
||||
:options="options"
|
||||
@search="handleSearch"
|
||||
>
|
||||
<template #dataSource>
|
||||
<a-select-option v-for="email in result" :key="email">
|
||||
{{ email }}
|
||||
</a-select-option>
|
||||
<template #option="{ value: val }">
|
||||
{{ val.split('@')[0] }} @
|
||||
<span style="font-weight: bold">{{ val.split('@')[1] }}</span>
|
||||
</template>
|
||||
</a-auto-complete>
|
||||
</template>
|
||||
|
@ -36,20 +36,20 @@ import { defineComponent, ref } from 'vue';
|
|||
export default defineComponent({
|
||||
setup() {
|
||||
const value = ref('');
|
||||
const result = ref<string[]>([]);
|
||||
const options = ref<{ value: string }[]>([]);
|
||||
const handleSearch = (val: string) => {
|
||||
let res: string[];
|
||||
let res: { value: string }[];
|
||||
if (!val || val.indexOf('@') >= 0) {
|
||||
res = [];
|
||||
} else {
|
||||
res = ['gmail.com', '163.com', 'qq.com'].map(domain => `${val}@${domain}`);
|
||||
res = ['gmail.com', '163.com', 'qq.com'].map(domain => ({ value: `${val}@${domain}` }));
|
||||
}
|
||||
result.value = res;
|
||||
options.value = res;
|
||||
};
|
||||
|
||||
return {
|
||||
value,
|
||||
result,
|
||||
options,
|
||||
handleSearch,
|
||||
};
|
||||
},
|
||||
|
|
|
@ -23,21 +23,20 @@ Lookup-Patterns - Uncertain Category.
|
|||
size="large"
|
||||
style="width: 100%"
|
||||
option-label-prop="title"
|
||||
:options="dataSource"
|
||||
@select="onSelect"
|
||||
@search="handleSearch"
|
||||
>
|
||||
<template #dataSource>
|
||||
<a-select-option v-for="item in dataSource" :key="item.category" :title="item.category">
|
||||
Found {{ item.query }} on
|
||||
<a
|
||||
:href="`https://s.taobao.com/search?q=${item.query}`"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{{ item.category }}
|
||||
</a>
|
||||
<span class="global-search-item-count">{{ item.count }} results</span>
|
||||
</a-select-option>
|
||||
<template #option="item">
|
||||
Found {{ item.query }} on
|
||||
<a
|
||||
:href="`https://s.taobao.com/search?q=${item.query}`"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{{ item.category }}
|
||||
</a>
|
||||
<span class="global-search-item-count">{{ item.count }} results</span>
|
||||
</template>
|
||||
<a-input-search size="large" placeholder="input here" enter-button></a-input-search>
|
||||
</a-auto-complete>
|
||||
|
@ -49,6 +48,7 @@ import { defineComponent, ref } from 'vue';
|
|||
interface Option {
|
||||
query: string;
|
||||
category: string;
|
||||
value: string;
|
||||
count: number;
|
||||
}
|
||||
export default defineComponent({
|
||||
|
@ -67,9 +67,10 @@ export default defineComponent({
|
|||
return new Array(getRandomInt(5))
|
||||
.join('.')
|
||||
.split('.')
|
||||
.map((item, idx) => ({
|
||||
.map((_item, idx) => ({
|
||||
query,
|
||||
category: `${query}${idx}`,
|
||||
value: `${query}${idx}`,
|
||||
count: getRandomInt(200, 100),
|
||||
}));
|
||||
};
|
||||
|
|
|
@ -25,6 +25,7 @@ When there is a need for autocomplete functionality.
|
|||
| backfill | backfill selected item the input when using keyboard | boolean | false | |
|
||||
| #default (for customize input element) | customize input element | HTMLInputElement / HTMLTextAreaElement | `<Input />` | |
|
||||
| options | Data source for autocomplete | slot \| [DataSourceItemType](https://github.com/vueComponent/ant-design-vue/blob/724d53b907e577cf5880c1e6742d4c3f924f8f49/components/auto-complete/index.vue#L9)\[] | | |
|
||||
| option | custom render option by slot | v-slot:option="{value, label, [disabled, key, title]}" | - | 3.0 |
|
||||
| dropdownMenuStyle | additional style applied to dropdown menu | object | | 1.5.0 |
|
||||
| defaultActiveFirstOption | Whether active first option by default | boolean | true | |
|
||||
| disabled | Whether disabled select | boolean | false | |
|
||||
|
@ -38,7 +39,7 @@ When there is a need for autocomplete functionality.
|
|||
### events
|
||||
|
||||
| Events Name | Description | Arguments | Version |
|
||||
| --- | --- | --- | --- |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| change | Called when select an option or input value change, or value of input is changed | function(value) | |
|
||||
| blur | Called when leaving the component. | function() | |
|
||||
| focus | Called when entering the component | function() | |
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import type { App, Plugin, VNode, ExtractPropTypes } from 'vue';
|
||||
import { defineComponent, inject, provide } from 'vue';
|
||||
import Select, { selectProps } from '../select';
|
||||
import Input from '../input';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import { defaultConfigProvider } from '../config-provider';
|
||||
import { getComponent, getOptionProps, isValidElement, getSlot } from '../_util/props-util';
|
||||
|
@ -44,6 +43,7 @@ const AutoComplete = defineComponent({
|
|||
defaultActiveFirstOption: PropTypes.looseBool.def(true),
|
||||
},
|
||||
emits: ['change', 'select', 'focus', 'blur'],
|
||||
slots: ['option'],
|
||||
Option,
|
||||
OptGroup,
|
||||
setup(props, { slots }) {
|
||||
|
@ -70,7 +70,7 @@ const AutoComplete = defineComponent({
|
|||
},
|
||||
getInputElement() {
|
||||
const children = getSlot(this);
|
||||
const element = children.length ? children[0] : <Input lazy={false} />;
|
||||
const element = children.length ? children[0] : undefined;
|
||||
return element;
|
||||
},
|
||||
|
||||
|
@ -144,7 +144,11 @@ const AutoComplete = defineComponent({
|
|||
class: cls,
|
||||
ref: this.saveSelect,
|
||||
};
|
||||
return <Select {...selectProps}>{optionChildren}</Select>;
|
||||
return (
|
||||
<Select {...selectProps} v-slots={{ option: this.$slots.option }}>
|
||||
{optionChildren}
|
||||
</Select>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/qtJm4yt45/AutoComplete.svg
|
|||
| backfill | 使用键盘选择选项的时候把选中项回填到输入框中 | boolean | false | |
|
||||
| #default (自定义输入框) | 自定义输入框 | HTMLInputElement / HTMLTextAreaElement | `<Input />` | |
|
||||
| options | 自动完成的数据源 | slot \| [DataSourceItemType](https://github.com/vueComponent/ant-design-vue/blob/724d53b907e577cf5880c1e6742d4c3f924f8f49/components/auto-complete/index.vue#L9)\[] | | |
|
||||
| option | 通过 option 插槽,自定义节点 | v-slot:option="{value, label, [disabled, key, title]}" | - | 3.0 |
|
||||
| dropdownMenuStyle | dropdown 菜单自定义样式 | object | | 1.5.0 |
|
||||
| defaultActiveFirstOption | 是否默认高亮第一个选项。 | boolean | true | |
|
||||
| disabled | 是否禁用 | boolean | false | |
|
||||
|
|
|
@ -63,10 +63,10 @@ exports[`renders ./components/input/demo/group.vue correctly 1`] = `
|
|||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="down" class="anticon anticon-down ant-select-suffix"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!---->
|
||||
</div>
|
||||
<div style="width: 200px;" class="ant-select ant-select-show-search ant-select-auto-complete ant-select-single ant-select-customize-input ant-select-show-search">
|
||||
<div style="width: 200px;" class="ant-select ant-select-show-search ant-select-auto-complete ant-select-single ant-select-show-search">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" type="search" autocomplete="off" class="ant-input ant-select-selection-search-input" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" aria-activedescendant="rc_select_TEST_OR_SSR_list_0"></span>
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" aria-activedescendant="rc_select_TEST_OR_SSR_list_0" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder">Email</span>
|
||||
</div>
|
||||
<!---->
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// debugger tsx
|
||||
import Demo from '../../components/form/demo/customized-form-controls.vue';
|
||||
import Demo from '../../components/auto-complete/demo/index.vue';
|
||||
|
||||
export default {
|
||||
render() {
|
||||
|
|
Loading…
Reference in New Issue