diff --git a/src/select/__tests__/index.test.jsx b/src/select/__tests__/index.test.jsx index 50faac6576..0477e0ed20 100644 --- a/src/select/__tests__/index.test.jsx +++ b/src/select/__tests__/index.test.jsx @@ -201,6 +201,53 @@ describe('Select', () => { expect(value.value).toBe([]); }); }); + + describe('onInputChange', () => { + it('[multiple=false] [filterable="value"]', async () => { + const onInputChangeFn = vi.fn(); + const options = [ + { label: '架构云', value: '1' }, + { label: '大数据', value: '2' }, + { label: '区块链', value: '3' }, + { label: '物联网', value: '4' }, + { label: '人工智能', value: '5' }, + ]; + + const wrapper = mount( + { + render() { + return ( + + ); + }, + }, + { + attachTo: document.body, + }, + ); + await wrapper.setProps({ popupProps: { attach: 'custom-select', visible: true } }); + + const input = wrapper.find('input'); + await input.trigger('focus'); + + // onInputChange 被调用 + await input.setValue('大数'); + await input.trigger('input'); + expect(onInputChangeFn).toBeCalled(); + + // 当前只剩下 filter 之后的数据,判断选中后的结果 + const optionsList = wrapper.findAll('.t-select-option'); + expect(optionsList.length).toBe(1); + expect(optionsList[0].text()).toContain('大数据'); + await optionsList[0].trigger('click'); + expect(input.element.value).toBe('大数据'); + }); + }); }); }); diff --git a/src/select/helper.ts b/src/select/helper.ts index 72b03bde2c..4c4d23dd2e 100644 --- a/src/select/helper.ts +++ b/src/select/helper.ts @@ -11,7 +11,7 @@ export const selectInjectKey: InjectionKey< reserveKeyword: TdSelectProps['reserveKeyword']; multiple: TdSelectProps['multiple']; handleValueChange: TdSelectProps['onChange']; - handleCreate: TdSelectProps['onCreate']; + handleCreate: (e: MouseEvent | KeyboardEvent) => void; handlerInputChange: TdSelectProps['onInputChange']; handlePopupVisibleChange: TdSelectProps['onPopupVisibleChange']; popupContentRef: ComputedRef; diff --git a/src/select/option.tsx b/src/select/option.tsx index 8757129b33..4c82109555 100644 --- a/src/select/option.tsx +++ b/src/select/option.tsx @@ -86,7 +86,7 @@ export default defineComponent({ } if (props.createAble) { - selectProvider.value.handleCreate?.(props.value); + selectProvider.value.handleCreate?.(e); if (selectProvider.value.multiple) { selectProvider.value.handleValueChange( [...(selectProvider.value.selectValue as SelectValue[]), props.value], diff --git a/src/select/select.tsx b/src/select/select.tsx index 605973e26d..00a22538ef 100644 --- a/src/select/select.tsx +++ b/src/select/select.tsx @@ -89,7 +89,7 @@ export default defineComponent({ newVal = props.multiple ? (newVal as SelectValue[]).map((val) => getOption(val)) : getOption(newVal); } if (newVal === orgValue.value) return; - if (props.multiple && !props.reserveKeyword) setInputValue(''); + if (props.multiple && !props.reserveKeyword) setInputValue('', { e: context.e, trigger: 'change' }); setOrgValue(newVal, { selectedOptions: getSelectedOptions(newVal), ...context, @@ -167,11 +167,11 @@ export default defineComponent({ }); }; - const handleCreate = () => { + const handleCreate = (e: KeyboardEvent) => { if (!innerInputValue.value) return; props.onCreate?.(innerInputValue.value); // only clean input value when reopen popup - if (!innerPopupVisible.value) setInputValue(''); + if (!innerPopupVisible.value) setInputValue('', { e, trigger: 'change' }); }; const popupContentRef = computed(() => selectInputRef.value?.popupRef.getOverlay() as HTMLElement); @@ -271,7 +271,7 @@ export default defineComponent({ if (value) { !innerPopupVisible.value && setInnerPopupVisible(true, { e: context.e as KeyboardEvent }); } - setInputValue(value); + setInputValue(value, context); handleSearch(`${value}`, { e: context.e as KeyboardEvent }); nextTick(() => { virtualFilteredOptions.value = selectPanelRef.value?.visibleData; @@ -285,8 +285,6 @@ export default defineComponent({ const handlerPopupVisibleChange = (visible: boolean, context: PopupVisibleChangeContext) => { setInnerPopupVisible(visible, context); - // 在通过点击选择器打开弹窗时 清空此前的输入内容 避免在关闭时就清空引起的闪烁问题 - if (visible && context.trigger === 'trigger-element-click') setInputValue(''); }; const handlerPopupScrollToBottom: PopupProps['onScrollToBottom'] = async (context) => { @@ -446,7 +444,7 @@ export default defineComponent({ // onEnter和handleKeyDown的Enter事件同时触发,需要通过setTimeout设置先后 setTimeout(() => { props.onEnter?.({ inputValue: `${innerInputValue.value}`, e, value: innerValue.value }); - handleCreate(); + handleCreate(e); }, 0); }} onBlur={(inputValue, { e }) => {