diff --git a/packages/components/select-v2/__tests__/select.test.ts b/packages/components/select-v2/__tests__/select.test.ts index 0a450c8a58..174bd81522 100644 --- a/packages/components/select-v2/__tests__/select.test.ts +++ b/packages/components/select-v2/__tests__/select.test.ts @@ -1180,10 +1180,10 @@ describe('Select', () => { // selected the new option selectVm.onSelect(selectVm.filteredOptions[0]) expect(vm.value).toBe('1111') - await input.trigger('click') + await wrapper.find('.el-select__suffix').trigger('click') await nextTick() await rAF() - await input.trigger('click') + await wrapper.find('.el-select__suffix').trigger('click') await nextTick() await rAF() expect(selectVm.filteredOptions.length).toBe(4) @@ -1876,6 +1876,23 @@ describe('Select', () => { const options = getOptions() expect(options.length).toBe(3) }) + + it('should keep the select dropdown open when using the filterable', async () => { + const wrapper = createSelect({ + data() { + return { + filterable: true, + } + }, + }) + const select = wrapper.findComponent({ name: 'ElSelectV2' }) + const input = wrapper.find('input') + await input.trigger('click') + expect((select.vm as any).expanded).toBe(true) + + await input.trigger('click') + expect((select.vm as any).expanded).toBe(true) + }) }) describe('remote search', () => { diff --git a/packages/components/select-v2/src/useSelect.ts b/packages/components/select-v2/src/useSelect.ts index 55e0f05032..fca0f8e39e 100644 --- a/packages/components/select-v2/src/useSelect.ts +++ b/packages/components/select-v2/src/useSelect.ts @@ -428,8 +428,15 @@ const useSelect = (props: SelectV2Props, emit: SelectV2EmitFn) => { } = useAllowCreate(props, states) // methods - const toggleMenu = () => { - if (selectDisabled.value) return + const toggleMenu = (event?: Event) => { + if ( + selectDisabled.value || + (props.filterable && + expanded.value && + event && + !suffixRef.value?.contains(event.target as Node)) + ) + return if (states.menuVisibleOnFocus) { // controlled by automaticDropdown diff --git a/packages/components/select/__tests__/select.test.ts b/packages/components/select/__tests__/select.test.ts index 9873865992..d0f91d8a2a 100644 --- a/packages/components/select/__tests__/select.test.ts +++ b/packages/components/select/__tests__/select.test.ts @@ -2600,7 +2600,7 @@ describe('Select', () => { clearable: true, }) const select = wrapper.findComponent({ name: 'ElSelect' }) - const trigger = wrapper.find(`.${WRAPPER_CLASS_NAME}`) + const trigger = wrapper.find('.el-select__suffix') await trigger.trigger('click') expect((select.vm as any).expanded).toBe(true) await trigger.trigger('click') @@ -2608,6 +2608,20 @@ describe('Select', () => { }) test('mouseenter click', async () => { + wrapper = getSelectVm({ + filterable: false, + clearable: true, + }) + const select = wrapper.findComponent({ name: 'ElSelect' }) + const trigger = wrapper.find(`.${WRAPPER_CLASS_NAME}`) + await trigger.trigger('click') + expect((select.vm as any).expanded).toBe(true) + + await trigger.trigger('click') + expect((select.vm as any).expanded).toBe(false) + }) + + test('should keep the select dropdown open when using the filterable', async () => { wrapper = getSelectVm({ filterable: true, clearable: true, @@ -2618,7 +2632,7 @@ describe('Select', () => { expect((select.vm as any).expanded).toBe(true) await trigger.trigger('click') - expect((select.vm as any).expanded).toBe(false) + expect((select.vm as any).expanded).toBe(true) }) describe('should show all options when open select dropdown', () => { diff --git a/packages/components/select/src/useSelect.ts b/packages/components/select/src/useSelect.ts index 601bbc7499..7f33cd43ab 100644 --- a/packages/components/select/src/useSelect.ts +++ b/packages/components/select/src/useSelect.ts @@ -692,8 +692,15 @@ export const useSelect = (props: SelectProps, emit: SelectEmits) => { } } - const toggleMenu = () => { - if (selectDisabled.value) return + const toggleMenu = (event?: Event) => { + if ( + selectDisabled.value || + (props.filterable && + expanded.value && + event && + !suffixRef.value?.contains(event.target as Node)) + ) + return // We only set the inputHovering state to true on mouseenter event on iOS devices // To keep the state updated we set it here to true