feat: select add fieldNames
parent
72e5afab9f
commit
741ec4c835
|
@ -1,17 +1,17 @@
|
||||||
import type { App, Plugin, ExtractPropTypes, PropType } from 'vue';
|
import type { App, Plugin, ExtractPropTypes, PropType, HTMLAttributes } from 'vue';
|
||||||
import { provide, defineComponent, ref, watch, computed, toRef } from 'vue';
|
import { provide, defineComponent, ref, watch, computed, toRef } from 'vue';
|
||||||
import PropTypes, { withUndefined } from '../_util/vue-types';
|
import PropTypes from '../_util/vue-types';
|
||||||
|
|
||||||
|
import type { SpinProps } from '../spin';
|
||||||
import Spin from '../spin';
|
import Spin from '../spin';
|
||||||
import type { PaginationConfig } from '../pagination';
|
import type { PaginationConfig } from '../pagination';
|
||||||
import Pagination, { paginationConfig } from '../pagination';
|
import Pagination from '../pagination';
|
||||||
import { Row } from '../grid';
|
import { Row } from '../grid';
|
||||||
|
|
||||||
import Item from './Item';
|
import Item from './Item';
|
||||||
import { flattenChildren } from '../_util/props-util';
|
import { flattenChildren } from '../_util/props-util';
|
||||||
import initDefaultProps from '../_util/props-util/initDefaultProps';
|
import initDefaultProps from '../_util/props-util/initDefaultProps';
|
||||||
import type { Key } from '../_util/type';
|
import type { Key } from '../_util/type';
|
||||||
import { tuple } from '../_util/type';
|
|
||||||
import ItemMeta from './ItemMeta';
|
import ItemMeta from './ItemMeta';
|
||||||
import useConfigInject from '../_util/hooks/useConfigInject';
|
import useConfigInject from '../_util/hooks/useConfigInject';
|
||||||
import useBreakpoint from '../_util/hooks/useBreakpoint';
|
import useBreakpoint from '../_util/hooks/useBreakpoint';
|
||||||
|
@ -36,41 +36,41 @@ export interface ListGridType {
|
||||||
xxxl?: ColumnCount;
|
xxxl?: ColumnCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ListSize = tuple('small', 'default', 'large');
|
export type ListSize = 'small' | 'default' | 'large';
|
||||||
|
|
||||||
export type ListItemLayout = 'horizontal' | 'vertical';
|
export type ListItemLayout = 'horizontal' | 'vertical';
|
||||||
|
|
||||||
export const listProps = {
|
export const listProps = () => ({
|
||||||
bordered: PropTypes.looseBool,
|
bordered: PropTypes.looseBool,
|
||||||
dataSource: PropTypes.array,
|
dataSource: PropTypes.array,
|
||||||
extra: PropTypes.any,
|
extra: PropTypes.any,
|
||||||
grid: { type: Object as PropType<ListGridType>, default: undefined },
|
grid: { type: Object as PropType<ListGridType>, default: undefined },
|
||||||
itemLayout: PropTypes.oneOf(tuple('horizontal', 'vertical')),
|
itemLayout: String as PropType<ListItemLayout>,
|
||||||
loading: withUndefined(PropTypes.oneOfType([PropTypes.looseBool, PropTypes.object])),
|
loading: {
|
||||||
|
type: [Boolean, Object] as PropType<boolean | (SpinProps & HTMLAttributes)>,
|
||||||
|
default: undefined as boolean | (SpinProps & HTMLAttributes),
|
||||||
|
},
|
||||||
loadMore: PropTypes.any,
|
loadMore: PropTypes.any,
|
||||||
pagination: withUndefined(
|
pagination: {
|
||||||
PropTypes.oneOfType([
|
type: [Boolean, Object] as PropType<false | PaginationConfig>,
|
||||||
PropTypes.shape<PaginationConfig>(paginationConfig()).loose,
|
default: undefined as false | PaginationConfig,
|
||||||
PropTypes.looseBool,
|
},
|
||||||
]),
|
prefixCls: String,
|
||||||
),
|
|
||||||
prefixCls: PropTypes.string,
|
|
||||||
rowKey: [String, Number, Function] as PropType<Key | ((item: any) => Key)>,
|
rowKey: [String, Number, Function] as PropType<Key | ((item: any) => Key)>,
|
||||||
renderItem: PropTypes.any,
|
renderItem: PropTypes.any,
|
||||||
size: PropTypes.oneOf(ListSize),
|
size: String as PropType<ListSize>,
|
||||||
split: PropTypes.looseBool,
|
split: PropTypes.looseBool,
|
||||||
header: PropTypes.any,
|
header: PropTypes.any,
|
||||||
footer: PropTypes.any,
|
footer: PropTypes.any,
|
||||||
locale: {
|
locale: {
|
||||||
type: Object as PropType<ListLocale>,
|
type: Object as PropType<ListLocale>,
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
|
|
||||||
export interface ListLocale {
|
export interface ListLocale {
|
||||||
emptyText: any;
|
emptyText: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ListProps = Partial<ExtractPropTypes<typeof listProps>>;
|
export type ListProps = Partial<ExtractPropTypes<ReturnType<typeof listProps>>>;
|
||||||
|
|
||||||
import { ListContextKey } from './contextKey';
|
import { ListContextKey } from './contextKey';
|
||||||
import type { RenderEmptyHandler } from '../config-provider/renderEmpty';
|
import type { RenderEmptyHandler } from '../config-provider/renderEmpty';
|
||||||
|
@ -78,7 +78,7 @@ import type { RenderEmptyHandler } from '../config-provider/renderEmpty';
|
||||||
const List = defineComponent({
|
const List = defineComponent({
|
||||||
name: 'AList',
|
name: 'AList',
|
||||||
Item,
|
Item,
|
||||||
props: initDefaultProps(listProps, {
|
props: initDefaultProps(listProps(), {
|
||||||
dataSource: [],
|
dataSource: [],
|
||||||
bordered: false,
|
bordered: false,
|
||||||
split: true,
|
split: true,
|
||||||
|
|
|
@ -153,6 +153,17 @@ exports[`renders ./components/select/demo/custom-dropdown-menu.vue correctly 1`]
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`renders ./components/select/demo/field-names.vue correctly 1`] = `
|
||||||
|
<div style="width: 120px;" class="ant-select ant-select-single ant-select-show-arrow">
|
||||||
|
<!---->
|
||||||
|
<!---->
|
||||||
|
<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" style="opacity: 0;" 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" readonly="" unselectable="on" type="search"></span><span class="ant-select-selection-item" title="Lucy">Lucy</span>
|
||||||
|
<!---->
|
||||||
|
</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>
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`renders ./components/select/demo/hide-selected.vue correctly 1`] = `
|
exports[`renders ./components/select/demo/hide-selected.vue correctly 1`] = `
|
||||||
<div style="width: 100%;" class="ant-select ant-select-multiple ant-select-show-search">
|
<div style="width: 100%;" class="ant-select ant-select-multiple ant-select-show-search">
|
||||||
<!---->
|
<!---->
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
<docs>
|
||||||
|
---
|
||||||
|
order: 0
|
||||||
|
title:
|
||||||
|
zh-CN: 自定义 label、value、options 字段
|
||||||
|
en-US: Custom `label` `value` `options` field
|
||||||
|
---
|
||||||
|
|
||||||
|
## zh-CN
|
||||||
|
|
||||||
|
方便数据结构转换。
|
||||||
|
|
||||||
|
仅支持 options 传递,不支持 a-select-option 构造节点。
|
||||||
|
|
||||||
|
## en-US
|
||||||
|
|
||||||
|
Easy data structure conversion.
|
||||||
|
|
||||||
|
Only options passing is supported, a-select-option construction node is not supported.
|
||||||
|
|
||||||
|
</docs>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<a-select
|
||||||
|
ref="select"
|
||||||
|
v-model:value="value"
|
||||||
|
style="width: 120px"
|
||||||
|
:options="options"
|
||||||
|
:field-names="{ label: 'name', value: 'id', options: 'children' }"
|
||||||
|
@focus="focus"
|
||||||
|
@change="handleChange"
|
||||||
|
></a-select>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import type { SelectProps } from 'ant-design-vue';
|
||||||
|
import { defineComponent, ref } from 'vue';
|
||||||
|
export default defineComponent({
|
||||||
|
setup() {
|
||||||
|
const options = ref<SelectProps['options']>([
|
||||||
|
{
|
||||||
|
id: 'jack',
|
||||||
|
name: 'Jack',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: 'small jack',
|
||||||
|
name: 'samll Jack',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'lucy',
|
||||||
|
name: 'Lucy',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'disabled',
|
||||||
|
name: 'Disabled',
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'yiminghe',
|
||||||
|
name: 'Yiminghe',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const focus = () => {
|
||||||
|
console.log('focus');
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleChange = (value: string) => {
|
||||||
|
console.log(`selected ${value}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
focus,
|
||||||
|
handleChange,
|
||||||
|
value: ref('lucy'),
|
||||||
|
options,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -17,6 +17,7 @@
|
||||||
<CustomDropdownMenu />
|
<CustomDropdownMenu />
|
||||||
<OptionLabelProp />
|
<OptionLabelProp />
|
||||||
<BigData />
|
<BigData />
|
||||||
|
<fieldNamesVue />
|
||||||
</demo-sort>
|
</demo-sort>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
@ -37,6 +38,7 @@ import CustomDropdownMenu from './custom-dropdown-menu.vue';
|
||||||
import OptionLabelProp from './option-label-prop.vue';
|
import OptionLabelProp from './option-label-prop.vue';
|
||||||
import BigData from './big-data.vue';
|
import BigData from './big-data.vue';
|
||||||
import Responsive from './responsive.vue';
|
import Responsive from './responsive.vue';
|
||||||
|
import fieldNamesVue from './field-names.vue';
|
||||||
import CN from '../index.zh-CN.md';
|
import CN from '../index.zh-CN.md';
|
||||||
import US from '../index.en-US.md';
|
import US from '../index.en-US.md';
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
@ -44,6 +46,7 @@ export default defineComponent({
|
||||||
CN,
|
CN,
|
||||||
US,
|
US,
|
||||||
components: {
|
components: {
|
||||||
|
fieldNamesVue,
|
||||||
Basic,
|
Basic,
|
||||||
Size,
|
Size,
|
||||||
Tags,
|
Tags,
|
||||||
|
|
|
@ -35,6 +35,7 @@ Select component to select value from options.
|
||||||
| dropdownRender | Customize dropdown content | ({menuNode: VNode, props}) => VNode \| v-slot | - | |
|
| dropdownRender | Customize dropdown content | ({menuNode: VNode, props}) => VNode \| v-slot | - | |
|
||||||
| dropdownStyle | style of dropdown menu | object | - | |
|
| dropdownStyle | style of dropdown menu | object | - | |
|
||||||
| dropdownMenuStyle | additional style applied to dropdown menu | object | - | |
|
| dropdownMenuStyle | additional style applied to dropdown menu | object | - | |
|
||||||
|
| fieldNames | Customize node label, value, options field name | object | { label: `label`, value: `value`, options: `options` } | 3.0 |
|
||||||
| filterOption | If true, filter options by input, if function, filter options against it. The function will receive two arguments, `inputValue` and `option`, if the function returns `true`, the option will be included in the filtered set; Otherwise, it will be excluded. | boolean or function(inputValue, option) | true | |
|
| filterOption | If true, filter options by input, if function, filter options against it. The function will receive two arguments, `inputValue` and `option`, if the function returns `true`, the option will be included in the filtered set; Otherwise, it will be excluded. | boolean or function(inputValue, option) | true | |
|
||||||
| firstActiveValue | Value of action option by default | string\|string\[] | - | |
|
| firstActiveValue | Value of action option by default | string\|string\[] | - | |
|
||||||
| getPopupContainer | Parent Node which the selector should be rendered to. Default to `body`. When position issues happen, try to modify it into scrollable content and position it relative. | function(triggerNode) | () => document.body | |
|
| getPopupContainer | Parent Node which the selector should be rendered to. Default to `body`. When position issues happen, try to modify it into scrollable content and position it relative. | function(triggerNode) | () => document.body | |
|
||||||
|
|
|
@ -27,7 +27,13 @@ export interface LabeledValue {
|
||||||
export type SelectValue = RawValue | RawValue[] | LabeledValue | LabeledValue[] | undefined;
|
export type SelectValue = RawValue | RawValue[] | LabeledValue | LabeledValue[] | undefined;
|
||||||
|
|
||||||
export const selectProps = () => ({
|
export const selectProps = () => ({
|
||||||
...omit(vcSelectProps<SelectValue>(), ['inputIcon', 'mode', 'getInputElement', 'backfill']),
|
...omit(vcSelectProps<SelectValue>(), [
|
||||||
|
'inputIcon',
|
||||||
|
'mode',
|
||||||
|
'getInputElement',
|
||||||
|
'getRawInputElement',
|
||||||
|
'backfill',
|
||||||
|
]),
|
||||||
value: {
|
value: {
|
||||||
type: [Array, Object, String, Number] as PropType<SelectValue>,
|
type: [Array, Object, String, Number] as PropType<SelectValue>,
|
||||||
},
|
},
|
||||||
|
|
|
@ -36,6 +36,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/_0XzgOis7/Select.svg
|
||||||
| dropdownRender | 自定义下拉框内容 | ({menuNode: VNode, props}) => VNode \| v-slot | - | |
|
| dropdownRender | 自定义下拉框内容 | ({menuNode: VNode, props}) => VNode \| v-slot | - | |
|
||||||
| dropdownStyle | 下拉菜单的 style 属性 | object | - | |
|
| dropdownStyle | 下拉菜单的 style 属性 | object | - | |
|
||||||
| dropdownMenuStyle | dropdown 菜单自定义样式 | object | - | |
|
| dropdownMenuStyle | dropdown 菜单自定义样式 | object | - | |
|
||||||
|
| fieldNames | 自定义节点 label、value、options 的字段 | object | { label: `label`, value: `value`, options: `options` } | 3.0 |
|
||||||
| filterOption | 是否根据输入项进行筛选。当其为一个函数时,会接收 `inputValue` `option` 两个参数,当 `option` 符合筛选条件时,应返回 `true`,反之则返回 `false`。 | boolean or function(inputValue, option) | true | |
|
| filterOption | 是否根据输入项进行筛选。当其为一个函数时,会接收 `inputValue` `option` 两个参数,当 `option` 符合筛选条件时,应返回 `true`,反之则返回 `false`。 | boolean or function(inputValue, option) | true | |
|
||||||
| firstActiveValue | 默认高亮的选项 | string\|string\[] | - | |
|
| firstActiveValue | 默认高亮的选项 | string\|string\[] | - | |
|
||||||
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。 | Function(triggerNode) | () => document.body | |
|
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。 | Function(triggerNode) | () => document.body | |
|
||||||
|
|
|
@ -193,6 +193,7 @@
|
||||||
"prettier": "^2.2.0",
|
"prettier": "^2.2.0",
|
||||||
"pretty-quick": "^3.0.0",
|
"pretty-quick": "^3.0.0",
|
||||||
"prismjs": "^1.23.0",
|
"prismjs": "^1.23.0",
|
||||||
|
"qs": "^6.10.3",
|
||||||
"query-string": "^7.0.1",
|
"query-string": "^7.0.1",
|
||||||
"querystring": "^0.2.0",
|
"querystring": "^0.2.0",
|
||||||
"raw-loader": "^4.0.2",
|
"raw-loader": "^4.0.2",
|
||||||
|
|
Loading…
Reference in New Issue