Skip to content

fix: getInputElement为textarea时,上下键用默认行为 #1072

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions src/Selector/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,14 @@ const Selector: React.ForwardRefRenderFunction<RefSelectorProps, SelectorProps>
// ====================== Input ======================
const [getInputMouseDown, setInputMouseDown] = useLock(0);

const onInternalInputKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (event) => {
const onInternalInputKeyDown: React.KeyboardEventHandler<
HTMLInputElement | HTMLTextAreaElement
> = (event) => {
const { which } = event;

if (which === KeyCode.UP || which === KeyCode.DOWN) {
// Compatible with multiple lines in TextArea
const isTextAreaElement = inputRef.current instanceof HTMLTextAreaElement;
if (!isTextAreaElement && open && (which === KeyCode.UP || which === KeyCode.DOWN)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

open 且显示 not found 的时候,也可以走默认行为。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

测试 open 且显示 not found 的时候会走默认行为

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

只有textarea时,才需要处理上下的默认行为,这的判断只要是textarea就不会阻止默认行为。
如果是 (单行&open&not found),按上下只能到行首和行尾,需要处理这种吗。

event.preventDefault();
}

Expand All @@ -150,7 +154,14 @@ const Selector: React.ForwardRefRenderFunction<RefSelectorProps, SelectorProps>
// So when enter is pressed, the tag's input value should be emitted here to let selector know
onSearchSubmit?.((event.target as HTMLInputElement).value);
}

// Move within the text box
if (
isTextAreaElement &&
!open &&
~[KeyCode.UP, KeyCode.DOWN, KeyCode.LEFT, KeyCode.RIGHT].indexOf(which)
) {
return;
}
if (isValidateOpenKey(which)) {
onToggleOpen(true);
}
Expand Down
106 changes: 106 additions & 0 deletions tests/Select.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,112 @@ describe('Select.Basic', () => {

expect(container.querySelector('input').getAttribute('type')).toEqual('email');
});

it('move the cursor in the textarea', () => {
const onKeyDown = jest.fn();
const onChange = jest.fn();
const onMouseDown = jest.fn();
const onCompositionStart = jest.fn();
const onCompositionEnd = jest.fn();
const textareaRef = jest.fn();
const mouseDownPreventDefault = jest.fn();
const { container } = render(
<Select
mode="combobox"
ref={textareaRef}
getInputElement={() => (
<textarea
rows={3}
onKeyDown={onKeyDown}
onMouseDown={onMouseDown}
onCompositionStart={onCompositionStart}
onCompositionEnd={onCompositionEnd}
onChange={onChange}
/>
)}
options={[{ value: 'light' }, { value: 'bamboo' }]}
allowClear
/>,
);

const textareaEle = container.querySelector('textarea');
toggleOpen(container);

const mouseDownEvent = createEvent.mouseDown(textareaEle);
mouseDownEvent.preventDefault = mouseDownPreventDefault;
fireEvent(textareaEle, mouseDownEvent);

keyDown(textareaEle, KeyCode.NUM_ONE);
fireEvent.change(textareaEle, {
target: {
selectionStart: 1,
selectionEnd: 1,
value: '1',
},
});
keyDown(textareaEle, KeyCode.ENTER);
keyDown(textareaEle, KeyCode.ENTER);

keyDown(textareaEle, KeyCode.NUM_TWO);
fireEvent.change(textareaEle, {
target: {
selectionStart: 3,
selectionEnd: 3,
value: '1\n2',
},
});
keyDown(textareaEle, KeyCode.ENTER);

keyDown(textareaEle, KeyCode.UP);
fireEvent.change(textareaEle, {
target: {
selectionStart: 1,
selectionEnd: 1,
},
});

const start = textareaEle.selectionStart - 1;
const end = textareaEle.selectionEnd;
const cursorValue = textareaEle.value.substring(start, end);

expect(textareaEle.value).toBe('1\n2');
expect(start).toBe(0);
expect(end).toBe(1);
expect(cursorValue).toBe('1');
});

it('Moving the cursor in TextArea does not display the listbox', () => {
const onKeyDown = jest.fn();
const onMouseDown = jest.fn();
const textareaRef = jest.fn();
const mouseDownPreventDefault = jest.fn();
const { container } = render(
<Select
mode="combobox"
value="abc\ndef"
ref={textareaRef}
getInputElement={() => (
<textarea rows={3} onKeyDown={onKeyDown} onMouseDown={onMouseDown} />
)}
options={[{ value: 'light' }, { value: 'bamboo' }]}
allowClear
/>,
);

const textareaEle = container.querySelector('textarea');
toggleOpen(container);

const mouseDownEvent = createEvent.mouseDown(textareaEle);
mouseDownEvent.preventDefault = mouseDownPreventDefault;
fireEvent(textareaEle, mouseDownEvent);

keyDown(textareaEle, KeyCode.ENTER);

[KeyCode.LEFT, KeyCode.DOWN, KeyCode.RIGHT, KeyCode.UP].forEach((keyCode) => {
keyDown(textareaEle, keyCode);
expectOpen(container, false);
});
});
});

it('getRawInputElement for rc-cascader', () => {
Expand Down
Loading