Skip to content

Commit c6bee0d

Browse files
authored
fix: fix Firefox scroll bug and improve TextArea tests (#72)
1 parent bca6b27 commit c6bee0d

File tree

2 files changed

+50
-8
lines changed

2 files changed

+50
-8
lines changed

src/ResizableTextArea.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import classNames from 'classnames';
21
import ResizeObserver from '@rc-component/resize-observer';
32
import useLayoutEffect from '@rc-component/util/lib/hooks/useLayoutEffect';
43
import useMergedState from '@rc-component/util/lib/hooks/useMergedState';
54
import raf from '@rc-component/util/lib/raf';
5+
import classNames from 'classnames';
66
import * as React from 'react';
77
import type { TextAreaProps } from '.';
88
import calculateAutoSizeStyle from './calculateNodeHeight';
@@ -66,9 +66,10 @@ const ResizableTextArea = React.forwardRef<ResizableTextAreaRef, TextAreaProps>(
6666
// https://github.com/ant-design/ant-design/issues/21870
6767
const fixFirefoxAutoScroll = () => {
6868
try {
69+
const isFirefox = navigator.userAgent.includes('Firefox');
6970
// FF has bug with jump of scroll to top. We force back here.
70-
if (document.activeElement === textareaRef.current) {
71-
const { selectionStart, selectionEnd, scrollTop } =
71+
if (isFirefox && document.activeElement === textareaRef.current) {
72+
const { scrollTop, selectionStart, selectionEnd } =
7273
textareaRef.current;
7374

7475
// Fix Safari bug which not rollback when break line

tests/index.spec.tsx

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,42 @@ describe('TextArea', () => {
3737
jest.useRealTimers();
3838
});
3939

40+
it('paste text should change cursor position', async () => {
41+
const { container } = render(
42+
<TextArea autoSize={{ minRows: 2, maxRows: 6 }} />,
43+
);
44+
const textArea = container.querySelector('textarea') as HTMLTextAreaElement;
45+
// 监听事件绑定和移除
46+
const pasteData = 'pasted text\n'.repeat(10);
47+
const clipboardData = {
48+
getData: jest.fn().mockReturnValue(pasteData),
49+
};
50+
51+
const pasteEvent = async () => {
52+
fireEvent.focus(textArea);
53+
54+
fireEvent.paste(textArea, {
55+
clipboardData,
56+
types: ['text/plain'],
57+
items: [],
58+
});
59+
60+
fireEvent.change(textArea, { target: { value: pasteData } });
61+
textArea.setSelectionRange(pasteData.length, pasteData.length);
62+
63+
await wait();
64+
expect(textArea.selectionStart).toBe(pasteData.length);
65+
expect(textArea.selectionEnd).toBe(pasteData.length);
66+
fireEvent.change(textArea, { target: { value: '' } });
67+
await wait();
68+
expect(textArea.selectionStart).toBe(0);
69+
expect(textArea.selectionEnd).toBe(0);
70+
};
71+
72+
await pasteEvent();
73+
await pasteEvent();
74+
});
75+
4076
it('should work correctly on controlled mode', () => {
4177
const Demo = () => {
4278
const [value, setValue] = React.useState('111');
@@ -235,18 +271,23 @@ describe('TextArea', () => {
235271
container.querySelector('textarea').focus();
236272
expect(document.activeElement).toBe(container.querySelector('textarea'));
237273

238-
const setSelectionRangeFn = jest.spyOn(
239-
container.querySelector('textarea'),
240-
'setSelectionRange',
241-
);
274+
// https://github.com/ant-design/ant-design/issues/54444
275+
// Other browsers may have cursor position issues when calling setSelectionRange, so we do not call it here.
276+
// const setSelectionRangeFn = jest.spyOn(
277+
// container.querySelector('textarea'),
278+
// 'setSelectionRange',
279+
// );
242280

243281
fireEvent.change(container.querySelector('textarea'), {
244282
target: { value: '\n1' },
245283
});
246284

247285
await wait();
248286

249-
expect(setSelectionRangeFn).toHaveBeenCalled();
287+
// expect(setSelectionRangeFn).toHaveBeenCalled();
288+
expect(container.querySelector('textarea').scrollTop).toBe(
289+
container.querySelector('textarea').scrollHeight,
290+
);
250291
unmount();
251292
});
252293

0 commit comments

Comments
 (0)