Skip to content

Commit

Permalink
feat: Prevent long press of enter (#1053)
Browse files Browse the repository at this point in the history
* feat: Prevent long press of enter

* feat: lint

* feat: test

* feat: test

* feat: 优化代码

* feat: test

* feat: 优化代码

* feat: 判断方式

* feat: 删除判断

* feat: 优化代码

* feat: reviewg

* feat: review
  • Loading branch information
crazyair authored Jul 19, 2024
1 parent 66b6667 commit a512335
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 7 deletions.
20 changes: 14 additions & 6 deletions src/BaseSelect/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -480,13 +479,16 @@ const BaseSelect = React.forwardRef<BaseSelectRef, BaseSelectProps>((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<HTMLDivElement> = (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();
Expand All @@ -502,7 +504,7 @@ const BaseSelect = React.forwardRef<BaseSelectRef, BaseSelectProps>((props, ref)

// Remove value by `backspace`
if (
which === KeyCode.BACKSPACE &&
key === 'Backspace' &&
!clearLock &&
multiple &&
!mergedSearchValue &&
Expand All @@ -529,10 +531,14 @@ const BaseSelect = React.forwardRef<BaseSelectRef, BaseSelectProps>((props, ref)
}
}

if (mergedOpen) {
if (mergedOpen && (!isEnterKey || !keyLockRef.current)) {
listRef.current?.onKeyDown(event, ...rest);
}

if (isEnterKey) {
keyLockRef.current = true;
}

onKeyDown?.(event, ...rest);
};

Expand All @@ -541,7 +547,9 @@ const BaseSelect = React.forwardRef<BaseSelectRef, BaseSelectProps>((props, ref)
if (mergedOpen) {
listRef.current?.onKeyUp(event, ...rest);
}

if (event.key === 'Enter') {
keyLockRef.current = false;
}
onKeyUp?.(event, ...rest);
};

Expand Down
22 changes: 21 additions & 1 deletion tests/Multiple.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
findSelection,
removeSelection,
keyDown,
keyUp,
} from './utils/common';
import allowClearTest from './shared/allowClearTest';
import { fireEvent, render } from '@testing-library/react';
Expand Down Expand Up @@ -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(
<Select mode="multiple" onChange={onChange}>
<Option value={1}>1</Option>
<Option value={2}>2</Option>
</Select>,
);

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(
Expand All @@ -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);

Expand Down
2 changes: 2 additions & 0 deletions tests/Select.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
findSelection,
injectRunAllTimers,
keyDown,
keyUp,
selectItem,
toggleOpen,
} from './utils/common';
Expand Down Expand Up @@ -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());
}
});
Expand Down
8 changes: 8 additions & 0 deletions tests/utils/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
}

0 comments on commit a512335

Please sign in to comment.