Skip to content

Commit d66c37f

Browse files
authored
fix: getInputElement为textarea时,上下键用默认行为 (#1072)
1 parent 561f8b7 commit d66c37f

File tree

2 files changed

+120
-3
lines changed

2 files changed

+120
-3
lines changed

src/Selector/index.tsx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,14 @@ const Selector: React.ForwardRefRenderFunction<RefSelectorProps, SelectorProps>
134134
// ====================== Input ======================
135135
const [getInputMouseDown, setInputMouseDown] = useLock(0);
136136

137-
const onInternalInputKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (event) => {
137+
const onInternalInputKeyDown: React.KeyboardEventHandler<
138+
HTMLInputElement | HTMLTextAreaElement
139+
> = (event) => {
138140
const { which } = event;
139141

140-
if (which === KeyCode.UP || which === KeyCode.DOWN) {
142+
// Compatible with multiple lines in TextArea
143+
const isTextAreaElement = inputRef.current instanceof HTMLTextAreaElement;
144+
if (!isTextAreaElement && open && (which === KeyCode.UP || which === KeyCode.DOWN)) {
141145
event.preventDefault();
142146
}
143147

@@ -150,7 +154,14 @@ const Selector: React.ForwardRefRenderFunction<RefSelectorProps, SelectorProps>
150154
// So when enter is pressed, the tag's input value should be emitted here to let selector know
151155
onSearchSubmit?.((event.target as HTMLInputElement).value);
152156
}
153-
157+
// Move within the text box
158+
if (
159+
isTextAreaElement &&
160+
!open &&
161+
~[KeyCode.UP, KeyCode.DOWN, KeyCode.LEFT, KeyCode.RIGHT].indexOf(which)
162+
) {
163+
return;
164+
}
154165
if (isValidateOpenKey(which)) {
155166
onToggleOpen(true);
156167
}

tests/Select.test.tsx

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -975,6 +975,112 @@ describe('Select.Basic', () => {
975975

976976
expect(container.querySelector('input').getAttribute('type')).toEqual('email');
977977
});
978+
979+
it('move the cursor in the textarea', () => {
980+
const onKeyDown = jest.fn();
981+
const onChange = jest.fn();
982+
const onMouseDown = jest.fn();
983+
const onCompositionStart = jest.fn();
984+
const onCompositionEnd = jest.fn();
985+
const textareaRef = jest.fn();
986+
const mouseDownPreventDefault = jest.fn();
987+
const { container } = render(
988+
<Select
989+
mode="combobox"
990+
ref={textareaRef}
991+
getInputElement={() => (
992+
<textarea
993+
rows={3}
994+
onKeyDown={onKeyDown}
995+
onMouseDown={onMouseDown}
996+
onCompositionStart={onCompositionStart}
997+
onCompositionEnd={onCompositionEnd}
998+
onChange={onChange}
999+
/>
1000+
)}
1001+
options={[{ value: 'light' }, { value: 'bamboo' }]}
1002+
allowClear
1003+
/>,
1004+
);
1005+
1006+
const textareaEle = container.querySelector('textarea');
1007+
toggleOpen(container);
1008+
1009+
const mouseDownEvent = createEvent.mouseDown(textareaEle);
1010+
mouseDownEvent.preventDefault = mouseDownPreventDefault;
1011+
fireEvent(textareaEle, mouseDownEvent);
1012+
1013+
keyDown(textareaEle, KeyCode.NUM_ONE);
1014+
fireEvent.change(textareaEle, {
1015+
target: {
1016+
selectionStart: 1,
1017+
selectionEnd: 1,
1018+
value: '1',
1019+
},
1020+
});
1021+
keyDown(textareaEle, KeyCode.ENTER);
1022+
keyDown(textareaEle, KeyCode.ENTER);
1023+
1024+
keyDown(textareaEle, KeyCode.NUM_TWO);
1025+
fireEvent.change(textareaEle, {
1026+
target: {
1027+
selectionStart: 3,
1028+
selectionEnd: 3,
1029+
value: '1\n2',
1030+
},
1031+
});
1032+
keyDown(textareaEle, KeyCode.ENTER);
1033+
1034+
keyDown(textareaEle, KeyCode.UP);
1035+
fireEvent.change(textareaEle, {
1036+
target: {
1037+
selectionStart: 1,
1038+
selectionEnd: 1,
1039+
},
1040+
});
1041+
1042+
const start = textareaEle.selectionStart - 1;
1043+
const end = textareaEle.selectionEnd;
1044+
const cursorValue = textareaEle.value.substring(start, end);
1045+
1046+
expect(textareaEle.value).toBe('1\n2');
1047+
expect(start).toBe(0);
1048+
expect(end).toBe(1);
1049+
expect(cursorValue).toBe('1');
1050+
});
1051+
1052+
it('Moving the cursor in TextArea does not display the listbox', () => {
1053+
const onKeyDown = jest.fn();
1054+
const onMouseDown = jest.fn();
1055+
const textareaRef = jest.fn();
1056+
const mouseDownPreventDefault = jest.fn();
1057+
const { container } = render(
1058+
<Select
1059+
mode="combobox"
1060+
value="abc\ndef"
1061+
ref={textareaRef}
1062+
getInputElement={() => (
1063+
<textarea rows={3} onKeyDown={onKeyDown} onMouseDown={onMouseDown} />
1064+
)}
1065+
options={[{ value: 'light' }, { value: 'bamboo' }]}
1066+
allowClear
1067+
/>,
1068+
);
1069+
1070+
const textareaEle = container.querySelector('textarea');
1071+
toggleOpen(container);
1072+
1073+
const mouseDownEvent = createEvent.mouseDown(textareaEle);
1074+
mouseDownEvent.preventDefault = mouseDownPreventDefault;
1075+
fireEvent(textareaEle, mouseDownEvent);
1076+
1077+
keyDown(textareaEle, KeyCode.ENTER);
1078+
1079+
[KeyCode.LEFT, KeyCode.DOWN, KeyCode.RIGHT, KeyCode.UP].forEach((keyCode) => {
1080+
keyDown(textareaEle, keyCode);
1081+
expectOpen(container, false);
1082+
});
1083+
});
9781084
});
9791085

9801086
it('getRawInputElement for rc-cascader', () => {

0 commit comments

Comments
 (0)