ant-design/components/input/TextArea.tsx
Rustin 767d2d0638 feat: Add allowClear to TextArea (#19310)
* 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
2019-11-01 18:19:29 +08:00

129 lines
3.4 KiB
TypeScript

import * as React from 'react';
import { polyfill } from 'react-lifecycles-compat';
import ClearableLabeledInput from './ClearableLabeledInput';
import ResizableTextArea, { AutoSizeType } from './ResizableTextArea';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import { fixControlledValue, resolveOnChange } from './Input';
export type HTMLTextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>;
export interface TextAreaProps extends HTMLTextareaProps {
prefixCls?: string;
/* deprecated, use autoSize instead */
autosize?: boolean | AutoSizeType;
autoSize?: boolean | AutoSizeType;
onPressEnter?: React.KeyboardEventHandler<HTMLTextAreaElement>;
allowClear?: boolean;
}
export interface TextAreaState {
value: any;
}
class TextArea extends React.Component<TextAreaProps, TextAreaState> {
resizableTextArea: ResizableTextArea;
clearableInput: ClearableLabeledInput;
constructor(props: TextAreaProps) {
super(props);
const value = typeof props.value === 'undefined' ? props.defaultValue : props.value;
this.state = {
value,
};
}
static getDerivedStateFromProps(nextProps: TextAreaProps) {
if ('value' in nextProps) {
return {
value: nextProps.value,
};
}
return null;
}
setValue(value: string, callback?: () => void) {
if (!('value' in this.props)) {
this.setState({ value }, callback);
}
}
focus() {
this.resizableTextArea.textArea.focus();
}
blur() {
this.resizableTextArea.textArea.blur();
}
saveTextArea = (resizableTextArea: ResizableTextArea) => {
this.resizableTextArea = resizableTextArea;
};
saveClearableInput = (clearableInput: ClearableLabeledInput) => {
this.clearableInput = clearableInput;
};
handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
this.setValue(e.target.value, () => {
this.resizableTextArea.resizeTextarea();
});
resolveOnChange(this.resizableTextArea.textArea, e, this.props.onChange);
};
handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
const { onPressEnter, onKeyDown } = this.props;
if (e.keyCode === 13 && onPressEnter) {
onPressEnter(e);
}
if (onKeyDown) {
onKeyDown(e);
}
};
handleReset = (e: React.MouseEvent<HTMLElement, MouseEvent>) => {
this.setValue('', () => {
this.resizableTextArea.renderTextArea();
this.focus();
});
resolveOnChange(this.resizableTextArea.textArea, e, this.props.onChange);
};
renderTextArea = (prefixCls: string) => {
return (
<ResizableTextArea
{...this.props}
prefixCls={prefixCls}
onKeyDown={this.handleKeyDown}
onChange={this.handleChange}
ref={this.saveTextArea}
/>
);
};
renderComponent = ({ getPrefixCls }: ConfigConsumerProps) => {
const { value } = this.state;
const { prefixCls: customizePrefixCls } = this.props;
const prefixCls = getPrefixCls('input', customizePrefixCls);
return (
<ClearableLabeledInput
{...this.props}
prefixCls={prefixCls}
inputType="text"
value={fixControlledValue(value)}
element={this.renderTextArea(prefixCls)}
handleReset={this.handleReset}
ref={this.saveClearableInput}
/>
);
};
render() {
return <ConfigConsumer>{this.renderComponent}</ConfigConsumer>;
}
}
polyfill(TextArea);
export default TextArea;