refactor: select by vc-select2
parent
f3c12b0323
commit
4d63b7cab6
|
@ -1,6 +1,6 @@
|
||||||
import { App, defineComponent, inject, provide } from 'vue';
|
import { App, defineComponent, inject, provide } from 'vue';
|
||||||
import { Option, OptGroup } from '../vc-select';
|
import { Option, OptGroup } from '../vc-select';
|
||||||
import Select, { AbstractSelectProps, SelectValue } from '../select';
|
import Select, { SelectProps } from '../select';
|
||||||
import Input from '../input';
|
import Input from '../input';
|
||||||
import InputElement from './InputElement';
|
import InputElement from './InputElement';
|
||||||
import PropTypes from '../_util/vue-types';
|
import PropTypes from '../_util/vue-types';
|
||||||
|
@ -12,9 +12,7 @@ function isSelectOptionOrSelectOptGroup(child: any): Boolean {
|
||||||
}
|
}
|
||||||
|
|
||||||
const AutoCompleteProps = {
|
const AutoCompleteProps = {
|
||||||
...AbstractSelectProps(),
|
...SelectProps,
|
||||||
value: SelectValue,
|
|
||||||
defaultValue: SelectValue,
|
|
||||||
dataSource: PropTypes.array,
|
dataSource: PropTypes.array,
|
||||||
dropdownMenuStyle: PropTypes.style,
|
dropdownMenuStyle: PropTypes.style,
|
||||||
optionLabelProp: PropTypes.string,
|
optionLabelProp: PropTypes.string,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { inject } from 'vue';
|
import { inject, VNodeChild } from 'vue';
|
||||||
import Empty from '../empty';
|
import Empty from '../empty';
|
||||||
import { defaultConfigProvider } from '.';
|
import { defaultConfigProvider } from '.';
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ const RenderEmpty = (props: RenderEmptyProps) => {
|
||||||
return renderHtml(props.componentName);
|
return renderHtml(props.componentName);
|
||||||
};
|
};
|
||||||
|
|
||||||
function renderEmpty(componentName?: string) {
|
function renderEmpty(componentName?: string): VNodeChild | JSX.Element{
|
||||||
return <RenderEmpty componentName={componentName} />;
|
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 omit from 'omit.js';
|
||||||
import PropTypes, { withUndefined } from '../_util/vue-types';
|
import classNames from '../_util/classNames';
|
||||||
import { Select as VcSelect, Option, OptGroup } from '../vc-select';
|
import RcSelect, { Option, OptGroup, SelectProps as RcSelectProps, props } from '../vc-select2';
|
||||||
|
import { OptionProps } from '../vc-select2/Option';
|
||||||
import { defaultConfigProvider } from '../config-provider';
|
import { defaultConfigProvider } from '../config-provider';
|
||||||
import { getComponent, getOptionProps, isValidElement, getSlot } from '../_util/props-util';
|
import getIcons from './utils/iconUtil';
|
||||||
import CloseOutlined from '@ant-design/icons-vue/CloseOutlined';
|
import { computed, defineComponent, inject, ref, VNodeChild, App, PropType } from 'vue';
|
||||||
import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled';
|
import PropTypes from '../_util/vue-types';
|
||||||
import CheckOutlined from '@ant-design/icons-vue/CheckOutlined';
|
import { tuple } from '../_util/type';
|
||||||
import DownOutlined from '@ant-design/icons-vue/DownOutlined';
|
|
||||||
import LoadingOutlined from '@ant-design/icons-vue/LoadingOutlined';
|
|
||||||
import { cloneElement } from '../_util/vnode';
|
|
||||||
|
|
||||||
const AbstractSelectProps = () => ({
|
type RawValue = string | number;
|
||||||
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([
|
export { OptionProps };
|
||||||
PropTypes.string,
|
|
||||||
PropTypes.number,
|
|
||||||
PropTypes.arrayOf(PropTypes.oneOfType([Value, PropTypes.string, PropTypes.number])),
|
|
||||||
Value,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const SelectProps = {
|
export type OptionType = typeof Option;
|
||||||
...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 = {
|
export interface LabeledValue {
|
||||||
prefixCls: PropTypes.string,
|
key?: string;
|
||||||
size: PropTypes.oneOf(['default', 'large', 'small']),
|
value: RawValue;
|
||||||
// combobox: PropTypes.looseBool,
|
label: VNodeChild;
|
||||||
notFoundContent: PropTypes.any,
|
}
|
||||||
showSearch: PropTypes.looseBool,
|
export type SizeType = 'small' | 'middle' | 'large' | undefined;
|
||||||
optionLabelProp: PropTypes.string,
|
export type SelectValue = RawValue | RawValue[] | LabeledValue | LabeledValue[];
|
||||||
transitionName: PropTypes.string,
|
|
||||||
choiceTransitionName: PropTypes.string,
|
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({
|
const Select = defineComponent({
|
||||||
SECRET_COMBOBOX_MODE_DO_NOT_USE,
|
|
||||||
Option: { ...Option, name: 'ASelectOption' },
|
|
||||||
OptGroup: { ...OptGroup, name: 'ASelectOptGroup' },
|
|
||||||
name: 'ASelect',
|
name: 'ASelect',
|
||||||
props: {
|
Option,
|
||||||
...SelectProps,
|
OptGroup,
|
||||||
showSearch: PropTypes.looseBool.def(false),
|
inheritAttrs: false,
|
||||||
transitionName: PropTypes.string.def('slide-up'),
|
props: SelectProps,
|
||||||
choiceTransitionName: PropTypes.string.def('zoom'),
|
SECRET_COMBOBOX_MODE_DO_NOT_USE: 'SECRET_COMBOBOX_MODE_DO_NOT_USE',
|
||||||
},
|
emits: ['change', 'update:value'],
|
||||||
propTypes: SelectPropTypes,
|
setup(props: any, {attrs, emit}) {
|
||||||
setup() {
|
const selectRef = ref(null);
|
||||||
return {
|
|
||||||
configProvider: inject('configProvider', defaultConfigProvider),
|
const configProvider = inject('configProvider', defaultConfigProvider);
|
||||||
popupRef: null,
|
|
||||||
|
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 blur = () => {
|
||||||
const { mode } = this;
|
if (selectRef.value) {
|
||||||
return mode === 'combobox' || mode === SECRET_COMBOBOX_MODE_DO_NOT_USE;
|
selectRef.value.blur();
|
||||||
},
|
}
|
||||||
|
};
|
||||||
|
|
||||||
renderSuffixIcon(prefixCls) {
|
const mode = computed(()=>{
|
||||||
const { loading } = this.$props;
|
const { mode } = props
|
||||||
let suffixIcon = getComponent(this, 'suffixIcon');
|
|
||||||
suffixIcon = Array.isArray(suffixIcon) ? suffixIcon[0] : suffixIcon;
|
if ((mode as any) === 'combobox') {
|
||||||
if (suffixIcon) {
|
return undefined;
|
||||||
return isValidElement(suffixIcon)
|
|
||||||
? cloneElement(suffixIcon, { class: `${prefixCls}-arrow-icon` })
|
|
||||||
: suffixIcon;
|
|
||||||
}
|
}
|
||||||
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() {
|
render() {
|
||||||
|
const {configProvider, mode, mergedClassName,triggerChange, $slots: slots, $props} = this as any;
|
||||||
|
const props: SelectTypes = $props
|
||||||
const {
|
const {
|
||||||
prefixCls: customizePrefixCls,
|
prefixCls: customizePrefixCls,
|
||||||
size,
|
notFoundContent,
|
||||||
mode,
|
listHeight = 256,
|
||||||
options,
|
listItemHeight = 24,
|
||||||
getPopupContainer,
|
getPopupContainer,
|
||||||
showArrow,
|
dropdownClassName,
|
||||||
...restProps
|
direction,
|
||||||
} = getOptionProps(this);
|
virtual,
|
||||||
const { class: className } = this.$attrs as any;
|
dropdownMatchSelectWidth
|
||||||
|
} = props;
|
||||||
|
|
||||||
const getPrefixCls = this.configProvider.getPrefixCls;
|
const { getPrefixCls, renderEmpty, getPopupContainer: getContextPopupContainer } = configProvider
|
||||||
const renderEmpty = this.configProvider.renderEmpty;
|
|
||||||
const prefixCls = getPrefixCls('select', customizePrefixCls);
|
const prefixCls = getPrefixCls('select', customizePrefixCls);
|
||||||
|
|
||||||
const { getPopupContainer: getContextPopupContainer } = this.configProvider;
|
const isMultiple = mode === 'multiple' || mode === 'tags';
|
||||||
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 = {
|
// ===================== Empty =====================
|
||||||
[className]: className,
|
let mergedNotFound: VNodeChild;
|
||||||
[`${prefixCls}-lg`]: size === 'large',
|
if (notFoundContent !== undefined) {
|
||||||
[`${prefixCls}-sm`]: size === 'small',
|
mergedNotFound = notFoundContent;
|
||||||
[`${prefixCls}-show-arrow`]: showArrow,
|
} else if(slots.notFoundContent){
|
||||||
};
|
mergedNotFound = slots.notFoundContent()
|
||||||
|
} else if (mode === 'combobox') {
|
||||||
let { optionLabelProp } = this.$props;
|
mergedNotFound = null;
|
||||||
if (this.isCombobox()) {
|
} else {
|
||||||
// children 带 dom 结构时,无法填入输入框
|
mergedNotFound = renderEmpty('Select') as any;
|
||||||
optionLabelProp = optionLabelProp || 'value';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const modeConfig = {
|
// ===================== Icons =====================
|
||||||
multiple: mode === 'multiple',
|
const { suffixIcon, itemIcon, removeIcon, clearIcon } = getIcons({
|
||||||
tags: mode === 'tags',
|
...this.$props,
|
||||||
combobox: this.isCombobox(),
|
multiple: isMultiple,
|
||||||
};
|
|
||||||
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,
|
prefixCls,
|
||||||
optionLabelProp: optionLabelProp || 'children',
|
}, slots);
|
||||||
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__={[]} />;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
|
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 */
|
/* istanbul ignore next */
|
||||||
Select.install = function(app: App) {
|
Select.install = function(app: App) {
|
||||||
app.component(Select.name, Select);
|
app.component(Select.name, Select);
|
||||||
app.component(Select.Option.name, Select.Option);
|
app.component('ASelectOption', Select.Option);
|
||||||
app.component(Select.OptGroup.name, Select.OptGroup);
|
app.component('ASelectOptGroup', Select.OptGroup);
|
||||||
return app;
|
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 PropTypes, { withUndefined } from '../_util/vue-types';
|
||||||
import { AbstractSelectProps } from '../select';
|
import { SelectProps } from '../select';
|
||||||
|
|
||||||
export const TreeData = PropTypes.shape({
|
export const TreeData = PropTypes.shape({
|
||||||
key: PropTypes.string,
|
key: PropTypes.string,
|
||||||
|
@ -10,7 +10,7 @@ export const TreeData = PropTypes.shape({
|
||||||
}).loose;
|
}).loose;
|
||||||
|
|
||||||
export const TreeSelectProps = () => ({
|
export const TreeSelectProps = () => ({
|
||||||
...AbstractSelectProps(),
|
...SelectProps,
|
||||||
autofocus: PropTypes.looseBool,
|
autofocus: PropTypes.looseBool,
|
||||||
dropdownStyle: PropTypes.object,
|
dropdownStyle: PropTypes.object,
|
||||||
filterTreeNode: withUndefined(PropTypes.oneOfType([Function, Boolean])),
|
filterTreeNode: withUndefined(PropTypes.oneOfType([Function, Boolean])),
|
||||||
|
|
|
@ -65,6 +65,106 @@ const DEFAULT_OMIT_PROPS = [
|
||||||
'onInputKeyDown',
|
'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> {
|
export interface SelectProps<OptionsType extends object[], ValueType> {
|
||||||
prefixCls?: string;
|
prefixCls?: string;
|
||||||
id?: string;
|
id?: string;
|
||||||
|
@ -1221,104 +1321,6 @@ export default function generateSelector<
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
Select.inheritAttrs = false;
|
Select.inheritAttrs = false;
|
||||||
Select.props = {
|
Select.props = 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({}),
|
|
||||||
};
|
|
||||||
return Select;
|
return Select;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import Select, { ExportedSelectProps } from './Select';
|
import Select, { ExportedSelectProps as SelectProps } from './Select';
|
||||||
import Option from './Option';
|
import Option from './Option';
|
||||||
import OptGroup from './OptGroup';
|
import OptGroup from './OptGroup';
|
||||||
type SelectProps = ExportedSelectProps;
|
import { props } from './generate';
|
||||||
export { Option, OptGroup, SelectProps };
|
export { Option, OptGroup, SelectProps, props };
|
||||||
|
|
||||||
export default Select;
|
export default Select;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import * as Vue from 'vue';
|
import { VNodeChild } from 'vue';
|
||||||
|
|
||||||
export type SelectSource = 'option' | 'selection' | 'input';
|
export type SelectSource = 'option' | 'selection' | 'input';
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ export type RawValueType = string | number | null;
|
||||||
export interface LabelValueType extends Record<string, any> {
|
export interface LabelValueType extends Record<string, any> {
|
||||||
key?: Key;
|
key?: Key;
|
||||||
value?: RawValueType;
|
value?: RawValueType;
|
||||||
label?: Vue.VNodeChild;
|
label?: VNodeChild;
|
||||||
}
|
}
|
||||||
export type DefaultValueType = RawValueType | RawValueType[] | LabelValueType | LabelValueType[];
|
export type DefaultValueType = RawValueType | RawValueType[] | LabelValueType | LabelValueType[];
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue