mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-12-02 12:09:14 +08:00
fix: Textarea blink on first mount (#37847)
* fix: Textarea blink on first mount * chore: Update ts def * test: Update test case * chore: bump rc-mentions * test: Update snapshot * test: Update test case
This commit is contained in:
parent
b110ff0293
commit
c436bd6f4f
@ -1,7 +1,7 @@
|
||||
import classNames from 'classnames';
|
||||
import type { TextAreaProps as RcTextAreaProps } from 'rc-textarea';
|
||||
import RcTextArea from 'rc-textarea';
|
||||
import type ResizableTextArea from 'rc-textarea/lib/ResizableTextArea';
|
||||
import type { ResizableTextAreaRef } from 'rc-textarea/lib/ResizableTextArea';
|
||||
import useMergedState from 'rc-util/lib/hooks/useMergedState';
|
||||
import omit from 'rc-util/lib/omit';
|
||||
import * as React from 'react';
|
||||
@ -56,7 +56,7 @@ export interface TextAreaProps extends RcTextAreaProps {
|
||||
export interface TextAreaRef {
|
||||
focus: (options?: InputFocusOptions) => void;
|
||||
blur: () => void;
|
||||
resizableTextArea?: ResizableTextArea;
|
||||
resizableTextArea?: ResizableTextAreaRef;
|
||||
}
|
||||
|
||||
const TextArea = React.forwardRef<TextAreaRef, TextAreaProps>(
|
||||
|
@ -4928,6 +4928,7 @@ Array [
|
||||
<textarea
|
||||
class="ant-input"
|
||||
placeholder="Autosize height based on content lines"
|
||||
style="height: 0px; resize: none;"
|
||||
/>,
|
||||
<div
|
||||
style="margin: 24px 0px;"
|
||||
@ -4935,6 +4936,7 @@ Array [
|
||||
<textarea
|
||||
class="ant-input"
|
||||
placeholder="Autosize height with minimum and maximum number of lines"
|
||||
style="height: -24px; resize: none; min-height: -8px; max-height: -24px;"
|
||||
/>,
|
||||
<div
|
||||
style="margin: 24px 0px;"
|
||||
@ -4942,6 +4944,7 @@ Array [
|
||||
<textarea
|
||||
class="ant-input"
|
||||
placeholder="Controlled autosize"
|
||||
style="height: -20px; resize: none; min-height: -12px; max-height: -20px;"
|
||||
/>,
|
||||
]
|
||||
`;
|
||||
|
@ -1145,6 +1145,7 @@ Array [
|
||||
<textarea
|
||||
class="ant-input"
|
||||
placeholder="Autosize height based on content lines"
|
||||
style="height: 0px; resize: none;"
|
||||
/>,
|
||||
<div
|
||||
style="margin: 24px 0px;"
|
||||
@ -1152,6 +1153,7 @@ Array [
|
||||
<textarea
|
||||
class="ant-input"
|
||||
placeholder="Autosize height with minimum and maximum number of lines"
|
||||
style="height: -24px; resize: none; min-height: -8px; max-height: -24px;"
|
||||
/>,
|
||||
<div
|
||||
style="margin: 24px 0px;"
|
||||
@ -1159,6 +1161,7 @@ Array [
|
||||
<textarea
|
||||
class="ant-input"
|
||||
placeholder="Controlled autosize"
|
||||
style="height: -20px; resize: none; min-height: -12px; max-height: -20px;"
|
||||
/>,
|
||||
]
|
||||
`;
|
||||
|
@ -3,8 +3,8 @@ import type { ChangeEventHandler, TextareaHTMLAttributes } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import Input from '..';
|
||||
import focusTest from '../../../tests/shared/focusTest';
|
||||
import { fireEvent, waitFakeTimer, render, sleep, triggerResize, pureRender } from '../../../tests/utils';
|
||||
import type { RenderOptions } from '../../../tests/utils';
|
||||
import { fireEvent, render, sleep, triggerResize } from '../../../tests/utils';
|
||||
import type { TextAreaRef } from '../TextArea';
|
||||
|
||||
const { TextArea } = Input;
|
||||
@ -29,10 +29,13 @@ describe('TextArea', () => {
|
||||
});
|
||||
|
||||
it('should auto calculate height according to content length', async () => {
|
||||
jest.useFakeTimers();
|
||||
|
||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
const ref = React.createRef<TextAreaRef>();
|
||||
|
||||
const onInternalAutoSize = jest.fn();
|
||||
const genTextArea = (props = {}) => (
|
||||
<TextArea
|
||||
value=""
|
||||
@ -41,27 +44,29 @@ describe('TextArea', () => {
|
||||
wrap="off"
|
||||
ref={ref}
|
||||
{...props}
|
||||
{...{ onInternalAutoSize }}
|
||||
/>
|
||||
);
|
||||
|
||||
const { container, rerender } = render(genTextArea());
|
||||
|
||||
const mockFunc = jest.spyOn(ref.current?.resizableTextArea!, 'resizeTextarea');
|
||||
const { container, rerender } = pureRender(genTextArea());
|
||||
await waitFakeTimer();
|
||||
expect(onInternalAutoSize).toHaveBeenCalledTimes(1);
|
||||
|
||||
rerender(genTextArea({ value: '1111\n2222\n3333' }));
|
||||
// wrapper.setProps({ value: '1111\n2222\n3333' });
|
||||
await sleep(0);
|
||||
expect(mockFunc).toHaveBeenCalledTimes(1);
|
||||
await waitFakeTimer();
|
||||
expect(onInternalAutoSize).toHaveBeenCalledTimes(2);
|
||||
|
||||
rerender(genTextArea({ value: '1111' }));
|
||||
// wrapper.setProps({ value: '1111' });
|
||||
await sleep(0);
|
||||
expect(mockFunc).toHaveBeenCalledTimes(2);
|
||||
await waitFakeTimer();
|
||||
expect(onInternalAutoSize).toHaveBeenCalledTimes(3);
|
||||
|
||||
expect(container.querySelector('textarea')?.style.overflow).toBeFalsy();
|
||||
|
||||
expect(errorSpy).not.toHaveBeenCalled();
|
||||
errorSpy.mockRestore();
|
||||
|
||||
jest.clearAllTimers();
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('should support onPressEnter and onKeyDown', () => {
|
||||
@ -188,14 +193,6 @@ describe('TextArea', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('when prop value not in this.props, resizeTextarea should be called', async () => {
|
||||
const ref = React.createRef<TextAreaRef>();
|
||||
const { container } = render(<TextArea aria-label="textarea" ref={ref} />);
|
||||
const resizeTextarea = jest.spyOn(ref.current?.resizableTextArea!, 'resizeTextarea');
|
||||
fireEvent.change(container.querySelector('textarea')!, { target: { value: 'test' } });
|
||||
expect(resizeTextarea).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('handleKeyDown', () => {
|
||||
const onPressEnter = jest.fn();
|
||||
const onKeyDown = jest.fn();
|
||||
@ -209,17 +206,21 @@ describe('TextArea', () => {
|
||||
});
|
||||
|
||||
it('should trigger onResize', async () => {
|
||||
jest.useFakeTimers();
|
||||
const onResize = jest.fn();
|
||||
const ref = React.createRef<TextAreaRef>();
|
||||
render(<TextArea ref={ref} onResize={onResize} autoSize />);
|
||||
await sleep(100);
|
||||
const target = ref.current?.resizableTextArea?.textArea!;
|
||||
triggerResize(target);
|
||||
await Promise.resolve();
|
||||
const { container } = render(<TextArea ref={ref} onResize={onResize} autoSize />);
|
||||
await waitFakeTimer();
|
||||
|
||||
triggerResize(container.querySelector('textarea')!);
|
||||
await waitFakeTimer();
|
||||
|
||||
expect(onResize).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ width: expect.any(Number), height: expect.any(Number) }),
|
||||
);
|
||||
|
||||
jest.clearAllTimers();
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('should works same as Input', () => {
|
||||
|
@ -20,6 +20,7 @@ exports[`renders ./components/mentions/demo/autoSize.md extend context correctly
|
||||
<textarea
|
||||
class="rc-textarea"
|
||||
rows="1"
|
||||
style="height: 0px; resize: none;"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
@ -20,6 +20,7 @@ exports[`renders ./components/mentions/demo/autoSize.md correctly 1`] = `
|
||||
<textarea
|
||||
class="rc-textarea"
|
||||
rows="1"
|
||||
style="height: 0px; resize: none;"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
@ -134,7 +134,7 @@
|
||||
"rc-image": "~5.7.0",
|
||||
"rc-input": "~0.1.2",
|
||||
"rc-input-number": "~7.3.9",
|
||||
"rc-mentions": "~1.9.1",
|
||||
"rc-mentions": "~1.10.0",
|
||||
"rc-menu": "~9.6.3",
|
||||
"rc-motion": "^2.6.1",
|
||||
"rc-notification": "~4.6.0",
|
||||
@ -150,7 +150,7 @@
|
||||
"rc-switch": "~3.2.0",
|
||||
"rc-table": "~7.26.0",
|
||||
"rc-tabs": "~12.1.0-alpha.1",
|
||||
"rc-textarea": "~0.3.0",
|
||||
"rc-textarea": "~0.4.3",
|
||||
"rc-tooltip": "~5.2.0",
|
||||
"rc-tree": "~5.7.0",
|
||||
"rc-tree-select": "~5.5.0",
|
||||
|
Loading…
Reference in New Issue
Block a user