import omit from 'omit.js'; 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 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'; type RawValue = string | number; export { OptionProps }; export type OptionType = typeof Option; 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 extends Omit, 'mode'> { suffixIcon?: VNodeChild; itemIcon?: VNodeChild; size?: SizeType; mode?: 'multiple' | 'tags' | 'SECRET_COMBOBOX_MODE_DO_NOT_USE'; bordered?: boolean; } export interface SelectPropsTypes extends Omit, 'inputIcon' | 'mode' | 'getInputElement' | 'backfill' | 'class' | 'style'> { mode?: 'multiple' | 'tags'; } export type SelectTypes = SelectPropsTypes export const SelectProps = { ...omit(props, ['inputIcon' ,'mode' ,'getInputElement' ,'backfill' ,'class' ,'style']), value: { type: [Array, Object, String, Number] as PropType }, defaultValue: { type: [Array, Object, String, Number] as PropType }, 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(''), } const Select = defineComponent({ name: 'ASelect', 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(); } }; const blur = () => { if (selectRef.value) { selectRef.value.blur(); } }; const mode = computed(()=>{ const { mode } = props if ((mode as any) === 'combobox') { return undefined; } if (mode === Select.SECRET_COMBOBOX_MODE_DO_NOT_USE) { return 'combobox'; } 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, notFoundContent, listHeight = 256, listItemHeight = 24, getPopupContainer, dropdownClassName, direction, virtual, dropdownMatchSelectWidth } = props; const { getPrefixCls, renderEmpty, getPopupContainer: getContextPopupContainer } = configProvider const prefixCls = getPrefixCls('select', customizePrefixCls); const isMultiple = mode === 'multiple' || mode === 'tags'; // ===================== 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; } // ===================== Icons ===================== const { suffixIcon, itemIcon, removeIcon, clearIcon } = getIcons({ ...this.$props, multiple: isMultiple, prefixCls, }, slots); const selectProps = omit(props, [ 'prefixCls', 'suffixIcon', 'itemIcon', 'removeIcon', 'clearIcon', 'size', 'bordered', ]) as any; const rcSelectRtlDropDownClassName = classNames(dropdownClassName, { [`${prefixCls}-dropdown-${direction}`]: direction === 'rtl', }); {slots?.default()} } }) /* istanbul ignore next */ Select.install = function(app: App) { app.component(Select.name, Select); app.component('ASelectOption', Select.Option); app.component('ASelectOptGroup', Select.OptGroup); return app; }; 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'; };