diff --git a/src/BaseSelect/index.tsx b/src/BaseSelect/index.tsx index 0b393dfc..b1390f98 100644 --- a/src/BaseSelect/index.tsx +++ b/src/BaseSelect/index.tsx @@ -3,7 +3,6 @@ import classNames from 'classnames'; import useLayoutEffect from 'rc-util/lib/hooks/useLayoutEffect'; import useMergedState from 'rc-util/lib/hooks/useMergedState'; import isMobile from 'rc-util/lib/isMobile'; -import KeyCode from 'rc-util/lib/KeyCode'; import { useComposeRef } from 'rc-util/lib/ref'; import type { ScrollConfig, ScrollTo } from 'rc-virtual-list/lib/List'; import * as React from 'react'; @@ -480,13 +479,16 @@ const BaseSelect = React.forwardRef((props, ref) * - false: Search text is not empty when first time backspace down */ const [getClearLock, setClearLock] = useLock(); + const keyLockRef = React.useRef(false); // KeyDown const onInternalKeyDown: React.KeyboardEventHandler = (event, ...rest) => { const clearLock = getClearLock(); - const { which } = event; + const { key } = event; - if (which === KeyCode.ENTER) { + const isEnterKey = key === 'Enter'; + + if (isEnterKey) { // Do not submit form when type in the input if (mode !== 'combobox') { event.preventDefault(); @@ -502,7 +504,7 @@ const BaseSelect = React.forwardRef((props, ref) // Remove value by `backspace` if ( - which === KeyCode.BACKSPACE && + key === 'Backspace' && !clearLock && multiple && !mergedSearchValue && @@ -529,10 +531,14 @@ const BaseSelect = React.forwardRef((props, ref) } } - if (mergedOpen) { + if (mergedOpen && (!isEnterKey || !keyLockRef.current)) { listRef.current?.onKeyDown(event, ...rest); } + if (isEnterKey) { + keyLockRef.current = true; + } + onKeyDown?.(event, ...rest); }; @@ -541,7 +547,9 @@ const BaseSelect = React.forwardRef((props, ref) if (mergedOpen) { listRef.current?.onKeyUp(event, ...rest); } - + if (event.key === 'Enter') { + keyLockRef.current = false; + } onKeyUp?.(event, ...rest); }; diff --git a/tests/Multiple.test.tsx b/tests/Multiple.test.tsx index 8e237690..e63b6773 100644 --- a/tests/Multiple.test.tsx +++ b/tests/Multiple.test.tsx @@ -16,6 +16,7 @@ import { findSelection, removeSelection, keyDown, + keyUp, } from './utils/common'; import allowClearTest from './shared/allowClearTest'; import { fireEvent, render } from '@testing-library/react'; @@ -294,6 +295,25 @@ describe('Select.Multiple', () => { expect(onChange).toHaveBeenCalledWith([2], expect.anything()); }); + it('should prevent long press of enter', () => { + const onChange = jest.fn(); + const { container } = render( + , + ); + + toggleOpen(container); + fireEvent.mouseMove(container.querySelectorAll('.rc-select-item-option')[1]); + + keyDown(container.querySelector('input'), KeyCode.ENTER); + keyDown(container.querySelector('input'), KeyCode.ENTER); + keyUp(container.querySelector('input'), KeyCode.ENTER); + expectOpen(container); + expect(onChange).toHaveBeenCalledTimes(1); + }); + it('enter twice to cancel the selection', () => { const onChange = jest.fn(); const { container } = render( @@ -306,7 +326,7 @@ describe('Select.Multiple', () => { toggleOpen(container); fireEvent.mouseMove(container.querySelectorAll('.rc-select-item-option')[0]); keyDown(container.querySelector('input'), KeyCode.ENTER); - + keyUp(container.querySelector('input'), KeyCode.ENTER); fireEvent.mouseMove(container.querySelectorAll('.rc-select-item-option')[0]); keyDown(container.querySelector('input'), KeyCode.ENTER); diff --git a/tests/Select.test.tsx b/tests/Select.test.tsx index 8cbd0a8b..361a55e6 100644 --- a/tests/Select.test.tsx +++ b/tests/Select.test.tsx @@ -25,6 +25,7 @@ import { findSelection, injectRunAllTimers, keyDown, + keyUp, selectItem, toggleOpen, } from './utils/common'; @@ -1469,6 +1470,7 @@ describe('Select.Basic', () => { for (let i = 0; i < 10; i += 1) { onSelect.mockReset(); keyDown(container.querySelector('input'), KeyCode.ENTER); + keyUp(container.querySelector('input'), KeyCode.ENTER); expect(onSelect).toHaveBeenCalledWith('1', expect.anything()); } }); diff --git a/tests/utils/common.ts b/tests/utils/common.ts index ed0d5aaa..12ebba26 100644 --- a/tests/utils/common.ts +++ b/tests/utils/common.ts @@ -106,3 +106,11 @@ export function keyDown(element: HTMLElement, keyCode: number) { fireEvent(element, event); }); } + +export function keyUp(element: HTMLElement, keyCode: number) { + const event = createEvent.keyUp(element, { keyCode }); + + act(() => { + fireEvent(element, event); + }); +}