mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-30 06:09:34 +08:00
767d2d0638
* add allow clear to textarea revert textarea md refactor textarea css fix textarea props bug add test and update snapshot update doc add margin refactor textarea to reuse fixControlledValue and setValue method add clearable input to reuse code refactor clearable input finish refactor refactor clearable input refactor input and textArea finish refactor update test snapshots fix input props bug fix dom issue fix textarea dom issue fix textarea test bug fix textarea dom issue refactor code and fix textarea dom issue fix input dom issue fix typo error update test snapshots fix ci failed issues adjust margin * remove useless code fix ci failed issue * fix textarea padding issue * update snapshots * fix padding issue
121 lines
3.3 KiB
TypeScript
121 lines
3.3 KiB
TypeScript
import * as React from 'react';
|
|
import { polyfill } from 'react-lifecycles-compat';
|
|
import ResizeObserver from 'rc-resize-observer';
|
|
import omit from 'omit.js';
|
|
import classNames from 'classnames';
|
|
import calculateNodeHeight from './calculateNodeHeight';
|
|
import raf from '../_util/raf';
|
|
import warning from '../_util/warning';
|
|
import { TextAreaProps } from './TextArea';
|
|
|
|
export interface AutoSizeType {
|
|
minRows?: number;
|
|
maxRows?: number;
|
|
}
|
|
|
|
export interface TextAreaState {
|
|
textareaStyles?: React.CSSProperties;
|
|
/** We need add process style to disable scroll first and then add back to avoid unexpected scrollbar */
|
|
resizing?: boolean;
|
|
}
|
|
|
|
class ResizableTextArea extends React.Component<TextAreaProps, TextAreaState> {
|
|
nextFrameActionId: number;
|
|
|
|
resizeFrameId: number;
|
|
|
|
constructor(props: TextAreaProps) {
|
|
super(props);
|
|
this.state = {
|
|
textareaStyles: {},
|
|
resizing: false,
|
|
};
|
|
}
|
|
|
|
textArea: HTMLTextAreaElement;
|
|
|
|
saveTextArea = (textArea: HTMLTextAreaElement) => {
|
|
this.textArea = textArea;
|
|
};
|
|
|
|
componentDidMount() {
|
|
this.resizeTextarea();
|
|
}
|
|
|
|
componentDidUpdate(prevProps: TextAreaProps) {
|
|
// Re-render with the new content then recalculate the height as required.
|
|
if (prevProps.value !== this.props.value) {
|
|
this.resizeTextarea();
|
|
}
|
|
}
|
|
|
|
resizeOnNextFrame = () => {
|
|
raf.cancel(this.nextFrameActionId);
|
|
this.nextFrameActionId = raf(this.resizeTextarea);
|
|
};
|
|
|
|
resizeTextarea = () => {
|
|
const autoSize = this.props.autoSize || this.props.autosize;
|
|
if (!autoSize || !this.textArea) {
|
|
return;
|
|
}
|
|
const { minRows, maxRows } = autoSize as AutoSizeType;
|
|
const textareaStyles = calculateNodeHeight(this.textArea, false, minRows, maxRows);
|
|
this.setState({ textareaStyles, resizing: true }, () => {
|
|
raf.cancel(this.resizeFrameId);
|
|
this.resizeFrameId = raf(() => {
|
|
this.setState({ resizing: false });
|
|
});
|
|
});
|
|
};
|
|
|
|
componentWillUnmount() {
|
|
raf.cancel(this.nextFrameActionId);
|
|
raf.cancel(this.resizeFrameId);
|
|
}
|
|
|
|
renderTextArea = () => {
|
|
const { prefixCls, autoSize, autosize, className, disabled } = this.props;
|
|
const { textareaStyles, resizing } = this.state;
|
|
warning(
|
|
autosize === undefined,
|
|
'Input.TextArea',
|
|
'autosize is deprecated, please use autoSize instead.',
|
|
);
|
|
const otherProps = omit(this.props, [
|
|
'prefixCls',
|
|
'onPressEnter',
|
|
'autoSize',
|
|
'autosize',
|
|
'defaultValue',
|
|
'allowClear',
|
|
]);
|
|
const cls = classNames(prefixCls, className, {
|
|
[`${prefixCls}-disabled`]: disabled,
|
|
});
|
|
// Fix https://github.com/ant-design/ant-design/issues/6776
|
|
// Make sure it could be reset when using form.getFieldDecorator
|
|
if ('value' in otherProps) {
|
|
otherProps.value = otherProps.value || '';
|
|
}
|
|
const style = {
|
|
...this.props.style,
|
|
...textareaStyles,
|
|
...(resizing ? { overflow: 'hidden' } : null),
|
|
};
|
|
return (
|
|
<ResizeObserver onResize={this.resizeOnNextFrame} disabled={!(autoSize || autosize)}>
|
|
<textarea {...otherProps} className={cls} style={style} ref={this.saveTextArea} />
|
|
</ResizeObserver>
|
|
);
|
|
};
|
|
|
|
render() {
|
|
return this.renderTextArea();
|
|
}
|
|
}
|
|
|
|
polyfill(ResizableTextArea);
|
|
|
|
export default ResizableTextArea;
|