/** * Since search box is in different position with different mode. * - Single: in the popup box * - multiple: in the selector * Move the code as a SearchInput for easy management. */ import BaseInput from '../../_util/BaseInput'; import { inject, ref, onMounted, computed, watch } from 'vue'; import PropTypes from '../../_util/vue-types'; import { createRef } from './util'; const SearchInput = { name: 'SearchInput', inheritAttrs: false, props: { open: PropTypes.looseBool, searchValue: PropTypes.string, prefixCls: PropTypes.string, disabled: PropTypes.looseBool, renderPlaceholder: PropTypes.func, needAlign: PropTypes.looseBool, ariaId: PropTypes.string, isMultiple: PropTypes.looseBool.def(true), }, emits: ['mirrorSearchValueChange'], setup(props, { emit }) { const measureRef = ref(); const inputWidth = ref(0); const mirrorSearchValue = ref(props.searchValue); watch( computed(() => props.searchValue), () => { mirrorSearchValue.value = props.searchValue; }, ); watch( mirrorSearchValue, () => { emit('mirrorSearchValueChange', mirrorSearchValue.value); }, { immediate: true }, ); // We measure width and set to the input immediately onMounted(() => { if (props.isMultiple) { watch( mirrorSearchValue, () => { inputWidth.value = measureRef.value.scrollWidth; }, { flush: 'post', immediate: true }, ); } }); return { measureRef, inputWidth, vcTreeSelect: inject('vcTreeSelect', {}), mirrorSearchValue, }; }, created() { this.inputRef = createRef(); this.prevProps = { ...this.$props }; }, mounted() { this.$nextTick(() => { const { open } = this.$props; if (open) { this.focus(true); } }); }, updated() { const { open } = this.$props; const { prevProps } = this; this.$nextTick(() => { if (open && prevProps.open !== open) { this.focus(); } this.prevProps = { ...this.$props }; }); }, methods: { /** * Need additional timeout for focus cause parent dom is not ready when didMount trigger */ focus(isDidMount) { if (this.inputRef.current) { if (isDidMount) { setTimeout(() => { this.inputRef.current.focus(); }, 0); } else { // set it into else, Avoid scrolling when focus this.inputRef.current.focus(); } } }, blur() { if (this.inputRef.current) { this.inputRef.current.blur(); } }, handleInputChange(e) { const { value, composing } = e.target; const { searchValue = '' } = this; if (e.isComposing || composing || searchValue === value) { this.mirrorSearchValue = value; return; } this.vcTreeSelect.onSearchInputChange(e); }, }, render() { const { searchValue, prefixCls, disabled, renderPlaceholder, open, ariaId, isMultiple, } = this.$props; const { vcTreeSelect: { onSearchInputKeyDown }, handleInputChange, mirrorSearchValue, inputWidth, } = this; return ( <> {isMultiple ? ( {mirrorSearchValue}  ) : null} {renderPlaceholder && !mirrorSearchValue ? renderPlaceholder() : null} ); }, }; export default SearchInput;