import pickAttrs from '../../_util/pickAttrs'; import Input from './Input'; import type { InnerSelectorProps } from './interface'; import { Fragment, Ref, computed, defineComponent, shallowRef, watch } from 'vue'; import PropTypes from '../../_util/vue-types'; import type { VueNode } from '../../_util/type'; import useInjectLegacySelectContext from '../../vc-tree-select/LegacyContext'; interface SelectorProps extends InnerSelectorProps { inputElement: VueNode; activeValue: string; optionLabelRender: Function; // placeholder compositionStatus: boolean; } const props = { inputElement: PropTypes.any, id: String, prefixCls: String, values: PropTypes.array, open: { type: Boolean, default: undefined }, searchValue: String, inputRef: PropTypes.any, placeholder: PropTypes.any, compositionStatus: { type: Boolean, default: undefined }, disabled: { type: Boolean, default: undefined }, mode: String, showSearch: { type: Boolean, default: undefined }, autofocus: { type: Boolean, default: undefined }, autocomplete: String, activeDescendantId: String, tabindex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), activeValue: String, backfill: { type: Boolean, default: undefined }, optionLabelRender: Function, onInputChange: Function, onInputPaste: Function, onInputKeyDown: Function, onInputMouseDown: Function, onInputCompositionStart: Function, onInputCompositionEnd: Function, }; const SingleSelector = defineComponent({ name: 'SingleSelector', setup(props) { const inputChanged = shallowRef(false); const combobox = computed(() => props.mode === 'combobox'); const inputEditable = computed(() => combobox.value || props.showSearch); const inputValue = computed(() => { let inputValue: string = props.searchValue || ''; if (combobox.value && props.activeValue && !inputChanged.value) { inputValue = props.activeValue; } return inputValue; }); const legacyTreeSelectContext = useInjectLegacySelectContext(); watch( [combobox, () => props.activeValue], () => { if (combobox.value) { inputChanged.value = false; } }, { immediate: true }, ); // Not show text when closed expect combobox mode const hasTextInput = computed(() => props.mode !== 'combobox' && !props.open && !props.showSearch ? false : !!inputValue.value || props.compositionStatus, ); const title = computed(() => { const item = props.values[0]; return item && (typeof item.label === 'string' || typeof item.label === 'number') ? item.label.toString() : undefined; }); const renderPlaceholder = () => { if (props.values[0]) { return null; } const hiddenStyle = hasTextInput.value ? { visibility: 'hidden' as const } : undefined; return ( {props.placeholder} ); }; return () => { const { inputElement, prefixCls, id, values, inputRef, disabled, autofocus, autocomplete, activeDescendantId, open, tabindex, optionLabelRender, onInputKeyDown, onInputMouseDown, onInputChange, onInputPaste, onInputCompositionStart, onInputCompositionEnd, } = props; const item = values[0]; let titleNode = null; // custom tree-select title by slot // For TreeSelect if (item && legacyTreeSelectContext.customSlots) { const key = item.key ?? item.value; const originData = legacyTreeSelectContext.keyEntities[key]?.node || {}; titleNode = legacyTreeSelectContext.customSlots[originData.slots?.title] || legacyTreeSelectContext.customSlots.title || item.label; if (typeof titleNode === 'function') { titleNode = titleNode(originData); } // else if (treeSelectContext.value.slots.titleRender) { // // 因历史 title 是覆盖逻辑,新增 titleRender,所有的 title 都走一遍 titleRender // titleNode = treeSelectContext.value.slots.titleRender(item.option?.data || {}); // } } else { titleNode = optionLabelRender && item ? optionLabelRender(item.option) : item?.label; } return ( <> { inputChanged.value = true; onInputChange(e as any); }} onPaste={onInputPaste} onCompositionstart={onInputCompositionStart} onCompositionend={onInputCompositionEnd} tabindex={tabindex} attrs={pickAttrs(props, true)} /> {/* Display value */} {!combobox.value && item && !hasTextInput.value && ( {titleNode} )} {/* Display placeholder */} {renderPlaceholder()} ); }; }, }); SingleSelector.props = props; SingleSelector.inheritAttrs = false; export default SingleSelector;