diff --git a/components/input/Input.tsx b/components/input/Input.tsx index b3e9b114bd..3fe4fd5fab 100644 --- a/components/input/Input.tsx +++ b/components/input/Input.tsx @@ -1,10 +1,10 @@ -import React from 'react'; -import { Component, cloneElement } from 'react'; +import React, { Component, cloneElement } from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; -import calculateNodeHeight from './calculateNodeHeight'; -import assign from 'object-assign'; import omit from 'omit.js'; +import Group from './Group'; +import Search from './Search'; +import TextArea from './TextArea'; function fixControlledValue(value) { if (typeof value === 'undefined' || value === null) { @@ -13,49 +13,31 @@ function fixControlledValue(value) { return value; } -function onNextFrame(cb) { - if (window.requestAnimationFrame) { - return window.requestAnimationFrame(cb); - } - return window.setTimeout(cb, 1); -} - -function clearNextFrameAction(nextFrameId) { - if (window.cancelAnimationFrame) { - window.cancelAnimationFrame(nextFrameId); - } else { - window.clearTimeout(nextFrameId); - } -} - -export interface AutoSizeType { - minRows?: number; - maxRows?: number; -} - -export interface InputProps { +export interface AbstractInputProps { prefixCls?: string; className?: string; + defaultValue?: any; + value?: any; + style?: React.CSSProperties; +} + +export interface InputProps extends AbstractInputProps { + placeholder?: string; type?: string; id?: number | string; name?: string; - value?: any; - defaultValue?: any; - placeholder?: string; size?: 'large' | 'default' | 'small'; disabled?: boolean; readOnly?: boolean; addonBefore?: React.ReactNode; addonAfter?: React.ReactNode; + onPressEnter?: React.FormEventHandler; onKeyDown?: React.FormEventHandler; onChange?: React.FormEventHandler; - onPressEnter?: React.FormEventHandler; onClick?: React.FormEventHandler; onFocus?: React.FormEventHandler; onBlur?: React.FormEventHandler; - autosize?: boolean | AutoSizeType; autoComplete?: 'on' | 'off'; - style?: React.CSSProperties; prefix?: React.ReactNode; suffix?: React.ReactNode; spellCheck?: boolean; @@ -63,13 +45,14 @@ export interface InputProps { } export default class Input extends Component { - static Group: any; - static Search: any; + static Group: typeof Group; + static Search: typeof Search; + static TextArea: typeof TextArea; + static defaultProps = { - disabled: false, prefixCls: 'ant-input', type: 'text', - autosize: false, + disabled: false, }; static propTypes = { @@ -95,30 +78,10 @@ export default class Input extends Component { suffix: PropTypes.node, }; - nextFrameActionId: number; refs: { - input: any; + input: HTMLInputElement; }; - state = { - textareaStyles: null, - isFocus: false, - }; - - componentDidMount() { - this.resizeTextarea(); - } - - componentWillReceiveProps(nextProps) { - // Re-render with the new content then recalculate the height as required. - if (this.props.value !== nextProps.value) { - if (this.nextFrameActionId) { - clearNextFrameAction(this.nextFrameActionId); - } - this.nextFrameActionId = onNextFrame(this.resizeTextarea); - } - } - handleKeyDown = (e) => { const { onPressEnter, onKeyDown } = this.props; if (e.keyCode === 13 && onPressEnter) { @@ -129,36 +92,18 @@ export default class Input extends Component { } } - handleTextareaChange = (e) => { - if (!('value' in this.props)) { - this.resizeTextarea(); - } - const onChange = this.props.onChange; - if (onChange) { - onChange(e); - } - } - - resizeTextarea = () => { - const { type, autosize } = this.props; - if (type !== 'textarea' || !autosize || !this.refs.input) { - return; - } - const minRows = autosize ? (autosize as AutoSizeType).minRows : null; - const maxRows = autosize ? (autosize as AutoSizeType).maxRows : null; - const textareaStyles = calculateNodeHeight(this.refs.input, false, minRows, maxRows); - this.setState({ textareaStyles }); - } - focus() { this.refs.input.focus(); } + blur() { + this.refs.input.blur(); + } + renderLabeledInput(children) { const props = this.props; - // Not wrap when there is not addons - if (props.type === 'textarea' || (!props.addonBefore && !props.addonAfter)) { + if ((!props.addonBefore && !props.addonAfter)) { return children; } @@ -207,8 +152,7 @@ export default class Input extends Component { renderLabeledIcon(children) { const { props } = this; - - if (props.type === 'textarea' || !('prefix' in props || 'suffix' in props)) { + if (!('prefix' in props || 'suffix' in props)) { return children; } @@ -234,12 +178,11 @@ export default class Input extends Component { } renderInput() { - const props = assign({}, this.props); + const props = this.props; // Fix https://fb.me/react-unknown-prop - const otherProps = omit(this.props, [ + const otherProps = omit(props, [ 'prefixCls', 'onPressEnter', - 'autosize', 'addonBefore', 'addonAfter', 'prefix', @@ -247,10 +190,6 @@ export default class Input extends Component { ]); const prefixCls = props.prefixCls; - if (!props.type) { - return props.children; - } - const inputClassName = classNames(prefixCls, { [`${prefixCls}-sm`]: props.size === 'small', [`${prefixCls}-lg`]: props.size === 'large', @@ -262,32 +201,20 @@ export default class Input extends Component { // specify either the value prop, or the defaultValue prop, but not both. delete otherProps.defaultValue; } - - switch (props.type) { - case 'textarea': - return ( -