1. Optimize prefix and suffix implementation

2. Improve the api document
3. Optimize `Input.Search` implementation
This commit is contained in:
Rex 2017-01-01 00:12:05 +08:00
parent 9a0db3e92c
commit b7621c986f
6 changed files with 150 additions and 11 deletions

View File

@ -49,6 +49,7 @@ export interface InputProps {
onKeyDown?: React.FormEventHandler<any>;
onChange?: React.FormEventHandler<any>;
onClick?: React.FormEventHandler<any>;
onFocus?: React.FormEventHandler<any>;
onBlur?: React.FormEventHandler<any>;
autosize?: boolean | AutoSizeType;
autoComplete?: 'on' | 'off';
@ -84,6 +85,8 @@ export default class Input extends Component<InputProps, any> {
autosize: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
onPressEnter: PropTypes.func,
onKeyDown: PropTypes.func,
onFocus: PropTypes.func,
onBlur: PropTypes.func,
prefix: PropTypes.node,
suffix: PropTypes.node,
};
@ -95,6 +98,7 @@ export default class Input extends Component<InputProps, any> {
state = {
textareaStyles: null,
isFocus: false,
};
componentDidMount() {
@ -111,6 +115,35 @@ export default class Input extends Component<InputProps, any> {
}
}
componentDidUpdate(prevProps) {
const { props, state, refs } = this;
const preHasPresuffix = prevProps.prefix || prevProps.suffix;
const curHasPresuffix = props.prefix || props.suffix;
if (state.isFocus && (preHasPresuffix !== curHasPresuffix)) {
refs.input.focus();
}
}
handleFocus = (e) => {
const { onFocus } = this.props;
this.setState({
isFocus: true,
});
if (onFocus) {
onFocus(e);
}
}
handleBlur = (e) => {
const { onBlur } = this.props;
this.setState({
isFocus: false,
});
if (onBlur) {
onBlur(e);
}
}
handleKeyDown = (e) => {
const { onPressEnter, onKeyDown } = this.props;
if (e.keyCode === 13 && onPressEnter) {
@ -258,6 +291,8 @@ export default class Input extends Component<InputProps, any> {
{...otherProps}
className={inputClassName}
onKeyDown={this.handleKeyDown}
onFocus={this.handleFocus}
onBlur={this.handleBlur}
ref="input"
/>
);

View File

@ -39,19 +39,22 @@ export default class Search extends React.Component<SearchProps, any> {
const wrapperCls = classNames({
[`${prefixCls}-wrapper`]: true,
}, className);
const searchSuffix = (
<Icon
className={`${prefixCls}-icon`}
onClick={this.onSearch}
type="search"
/>
);
return (
<div className={wrapperCls} style={style}>
<Input
className={prefixCls}
onPressEnter={this.onSearch}
ref={node => this.input = node}
suffix={searchSuffix}
{...others}
/>
<Icon
className={`${prefixCls}-icon`}
onClick={this.onSearch}
type="search"
/>
</div>
);
}

View File

@ -0,0 +1,103 @@
---
order: 8
title:
zh-CN: 前缀和后缀
en-US: prefix and suffix
---
## zh-CN
在输入框上添加前缀或后缀图标。
## en-US
Add a prefix or suffix icon on the input.
````jsx
import { Input, Icon } from 'antd';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
userName: '',
domain: '',
};
this.onChangeUserName = this.emitChange.bind(this, 'userName');
this.onChangeDomain = this.emitChange.bind(this, 'domain');
}
emitEmpty(type) {
this[`${type}Input`].focus();
this.setState({
[type]: '',
});
}
emitChange(type, e) {
this.setState({
[type]: e.target.value,
});
}
renderClearIcon(type) {
const value = this.state[type];
const empty = this.emitEmpty.bind(this, type);
return value ? (
<Icon
type="close-circle"
onClick={empty}
/>
) : null;
}
renderUserNameInput() {
const { userName } = this.state;
return (
<div style={{ marginBottom: 16 }}>
<Input
placeholder="Enter your userName"
prefix={<Icon type="user" />}
suffix={this.renderClearIcon('userName')}
value={userName}
onChange={this.onChangeUserName}
ref={node => this.userNameInput = node}
/>
</div>
);
}
renderDomainInput() {
const { domain } = this.state;
return (
<div style={{ marginBottom: 16 }}>
<Input
placeholder="Input your domain"
addonBefore="Http://"
addonAfter=".com"
suffix={this.renderClearIcon('domain')}
value={domain}
onChange={this.onChangeDomain}
ref={node => this.domainInput = node}
/>
</div>
);
}
render() {
return (
<div>
{this.renderUserNameInput()}
{this.renderDomainInput()}
</div>
);
}
}
ReactDOM.render(<App />, mountNode);
````
````css
.anticon-close-circle {
cursor: pointer;
color: #ccc;
transition: color 0.3s;
}
.anticon-close-circle:hover {
color: #999;
}
````

View File

@ -26,6 +26,8 @@ Keyboard and mouse can be used for providing or changing data.
| disabled | Tell if the input is disabled. | boolean | false |
| addonBefore | The label text displayed before (on the left side of) the input field. | React.Node | |
| addonAfter | The label text displayed after (on the right side of) the input field. | React.Node | |
| prefix | The Input with prefix icon. | React.Node | |
| suffix | The Input with suffix icon. | React.Node | |
| onPressEnter | The callback function that is triggered when pressing Enter key. | function(e) | |
| autosize | Height autosize feature, available when type="textarea", can be set to `true|false` or a object `{ minRows: 2, maxRows: 6 }` | boolean or object | false |

View File

@ -26,6 +26,8 @@ title: Input
| disabled | 是否禁用状态,默认为 false | boolean | false |
| addonBefore | 带标签的 input设置前置标签 | React.Node | |
| addonAfter | 带标签的 input设置后置标签 | React.Node | |
| prefix | 带有前缀图标的 input | React.Node | |
| suffix | 带有后缀图标的 input | React.Node | |
| onPressEnter | 按下回车的回调 | function(e) | |
| autosize | 自适应内容高度,只对 `type="textarea"` 有效,可设置为 `true|false` 或对象:`{ minRows: 2, maxRows: 6 }` | boolean or object | false |

View File

@ -10,15 +10,9 @@
.@{ant-prefix}-input-search {
transition: all .3s ease;
&-icon {
position: absolute;
right: 8px;
cursor: pointer;
transition: all .3s ease;
font-size: 14px;
height: 20px;
line-height: 20px;
top: 50%;
margin-top: -10px;
&:hover {
color: @input-hover-border-color;
}