refactor: select by vc-select2
parent
f3c12b0323
commit
4d63b7cab6
|
@ -1,6 +1,6 @@
|
|||
import { App, defineComponent, inject, provide } from 'vue';
|
||||
import { Option, OptGroup } from '../vc-select';
|
||||
import Select, { AbstractSelectProps, SelectValue } from '../select';
|
||||
import Select, { SelectProps } from '../select';
|
||||
import Input from '../input';
|
||||
import InputElement from './InputElement';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
|
@ -12,9 +12,7 @@ function isSelectOptionOrSelectOptGroup(child: any): Boolean {
|
|||
}
|
||||
|
||||
const AutoCompleteProps = {
|
||||
...AbstractSelectProps(),
|
||||
value: SelectValue,
|
||||
defaultValue: SelectValue,
|
||||
...SelectProps,
|
||||
dataSource: PropTypes.array,
|
||||
dropdownMenuStyle: PropTypes.style,
|
||||
optionLabelProp: PropTypes.string,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { inject } from 'vue';
|
||||
import { inject, VNodeChild } from 'vue';
|
||||
import Empty from '../empty';
|
||||
import { defaultConfigProvider } from '.';
|
||||
|
||||
|
@ -30,7 +30,7 @@ const RenderEmpty = (props: RenderEmptyProps) => {
|
|||
return renderHtml(props.componentName);
|
||||
};
|
||||
|
||||
function renderEmpty(componentName?: string) {
|
||||
function renderEmpty(componentName?: string): VNodeChild | JSX.Element{
|
||||
return <RenderEmpty componentName={componentName} />;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,268 +1,204 @@
|
|||
import { provide, inject, defineComponent, App } from 'vue';
|
||||
import warning from '../_util/warning';
|
||||
import omit from 'omit.js';
|
||||
import PropTypes, { withUndefined } from '../_util/vue-types';
|
||||
import { Select as VcSelect, Option, OptGroup } from '../vc-select';
|
||||
import classNames from '../_util/classNames';
|
||||
import RcSelect, { Option, OptGroup, SelectProps as RcSelectProps, props } from '../vc-select2';
|
||||
import { OptionProps } from '../vc-select2/Option';
|
||||
import { defaultConfigProvider } from '../config-provider';
|
||||
import { getComponent, getOptionProps, isValidElement, getSlot } from '../_util/props-util';
|
||||
import CloseOutlined from '@ant-design/icons-vue/CloseOutlined';
|
||||
import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled';
|
||||
import CheckOutlined from '@ant-design/icons-vue/CheckOutlined';
|
||||
import DownOutlined from '@ant-design/icons-vue/DownOutlined';
|
||||
import LoadingOutlined from '@ant-design/icons-vue/LoadingOutlined';
|
||||
import { cloneElement } from '../_util/vnode';
|
||||
import getIcons from './utils/iconUtil';
|
||||
import { computed, defineComponent, inject, ref, VNodeChild, App, PropType } from 'vue';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import { tuple } from '../_util/type';
|
||||
|
||||
const AbstractSelectProps = () => ({
|
||||
prefixCls: PropTypes.string,
|
||||
size: PropTypes.oneOf(['small', 'large', 'default']),
|
||||
showAction: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(String)]),
|
||||
notFoundContent: PropTypes.VNodeChild,
|
||||
transitionName: PropTypes.string,
|
||||
choiceTransitionName: PropTypes.string,
|
||||
showSearch: PropTypes.looseBool,
|
||||
allowClear: PropTypes.looseBool,
|
||||
disabled: PropTypes.looseBool,
|
||||
tabindex: PropTypes.number,
|
||||
placeholder: PropTypes.VNodeChild,
|
||||
defaultActiveFirstOption: PropTypes.looseBool,
|
||||
dropdownClassName: PropTypes.string,
|
||||
dropdownStyle: PropTypes.style,
|
||||
dropdownMenuStyle: PropTypes.style,
|
||||
dropdownMatchSelectWidth: PropTypes.looseBool,
|
||||
// onSearch: (value: string) => any,
|
||||
filterOption: withUndefined(PropTypes.oneOfType([PropTypes.looseBool, PropTypes.func])),
|
||||
autofocus: PropTypes.looseBool,
|
||||
backfill: PropTypes.looseBool,
|
||||
showArrow: PropTypes.looseBool,
|
||||
getPopupContainer: PropTypes.func,
|
||||
open: PropTypes.looseBool,
|
||||
defaultOpen: PropTypes.looseBool,
|
||||
autoClearSearchValue: PropTypes.looseBool,
|
||||
dropdownRender: PropTypes.func,
|
||||
onChange: PropTypes.func,
|
||||
loading: PropTypes.looseBool,
|
||||
});
|
||||
const Value = PropTypes.shape({
|
||||
key: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
}).loose;
|
||||
type RawValue = string | number;
|
||||
|
||||
const SelectValue = PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.number,
|
||||
PropTypes.arrayOf(PropTypes.oneOfType([Value, PropTypes.string, PropTypes.number])),
|
||||
Value,
|
||||
]);
|
||||
export { OptionProps };
|
||||
|
||||
const SelectProps = {
|
||||
...AbstractSelectProps(),
|
||||
value: SelectValue,
|
||||
defaultValue: SelectValue,
|
||||
// mode: PropTypes.oneOf(['default', 'multiple', 'tags', 'combobox']),
|
||||
mode: PropTypes.string,
|
||||
optionLabelProp: PropTypes.string,
|
||||
firstActiveValue: PropTypes.oneOfType([String, PropTypes.arrayOf(String)]),
|
||||
maxTagCount: PropTypes.number,
|
||||
maxTagPlaceholder: PropTypes.any,
|
||||
maxTagTextLength: PropTypes.number,
|
||||
dropdownMatchSelectWidth: PropTypes.looseBool,
|
||||
optionFilterProp: PropTypes.string,
|
||||
labelInValue: PropTypes.looseBool,
|
||||
getPopupContainer: PropTypes.func,
|
||||
tokenSeparators: PropTypes.arrayOf(PropTypes.string),
|
||||
getInputElement: PropTypes.func,
|
||||
options: PropTypes.array,
|
||||
suffixIcon: PropTypes.any,
|
||||
removeIcon: PropTypes.any,
|
||||
clearIcon: PropTypes.any,
|
||||
menuItemSelectedIcon: PropTypes.any,
|
||||
};
|
||||
export type OptionType = typeof Option;
|
||||
|
||||
const SelectPropTypes = {
|
||||
prefixCls: PropTypes.string,
|
||||
size: PropTypes.oneOf(['default', 'large', 'small']),
|
||||
// combobox: PropTypes.looseBool,
|
||||
notFoundContent: PropTypes.any,
|
||||
showSearch: PropTypes.looseBool,
|
||||
optionLabelProp: PropTypes.string,
|
||||
transitionName: PropTypes.string,
|
||||
choiceTransitionName: PropTypes.string,
|
||||
};
|
||||
export interface LabeledValue {
|
||||
key?: string;
|
||||
value: RawValue;
|
||||
label: VNodeChild;
|
||||
}
|
||||
export type SizeType = 'small' | 'middle' | 'large' | undefined;
|
||||
export type SelectValue = RawValue | RawValue[] | LabeledValue | LabeledValue[];
|
||||
|
||||
export interface InternalSelectProps<VT> extends Omit<RcSelectProps<VT>, 'mode'> {
|
||||
suffixIcon?: VNodeChild;
|
||||
itemIcon?: VNodeChild;
|
||||
size?: SizeType;
|
||||
mode?: 'multiple' | 'tags' | 'SECRET_COMBOBOX_MODE_DO_NOT_USE';
|
||||
bordered?: boolean;
|
||||
}
|
||||
|
||||
export interface SelectPropsTypes<VT>
|
||||
extends Omit<InternalSelectProps<VT>, 'inputIcon' | 'mode' | 'getInputElement' | 'backfill' | 'class' | 'style'> {
|
||||
mode?: 'multiple' | 'tags';
|
||||
}
|
||||
export type SelectTypes = SelectPropsTypes<SelectValue>
|
||||
export const SelectProps = {
|
||||
...omit(props, ['inputIcon' ,'mode' ,'getInputElement' ,'backfill' ,'class' ,'style']),
|
||||
value: {
|
||||
type: [Array, Object, String, Number] as PropType<SelectValue>
|
||||
},
|
||||
defaultValue: {
|
||||
type: [Array, Object, String, Number] as PropType<SelectValue>
|
||||
},
|
||||
suffixIcon: PropTypes.VNodeChild,
|
||||
itemIcon: PropTypes.VNodeChild,
|
||||
size: PropTypes.oneOf(tuple('small', 'middle', 'large', undefined, 'default')),
|
||||
mode: PropTypes.oneOf(tuple('multiple', 'tags')),
|
||||
bordered: PropTypes.looseBool.def(true),
|
||||
transitionName: PropTypes.string.def('slide-up'),
|
||||
choiceTransitionName: PropTypes.string.def(''),
|
||||
}
|
||||
|
||||
export { AbstractSelectProps, SelectValue, SelectProps };
|
||||
const SECRET_COMBOBOX_MODE_DO_NOT_USE = 'SECRET_COMBOBOX_MODE_DO_NOT_USE';
|
||||
const Select = defineComponent({
|
||||
SECRET_COMBOBOX_MODE_DO_NOT_USE,
|
||||
Option: { ...Option, name: 'ASelectOption' },
|
||||
OptGroup: { ...OptGroup, name: 'ASelectOptGroup' },
|
||||
name: 'ASelect',
|
||||
props: {
|
||||
...SelectProps,
|
||||
showSearch: PropTypes.looseBool.def(false),
|
||||
transitionName: PropTypes.string.def('slide-up'),
|
||||
choiceTransitionName: PropTypes.string.def('zoom'),
|
||||
},
|
||||
propTypes: SelectPropTypes,
|
||||
setup() {
|
||||
return {
|
||||
configProvider: inject('configProvider', defaultConfigProvider),
|
||||
popupRef: null,
|
||||
Option,
|
||||
OptGroup,
|
||||
inheritAttrs: false,
|
||||
props: SelectProps,
|
||||
SECRET_COMBOBOX_MODE_DO_NOT_USE: 'SECRET_COMBOBOX_MODE_DO_NOT_USE',
|
||||
emits: ['change', 'update:value'],
|
||||
setup(props: any, {attrs, emit}) {
|
||||
const selectRef = ref(null);
|
||||
|
||||
const configProvider = inject('configProvider', defaultConfigProvider);
|
||||
|
||||
const focus = () => {
|
||||
if (selectRef.value) {
|
||||
selectRef.value.focus();
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
provide('savePopupRef', this.savePopupRef);
|
||||
warning(
|
||||
this.$props.mode !== 'combobox',
|
||||
'Select',
|
||||
'The combobox mode of Select is deprecated,' +
|
||||
'it will be removed in next major version,' +
|
||||
'please use AutoComplete instead',
|
||||
);
|
||||
},
|
||||
methods: {
|
||||
getNotFoundContent(renderEmpty: any) {
|
||||
const notFoundContent = getComponent(this, 'notFoundContent');
|
||||
if (notFoundContent !== undefined) {
|
||||
return notFoundContent;
|
||||
}
|
||||
if (this.isCombobox()) {
|
||||
return null;
|
||||
}
|
||||
return renderEmpty('Select');
|
||||
},
|
||||
savePopupRef(ref) {
|
||||
this.popupRef = ref;
|
||||
},
|
||||
focus() {
|
||||
(this.$refs.vcSelect as any).focus();
|
||||
},
|
||||
blur() {
|
||||
(this.$refs.vcSelect as any).blur();
|
||||
},
|
||||
|
||||
isCombobox() {
|
||||
const { mode } = this;
|
||||
return mode === 'combobox' || mode === SECRET_COMBOBOX_MODE_DO_NOT_USE;
|
||||
},
|
||||
const blur = () => {
|
||||
if (selectRef.value) {
|
||||
selectRef.value.blur();
|
||||
}
|
||||
};
|
||||
|
||||
renderSuffixIcon(prefixCls) {
|
||||
const { loading } = this.$props;
|
||||
let suffixIcon = getComponent(this, 'suffixIcon');
|
||||
suffixIcon = Array.isArray(suffixIcon) ? suffixIcon[0] : suffixIcon;
|
||||
if (suffixIcon) {
|
||||
return isValidElement(suffixIcon)
|
||||
? cloneElement(suffixIcon, { class: `${prefixCls}-arrow-icon` })
|
||||
: suffixIcon;
|
||||
const mode = computed(()=>{
|
||||
const { mode } = props
|
||||
|
||||
if ((mode as any) === 'combobox') {
|
||||
return undefined;
|
||||
}
|
||||
if (loading) {
|
||||
return <LoadingOutlined />;
|
||||
|
||||
if (mode === Select.SECRET_COMBOBOX_MODE_DO_NOT_USE) {
|
||||
return 'combobox';
|
||||
}
|
||||
return <DownOutlined class={`${prefixCls}-arrow-icon`} />;
|
||||
},
|
||||
|
||||
return mode;
|
||||
});
|
||||
|
||||
const mergedClassName = computed(()=> classNames(
|
||||
{
|
||||
[`${props.prefixCls}-lg`]: props.size === 'large',
|
||||
[`${props.prefixCls}-sm`]: props.size === 'small',
|
||||
[`${props.prefixCls}-rtl`]: props.direction === 'rtl',
|
||||
[`${props.prefixCls}-borderless`]: !props.bordered,
|
||||
},
|
||||
attrs.class,
|
||||
));
|
||||
const triggerChange=(...args: any[])=>{
|
||||
console.log(args)
|
||||
emit('update:value', ...args)
|
||||
emit('change', ...args)
|
||||
}
|
||||
return {
|
||||
mergedClassName,
|
||||
mode,
|
||||
focus,
|
||||
blur,
|
||||
configProvider,
|
||||
triggerChange
|
||||
}
|
||||
},
|
||||
render() {
|
||||
const {configProvider, mode, mergedClassName,triggerChange, $slots: slots, $props} = this as any;
|
||||
const props: SelectTypes = $props
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
size,
|
||||
mode,
|
||||
options,
|
||||
notFoundContent,
|
||||
listHeight = 256,
|
||||
listItemHeight = 24,
|
||||
getPopupContainer,
|
||||
showArrow,
|
||||
...restProps
|
||||
} = getOptionProps(this);
|
||||
const { class: className } = this.$attrs as any;
|
||||
dropdownClassName,
|
||||
direction,
|
||||
virtual,
|
||||
dropdownMatchSelectWidth
|
||||
} = props;
|
||||
|
||||
const getPrefixCls = this.configProvider.getPrefixCls;
|
||||
const renderEmpty = this.configProvider.renderEmpty;
|
||||
const { getPrefixCls, renderEmpty, getPopupContainer: getContextPopupContainer } = configProvider
|
||||
const prefixCls = getPrefixCls('select', customizePrefixCls);
|
||||
|
||||
const { getPopupContainer: getContextPopupContainer } = this.configProvider;
|
||||
let removeIcon = getComponent(this, 'removeIcon');
|
||||
removeIcon = Array.isArray(removeIcon) ? removeIcon[0] : removeIcon;
|
||||
let clearIcon = getComponent(this, 'clearIcon');
|
||||
clearIcon = Array.isArray(clearIcon) ? clearIcon[0] : clearIcon;
|
||||
let menuItemSelectedIcon = getComponent(this, 'menuItemSelectedIcon');
|
||||
menuItemSelectedIcon = Array.isArray(menuItemSelectedIcon)
|
||||
? menuItemSelectedIcon[0]
|
||||
: menuItemSelectedIcon;
|
||||
const rest = omit(restProps as any, [
|
||||
'inputIcon',
|
||||
'removeIcon',
|
||||
'clearIcon',
|
||||
'suffixIcon',
|
||||
'menuItemSelectedIcon',
|
||||
]);
|
||||
const isMultiple = mode === 'multiple' || mode === 'tags';
|
||||
|
||||
const cls = {
|
||||
[className]: className,
|
||||
[`${prefixCls}-lg`]: size === 'large',
|
||||
[`${prefixCls}-sm`]: size === 'small',
|
||||
[`${prefixCls}-show-arrow`]: showArrow,
|
||||
};
|
||||
|
||||
let { optionLabelProp } = this.$props;
|
||||
if (this.isCombobox()) {
|
||||
// children 带 dom 结构时,无法填入输入框
|
||||
optionLabelProp = optionLabelProp || 'value';
|
||||
// ===================== Empty =====================
|
||||
let mergedNotFound: VNodeChild;
|
||||
if (notFoundContent !== undefined) {
|
||||
mergedNotFound = notFoundContent;
|
||||
} else if(slots.notFoundContent){
|
||||
mergedNotFound = slots.notFoundContent()
|
||||
} else if (mode === 'combobox') {
|
||||
mergedNotFound = null;
|
||||
} else {
|
||||
mergedNotFound = renderEmpty('Select') as any;
|
||||
}
|
||||
|
||||
const modeConfig = {
|
||||
multiple: mode === 'multiple',
|
||||
tags: mode === 'tags',
|
||||
combobox: this.isCombobox(),
|
||||
};
|
||||
const finalRemoveIcon = (removeIcon &&
|
||||
(isValidElement(removeIcon)
|
||||
? cloneElement(removeIcon, { class: `${prefixCls}-remove-icon` })
|
||||
: removeIcon)) || <CloseOutlined class={`${prefixCls}-remove-icon`} />;
|
||||
|
||||
const finalClearIcon = (clearIcon &&
|
||||
(isValidElement(clearIcon)
|
||||
? cloneElement(clearIcon, { class: `${prefixCls}-clear-icon` })
|
||||
: clearIcon)) || <CloseCircleFilled class={`${prefixCls}-clear-icon`} />;
|
||||
|
||||
const finalMenuItemSelectedIcon = (menuItemSelectedIcon &&
|
||||
(isValidElement(menuItemSelectedIcon)
|
||||
? cloneElement(menuItemSelectedIcon, { class: `${prefixCls}-selected-icon` })
|
||||
: menuItemSelectedIcon)) || <CheckOutlined class={`${prefixCls}-selected-icon`} />;
|
||||
|
||||
const selectProps = {
|
||||
inputIcon: this.renderSuffixIcon(prefixCls),
|
||||
removeIcon: finalRemoveIcon,
|
||||
clearIcon: finalClearIcon,
|
||||
menuItemSelectedIcon: finalMenuItemSelectedIcon,
|
||||
showArrow,
|
||||
...rest,
|
||||
...modeConfig,
|
||||
// ===================== Icons =====================
|
||||
const { suffixIcon, itemIcon, removeIcon, clearIcon } = getIcons({
|
||||
...this.$props,
|
||||
multiple: isMultiple,
|
||||
prefixCls,
|
||||
optionLabelProp: optionLabelProp || 'children',
|
||||
notFoundContent: this.getNotFoundContent(renderEmpty),
|
||||
maxTagPlaceholder: getComponent(this, 'maxTagPlaceholder'),
|
||||
placeholder: getComponent(this, 'placeholder'),
|
||||
children: options
|
||||
? options.map(option => {
|
||||
const { key, label = option.title, class: cls, style, ...restOption } = option;
|
||||
return (
|
||||
<Option key={key} {...{ class: cls, style, ...restOption }}>
|
||||
{label}
|
||||
</Option>
|
||||
);
|
||||
})
|
||||
: getSlot(this),
|
||||
dropdownRender: getComponent(this, 'dropdownRender', {}, false),
|
||||
getPopupContainer: getPopupContainer || getContextPopupContainer,
|
||||
...this.$attrs,
|
||||
class: cls,
|
||||
ref: 'vcSelect',
|
||||
};
|
||||
return <VcSelect {...selectProps} __propsSymbol__={[]} />;
|
||||
},
|
||||
});
|
||||
}, slots);
|
||||
|
||||
const selectProps = omit(props, [
|
||||
'prefixCls',
|
||||
'suffixIcon',
|
||||
'itemIcon',
|
||||
'removeIcon',
|
||||
'clearIcon',
|
||||
'size',
|
||||
'bordered',
|
||||
]) as any;
|
||||
|
||||
const rcSelectRtlDropDownClassName = classNames(dropdownClassName, {
|
||||
[`${prefixCls}-dropdown-${direction}`]: direction === 'rtl',
|
||||
});
|
||||
<RcSelect
|
||||
ref="selectRef"
|
||||
virtual={virtual}
|
||||
dropdownMatchSelectWidth={dropdownMatchSelectWidth}
|
||||
{...selectProps}
|
||||
listHeight={listHeight}
|
||||
listItemHeight={listItemHeight}
|
||||
mode={mode}
|
||||
prefixCls={prefixCls}
|
||||
direction={direction}
|
||||
inputIcon={suffixIcon}
|
||||
menuItemSelectedIcon={itemIcon}
|
||||
removeIcon={removeIcon}
|
||||
clearIcon={clearIcon}
|
||||
notFoundContent={mergedNotFound}
|
||||
class={mergedClassName}
|
||||
getPopupContainer={getPopupContainer || getContextPopupContainer}
|
||||
dropdownClassName={rcSelectRtlDropDownClassName}
|
||||
onChange={triggerChange}
|
||||
>
|
||||
{slots?.default()}
|
||||
</RcSelect>
|
||||
}
|
||||
})
|
||||
/* istanbul ignore next */
|
||||
Select.install = function(app: App) {
|
||||
app.component(Select.name, Select);
|
||||
app.component(Select.Option.name, Select.Option);
|
||||
app.component(Select.OptGroup.name, Select.OptGroup);
|
||||
app.component('ASelectOption', Select.Option);
|
||||
app.component('ASelectOptGroup', Select.OptGroup);
|
||||
return app;
|
||||
};
|
||||
export default Select;
|
||||
export default Select as typeof Select & {
|
||||
readonly Option: typeof Option;
|
||||
readonly OptGroup: typeof OptGroup;
|
||||
SECRET_COMBOBOX_MODE_DO_NOT_USE: 'SECRET_COMBOBOX_MODE_DO_NOT_USE';
|
||||
};
|
||||
|
|
|
@ -0,0 +1,268 @@
|
|||
import { provide, inject, defineComponent, App } from 'vue';
|
||||
import warning from '../_util/warning';
|
||||
import omit from 'omit.js';
|
||||
import PropTypes, { withUndefined } from '../_util/vue-types';
|
||||
import { Select as VcSelect, Option, OptGroup } from '../vc-select';
|
||||
import { defaultConfigProvider } from '../config-provider';
|
||||
import { getComponent, getOptionProps, isValidElement, getSlot } from '../_util/props-util';
|
||||
import CloseOutlined from '@ant-design/icons-vue/CloseOutlined';
|
||||
import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled';
|
||||
import CheckOutlined from '@ant-design/icons-vue/CheckOutlined';
|
||||
import DownOutlined from '@ant-design/icons-vue/DownOutlined';
|
||||
import LoadingOutlined from '@ant-design/icons-vue/LoadingOutlined';
|
||||
import { cloneElement } from '../_util/vnode';
|
||||
|
||||
const AbstractSelectProps = () => ({
|
||||
prefixCls: PropTypes.string,
|
||||
size: PropTypes.oneOf(['small', 'large', 'default']),
|
||||
showAction: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(String)]),
|
||||
notFoundContent: PropTypes.VNodeChild,
|
||||
transitionName: PropTypes.string,
|
||||
choiceTransitionName: PropTypes.string,
|
||||
showSearch: PropTypes.looseBool,
|
||||
allowClear: PropTypes.looseBool,
|
||||
disabled: PropTypes.looseBool,
|
||||
tabindex: PropTypes.number,
|
||||
placeholder: PropTypes.VNodeChild,
|
||||
defaultActiveFirstOption: PropTypes.looseBool,
|
||||
dropdownClassName: PropTypes.string,
|
||||
dropdownStyle: PropTypes.style,
|
||||
dropdownMenuStyle: PropTypes.style,
|
||||
dropdownMatchSelectWidth: PropTypes.looseBool,
|
||||
// onSearch: (value: string) => any,
|
||||
filterOption: withUndefined(PropTypes.oneOfType([PropTypes.looseBool, PropTypes.func])),
|
||||
autofocus: PropTypes.looseBool,
|
||||
backfill: PropTypes.looseBool,
|
||||
showArrow: PropTypes.looseBool,
|
||||
getPopupContainer: PropTypes.func,
|
||||
open: PropTypes.looseBool,
|
||||
defaultOpen: PropTypes.looseBool,
|
||||
autoClearSearchValue: PropTypes.looseBool,
|
||||
dropdownRender: PropTypes.func,
|
||||
onChange: PropTypes.func,
|
||||
loading: PropTypes.looseBool,
|
||||
});
|
||||
const Value = PropTypes.shape({
|
||||
key: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
}).loose;
|
||||
|
||||
const SelectValue = PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.number,
|
||||
PropTypes.arrayOf(PropTypes.oneOfType([Value, PropTypes.string, PropTypes.number])),
|
||||
Value,
|
||||
]);
|
||||
|
||||
const SelectProps = {
|
||||
...AbstractSelectProps(),
|
||||
value: SelectValue,
|
||||
defaultValue: SelectValue,
|
||||
// mode: PropTypes.oneOf(['default', 'multiple', 'tags', 'combobox']),
|
||||
mode: PropTypes.string,
|
||||
optionLabelProp: PropTypes.string,
|
||||
firstActiveValue: PropTypes.oneOfType([String, PropTypes.arrayOf(String)]),
|
||||
maxTagCount: PropTypes.number,
|
||||
maxTagPlaceholder: PropTypes.any,
|
||||
maxTagTextLength: PropTypes.number,
|
||||
dropdownMatchSelectWidth: PropTypes.looseBool,
|
||||
optionFilterProp: PropTypes.string,
|
||||
labelInValue: PropTypes.looseBool,
|
||||
getPopupContainer: PropTypes.func,
|
||||
tokenSeparators: PropTypes.arrayOf(PropTypes.string),
|
||||
getInputElement: PropTypes.func,
|
||||
options: PropTypes.array,
|
||||
suffixIcon: PropTypes.any,
|
||||
removeIcon: PropTypes.any,
|
||||
clearIcon: PropTypes.any,
|
||||
menuItemSelectedIcon: PropTypes.any,
|
||||
};
|
||||
|
||||
const SelectPropTypes = {
|
||||
prefixCls: PropTypes.string,
|
||||
size: PropTypes.oneOf(['default', 'large', 'small']),
|
||||
// combobox: PropTypes.looseBool,
|
||||
notFoundContent: PropTypes.any,
|
||||
showSearch: PropTypes.looseBool,
|
||||
optionLabelProp: PropTypes.string,
|
||||
transitionName: PropTypes.string,
|
||||
choiceTransitionName: PropTypes.string,
|
||||
};
|
||||
|
||||
export { AbstractSelectProps, SelectValue, SelectProps };
|
||||
const SECRET_COMBOBOX_MODE_DO_NOT_USE = 'SECRET_COMBOBOX_MODE_DO_NOT_USE';
|
||||
const Select = defineComponent({
|
||||
SECRET_COMBOBOX_MODE_DO_NOT_USE,
|
||||
Option: { ...Option, name: 'ASelectOption' },
|
||||
OptGroup: { ...OptGroup, name: 'ASelectOptGroup' },
|
||||
name: 'ASelect',
|
||||
props: {
|
||||
...SelectProps,
|
||||
showSearch: PropTypes.looseBool.def(false),
|
||||
transitionName: PropTypes.string.def('slide-up'),
|
||||
choiceTransitionName: PropTypes.string.def('zoom'),
|
||||
},
|
||||
propTypes: SelectPropTypes,
|
||||
setup() {
|
||||
return {
|
||||
configProvider: inject('configProvider', defaultConfigProvider),
|
||||
popupRef: null,
|
||||
};
|
||||
},
|
||||
created() {
|
||||
provide('savePopupRef', this.savePopupRef);
|
||||
warning(
|
||||
this.$props.mode !== 'combobox',
|
||||
'Select',
|
||||
'The combobox mode of Select is deprecated,' +
|
||||
'it will be removed in next major version,' +
|
||||
'please use AutoComplete instead',
|
||||
);
|
||||
},
|
||||
methods: {
|
||||
getNotFoundContent(renderEmpty: any) {
|
||||
const notFoundContent = getComponent(this, 'notFoundContent');
|
||||
if (notFoundContent !== undefined) {
|
||||
return notFoundContent;
|
||||
}
|
||||
if (this.isCombobox()) {
|
||||
return null;
|
||||
}
|
||||
return renderEmpty('Select');
|
||||
},
|
||||
savePopupRef(ref) {
|
||||
this.popupRef = ref;
|
||||
},
|
||||
focus() {
|
||||
(this.$refs.vcSelect as any).focus();
|
||||
},
|
||||
blur() {
|
||||
(this.$refs.vcSelect as any).blur();
|
||||
},
|
||||
|
||||
isCombobox() {
|
||||
const { mode } = this;
|
||||
return mode === 'combobox' || mode === SECRET_COMBOBOX_MODE_DO_NOT_USE;
|
||||
},
|
||||
|
||||
renderSuffixIcon(prefixCls) {
|
||||
const { loading } = this.$props;
|
||||
let suffixIcon = getComponent(this, 'suffixIcon');
|
||||
suffixIcon = Array.isArray(suffixIcon) ? suffixIcon[0] : suffixIcon;
|
||||
if (suffixIcon) {
|
||||
return isValidElement(suffixIcon)
|
||||
? cloneElement(suffixIcon, { class: `${prefixCls}-arrow-icon` })
|
||||
: suffixIcon;
|
||||
}
|
||||
if (loading) {
|
||||
return <LoadingOutlined />;
|
||||
}
|
||||
return <DownOutlined class={`${prefixCls}-arrow-icon`} />;
|
||||
},
|
||||
},
|
||||
render() {
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
size,
|
||||
mode,
|
||||
options,
|
||||
getPopupContainer,
|
||||
showArrow,
|
||||
...restProps
|
||||
} = getOptionProps(this);
|
||||
const { class: className } = this.$attrs as any;
|
||||
|
||||
const getPrefixCls = this.configProvider.getPrefixCls;
|
||||
const renderEmpty = this.configProvider.renderEmpty;
|
||||
const prefixCls = getPrefixCls('select', customizePrefixCls);
|
||||
|
||||
const { getPopupContainer: getContextPopupContainer } = this.configProvider;
|
||||
let removeIcon = getComponent(this, 'removeIcon');
|
||||
removeIcon = Array.isArray(removeIcon) ? removeIcon[0] : removeIcon;
|
||||
let clearIcon = getComponent(this, 'clearIcon');
|
||||
clearIcon = Array.isArray(clearIcon) ? clearIcon[0] : clearIcon;
|
||||
let menuItemSelectedIcon = getComponent(this, 'menuItemSelectedIcon');
|
||||
menuItemSelectedIcon = Array.isArray(menuItemSelectedIcon)
|
||||
? menuItemSelectedIcon[0]
|
||||
: menuItemSelectedIcon;
|
||||
const rest = omit(restProps as any, [
|
||||
'inputIcon',
|
||||
'removeIcon',
|
||||
'clearIcon',
|
||||
'suffixIcon',
|
||||
'menuItemSelectedIcon',
|
||||
]);
|
||||
|
||||
const cls = {
|
||||
[className]: className,
|
||||
[`${prefixCls}-lg`]: size === 'large',
|
||||
[`${prefixCls}-sm`]: size === 'small',
|
||||
[`${prefixCls}-show-arrow`]: showArrow,
|
||||
};
|
||||
|
||||
let { optionLabelProp } = this.$props;
|
||||
if (this.isCombobox()) {
|
||||
// children 带 dom 结构时,无法填入输入框
|
||||
optionLabelProp = optionLabelProp || 'value';
|
||||
}
|
||||
|
||||
const modeConfig = {
|
||||
multiple: mode === 'multiple',
|
||||
tags: mode === 'tags',
|
||||
combobox: this.isCombobox(),
|
||||
};
|
||||
const finalRemoveIcon = (removeIcon &&
|
||||
(isValidElement(removeIcon)
|
||||
? cloneElement(removeIcon, { class: `${prefixCls}-remove-icon` })
|
||||
: removeIcon)) || <CloseOutlined class={`${prefixCls}-remove-icon`} />;
|
||||
|
||||
const finalClearIcon = (clearIcon &&
|
||||
(isValidElement(clearIcon)
|
||||
? cloneElement(clearIcon, { class: `${prefixCls}-clear-icon` })
|
||||
: clearIcon)) || <CloseCircleFilled class={`${prefixCls}-clear-icon`} />;
|
||||
|
||||
const finalMenuItemSelectedIcon = (menuItemSelectedIcon &&
|
||||
(isValidElement(menuItemSelectedIcon)
|
||||
? cloneElement(menuItemSelectedIcon, { class: `${prefixCls}-selected-icon` })
|
||||
: menuItemSelectedIcon)) || <CheckOutlined class={`${prefixCls}-selected-icon`} />;
|
||||
|
||||
const selectProps = {
|
||||
inputIcon: this.renderSuffixIcon(prefixCls),
|
||||
removeIcon: finalRemoveIcon,
|
||||
clearIcon: finalClearIcon,
|
||||
menuItemSelectedIcon: finalMenuItemSelectedIcon,
|
||||
showArrow,
|
||||
...rest,
|
||||
...modeConfig,
|
||||
prefixCls,
|
||||
optionLabelProp: optionLabelProp || 'children',
|
||||
notFoundContent: this.getNotFoundContent(renderEmpty),
|
||||
maxTagPlaceholder: getComponent(this, 'maxTagPlaceholder'),
|
||||
placeholder: getComponent(this, 'placeholder'),
|
||||
children: options
|
||||
? options.map(option => {
|
||||
const { key, label = option.title, class: cls, style, ...restOption } = option;
|
||||
return (
|
||||
<Option key={key} {...{ class: cls, style, ...restOption }}>
|
||||
{label}
|
||||
</Option>
|
||||
);
|
||||
})
|
||||
: getSlot(this),
|
||||
dropdownRender: getComponent(this, 'dropdownRender', {}, false),
|
||||
getPopupContainer: getPopupContainer || getContextPopupContainer,
|
||||
...this.$attrs,
|
||||
class: cls,
|
||||
ref: 'vcSelect',
|
||||
};
|
||||
return <VcSelect {...selectProps} __propsSymbol__={[]} />;
|
||||
},
|
||||
});
|
||||
|
||||
/* istanbul ignore next */
|
||||
Select.install = function(app: App) {
|
||||
app.component(Select.name, Select);
|
||||
app.component(Select.Option.name, Select.Option);
|
||||
app.component(Select.OptGroup.name, Select.OptGroup);
|
||||
return app;
|
||||
};
|
||||
export default Select;
|
|
@ -0,0 +1,64 @@
|
|||
|
||||
import DownOutlined from '@ant-design/icons-vue/DownOutlined';
|
||||
import LoadingOutlined from '@ant-design/icons-vue/LoadingOutlined';
|
||||
import CheckOutlined from '@ant-design/icons-vue/CheckOutlined';
|
||||
import CloseOutlined from '@ant-design/icons-vue/CloseOutlined';
|
||||
import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled';
|
||||
import SearchOutlined from '@ant-design/icons-vue/SearchOutlined';
|
||||
|
||||
export default function getIcons(props: any, slots: any = {}) {
|
||||
const {
|
||||
loading,
|
||||
multiple,
|
||||
prefixCls,
|
||||
} = props;
|
||||
const suffixIcon = props.suffixIcon || slots.suffixIcon && slots.suffixIcon();
|
||||
const clearIcon = props.clearIcon || slots.clearIcon && slots.clearIcon();
|
||||
const menuItemSelectedIcon = props.menuItemSelectedIcon || slots.menuItemSelectedIcon && slots.menuItemSelectedIcon();
|
||||
const removeIcon = props.removeIcon || slots.removeIcon && slots.removeIcon();
|
||||
// Clear Icon
|
||||
let mergedClearIcon = clearIcon;
|
||||
if (!clearIcon) {
|
||||
mergedClearIcon = <CloseCircleFilled />;
|
||||
}
|
||||
|
||||
// Arrow item icon
|
||||
let mergedSuffixIcon = null;
|
||||
if (suffixIcon !== undefined) {
|
||||
mergedSuffixIcon = suffixIcon;
|
||||
} else if (loading) {
|
||||
mergedSuffixIcon = <LoadingOutlined spin />;
|
||||
} else {
|
||||
const iconCls = `${prefixCls}-suffix`;
|
||||
mergedSuffixIcon = ({ open, showSearch }: { open: boolean; showSearch: boolean }) => {
|
||||
if (open && showSearch) {
|
||||
return <SearchOutlined class={iconCls} />;
|
||||
}
|
||||
return <DownOutlined class={iconCls} />;
|
||||
};
|
||||
}
|
||||
|
||||
// Checked item icon
|
||||
let mergedItemIcon = null;
|
||||
if (menuItemSelectedIcon !== undefined) {
|
||||
mergedItemIcon = menuItemSelectedIcon;
|
||||
} else if (multiple) {
|
||||
mergedItemIcon = <CheckOutlined />;
|
||||
} else {
|
||||
mergedItemIcon = null;
|
||||
}
|
||||
|
||||
let mergedRemoveIcon = null;
|
||||
if (removeIcon !== undefined) {
|
||||
mergedRemoveIcon = removeIcon;
|
||||
} else {
|
||||
mergedRemoveIcon = <CloseOutlined />;
|
||||
}
|
||||
|
||||
return {
|
||||
clearIcon: mergedClearIcon,
|
||||
suffixIcon: mergedSuffixIcon,
|
||||
itemIcon: mergedItemIcon,
|
||||
removeIcon: mergedRemoveIcon,
|
||||
};
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import PropTypes, { withUndefined } from '../_util/vue-types';
|
||||
import { AbstractSelectProps } from '../select';
|
||||
import { SelectProps } from '../select';
|
||||
|
||||
export const TreeData = PropTypes.shape({
|
||||
key: PropTypes.string,
|
||||
|
@ -10,7 +10,7 @@ export const TreeData = PropTypes.shape({
|
|||
}).loose;
|
||||
|
||||
export const TreeSelectProps = () => ({
|
||||
...AbstractSelectProps(),
|
||||
...SelectProps,
|
||||
autofocus: PropTypes.looseBool,
|
||||
dropdownStyle: PropTypes.object,
|
||||
filterTreeNode: withUndefined(PropTypes.oneOfType([Function, Boolean])),
|
||||
|
|
|
@ -65,6 +65,106 @@ const DEFAULT_OMIT_PROPS = [
|
|||
'onInputKeyDown',
|
||||
];
|
||||
|
||||
export const props = {
|
||||
prefixCls: PropTypes.string,
|
||||
id: PropTypes.string,
|
||||
class: PropTypes.string,
|
||||
style: PropTypes.any,
|
||||
|
||||
// Options
|
||||
options: PropTypes.array,
|
||||
children: PropTypes.array.def([]),
|
||||
mode: PropTypes.string,
|
||||
|
||||
// Value
|
||||
value: PropTypes.any,
|
||||
defaultValue: PropTypes.any,
|
||||
labelInValue: PropTypes.looseBool,
|
||||
|
||||
// Search
|
||||
inputValue: PropTypes.string,
|
||||
searchValue: PropTypes.string,
|
||||
optionFilterProp: PropTypes.string.def('value'),
|
||||
/**
|
||||
* In Select, `false` means do nothing.
|
||||
* In TreeSelect, `false` will highlight match item.
|
||||
* It's by design.
|
||||
*/
|
||||
filterOption: PropTypes.any,
|
||||
showSearch: PropTypes.looseBool,
|
||||
autoClearSearchValue: PropTypes.looseBool,
|
||||
onSearch: PropTypes.func,
|
||||
onClear: PropTypes.func,
|
||||
|
||||
// Icons
|
||||
allowClear: PropTypes.looseBool,
|
||||
clearIcon: PropTypes.any,
|
||||
showArrow: PropTypes.looseBool,
|
||||
inputIcon: PropTypes.any,
|
||||
removeIcon: PropTypes.any,
|
||||
menuItemSelectedIcon: PropTypes.func,
|
||||
|
||||
// Dropdown
|
||||
open: PropTypes.looseBool,
|
||||
defaultOpen: PropTypes.looseBool,
|
||||
listHeight: PropTypes.number.def(200),
|
||||
listItemHeight: PropTypes.number.def(20),
|
||||
dropdownStyle: PropTypes.object,
|
||||
dropdownClassName: PropTypes.string,
|
||||
dropdownMatchSelectWidth: PropTypes.oneOfType([Boolean, Number]).def(true),
|
||||
virtual: PropTypes.looseBool,
|
||||
dropdownRender: PropTypes.func,
|
||||
dropdownAlign: PropTypes.any,
|
||||
animation: PropTypes.string,
|
||||
transitionName: PropTypes.string,
|
||||
getPopupContainer: PropTypes.func,
|
||||
direction: PropTypes.string,
|
||||
|
||||
// Others
|
||||
disabled: PropTypes.looseBool,
|
||||
loading: PropTypes.looseBool,
|
||||
autofocus: PropTypes.looseBool,
|
||||
defaultActiveFirstOption: PropTypes.looseBool,
|
||||
notFoundContent: PropTypes.any.def('Not Found'),
|
||||
placeholder: PropTypes.any,
|
||||
backfill: PropTypes.looseBool,
|
||||
getInputElement: PropTypes.func,
|
||||
optionLabelProp: PropTypes.string,
|
||||
maxTagTextLength: PropTypes.number,
|
||||
maxTagCount: PropTypes.number,
|
||||
maxTagPlaceholder: PropTypes.any,
|
||||
tokenSeparators: PropTypes.array,
|
||||
tagRender: PropTypes.func,
|
||||
showAction: PropTypes.array.def([]),
|
||||
tabindex: PropTypes.number,
|
||||
|
||||
// Events
|
||||
onKeyup: PropTypes.func,
|
||||
onKeydown: PropTypes.func,
|
||||
onPopupScroll: PropTypes.func,
|
||||
onDropdownVisibleChange: PropTypes.func,
|
||||
onSelect: PropTypes.func,
|
||||
onDeselect: PropTypes.func,
|
||||
onInputKeyDown: PropTypes.func,
|
||||
onClick: PropTypes.func,
|
||||
onChange: PropTypes.func,
|
||||
onBlur: PropTypes.func,
|
||||
onFocus: PropTypes.func,
|
||||
onMousedown: PropTypes.func,
|
||||
onMouseenter: PropTypes.func,
|
||||
onMouseleave: PropTypes.func,
|
||||
|
||||
// Motion
|
||||
choiceTransitionName: PropTypes.string,
|
||||
|
||||
// Internal props
|
||||
/**
|
||||
* Only used in current version for internal event process.
|
||||
* Do not use in production environment.
|
||||
*/
|
||||
internalProps: PropTypes.object.def({}),
|
||||
}
|
||||
|
||||
export interface SelectProps<OptionsType extends object[], ValueType> {
|
||||
prefixCls?: string;
|
||||
id?: string;
|
||||
|
@ -1221,104 +1321,6 @@ export default function generateSelector<
|
|||
},
|
||||
});
|
||||
Select.inheritAttrs = false;
|
||||
Select.props = {
|
||||
prefixCls: PropTypes.string,
|
||||
id: PropTypes.string,
|
||||
class: PropTypes.string,
|
||||
style: PropTypes.any,
|
||||
|
||||
// Options
|
||||
options: PropTypes.array,
|
||||
children: PropTypes.array.def([]),
|
||||
mode: PropTypes.string,
|
||||
|
||||
// Value
|
||||
value: PropTypes.any,
|
||||
defaultValue: PropTypes.any,
|
||||
labelInValue: PropTypes.looseBool,
|
||||
|
||||
// Search
|
||||
inputValue: PropTypes.string,
|
||||
searchValue: PropTypes.string,
|
||||
optionFilterProp: PropTypes.string.def('value'),
|
||||
/**
|
||||
* In Select, `false` means do nothing.
|
||||
* In TreeSelect, `false` will highlight match item.
|
||||
* It's by design.
|
||||
*/
|
||||
filterOption: PropTypes.any,
|
||||
showSearch: PropTypes.looseBool,
|
||||
autoClearSearchValue: PropTypes.looseBool,
|
||||
onSearch: PropTypes.func,
|
||||
onClear: PropTypes.func,
|
||||
|
||||
// Icons
|
||||
allowClear: PropTypes.looseBool,
|
||||
clearIcon: PropTypes.any,
|
||||
showArrow: PropTypes.looseBool,
|
||||
inputIcon: PropTypes.any,
|
||||
removeIcon: PropTypes.any,
|
||||
menuItemSelectedIcon: PropTypes.func,
|
||||
|
||||
// Dropdown
|
||||
open: PropTypes.looseBool,
|
||||
defaultOpen: PropTypes.looseBool,
|
||||
listHeight: PropTypes.number.def(200),
|
||||
listItemHeight: PropTypes.number.def(20),
|
||||
dropdownStyle: PropTypes.object,
|
||||
dropdownClassName: PropTypes.string,
|
||||
dropdownMatchSelectWidth: PropTypes.oneOfType([Boolean, Number]).def(true),
|
||||
virtual: PropTypes.looseBool,
|
||||
dropdownRender: PropTypes.func,
|
||||
dropdownAlign: PropTypes.any,
|
||||
animation: PropTypes.string,
|
||||
transitionName: PropTypes.string,
|
||||
getPopupContainer: PropTypes.func,
|
||||
direction: PropTypes.string,
|
||||
|
||||
// Others
|
||||
disabled: PropTypes.looseBool,
|
||||
loading: PropTypes.looseBool,
|
||||
autofocus: PropTypes.looseBool,
|
||||
defaultActiveFirstOption: PropTypes.looseBool,
|
||||
notFoundContent: PropTypes.any.def('Not Found'),
|
||||
placeholder: PropTypes.any,
|
||||
backfill: PropTypes.looseBool,
|
||||
getInputElement: PropTypes.func,
|
||||
optionLabelProp: PropTypes.string,
|
||||
maxTagTextLength: PropTypes.number,
|
||||
maxTagCount: PropTypes.number,
|
||||
maxTagPlaceholder: PropTypes.any,
|
||||
tokenSeparators: PropTypes.array,
|
||||
tagRender: PropTypes.func,
|
||||
showAction: PropTypes.array.def([]),
|
||||
tabindex: PropTypes.number,
|
||||
|
||||
// Events
|
||||
onKeyup: PropTypes.func,
|
||||
onKeydown: PropTypes.func,
|
||||
onPopupScroll: PropTypes.func,
|
||||
onDropdownVisibleChange: PropTypes.func,
|
||||
onSelect: PropTypes.func,
|
||||
onDeselect: PropTypes.func,
|
||||
onInputKeyDown: PropTypes.func,
|
||||
onClick: PropTypes.func,
|
||||
onChange: PropTypes.func,
|
||||
onBlur: PropTypes.func,
|
||||
onFocus: PropTypes.func,
|
||||
onMousedown: PropTypes.func,
|
||||
onMouseenter: PropTypes.func,
|
||||
onMouseleave: PropTypes.func,
|
||||
|
||||
// Motion
|
||||
choiceTransitionName: PropTypes.string,
|
||||
|
||||
// Internal props
|
||||
/**
|
||||
* Only used in current version for internal event process.
|
||||
* Do not use in production environment.
|
||||
*/
|
||||
internalProps: PropTypes.object.def({}),
|
||||
};
|
||||
Select.props = props;
|
||||
return Select;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Select, { ExportedSelectProps } from './Select';
|
||||
import Select, { ExportedSelectProps as SelectProps } from './Select';
|
||||
import Option from './Option';
|
||||
import OptGroup from './OptGroup';
|
||||
type SelectProps = ExportedSelectProps;
|
||||
export { Option, OptGroup, SelectProps };
|
||||
import { props } from './generate';
|
||||
export { Option, OptGroup, SelectProps, props };
|
||||
|
||||
export default Select;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as Vue from 'vue';
|
||||
import { VNodeChild } from 'vue';
|
||||
|
||||
export type SelectSource = 'option' | 'selection' | 'input';
|
||||
|
||||
|
@ -12,7 +12,7 @@ export type RawValueType = string | number | null;
|
|||
export interface LabelValueType extends Record<string, any> {
|
||||
key?: Key;
|
||||
value?: RawValueType;
|
||||
label?: Vue.VNodeChild;
|
||||
label?: VNodeChild;
|
||||
}
|
||||
export type DefaultValueType = RawValueType | RawValueType[] | LabelValueType | LabelValueType[];
|
||||
|
||||
|
|
Loading…
Reference in New Issue