ant-design/components/cascader/index.jsx

112 lines
3.2 KiB
React
Raw Normal View History

2015-12-29 11:46:13 +08:00
import React from 'react';
import Cascader from 'rc-cascader';
import Input from '../input';
2015-12-29 21:18:27 +08:00
import Icon from '../icon';
2015-12-29 11:46:13 +08:00
import arrayTreeFilter from 'array-tree-filter';
2015-12-29 18:31:48 +08:00
import classNames from 'classnames';
2015-12-29 11:46:13 +08:00
class AntCascader extends React.Component {
constructor(props) {
super(props);
this.state = {
2015-12-29 21:18:27 +08:00
value: props.value || props.defaultValue || [],
popupVisible: false,
2015-12-29 11:46:13 +08:00
};
[
'handleChange',
2015-12-29 21:18:27 +08:00
'handlePopupVisibleChange',
'setValue',
2015-12-29 11:46:13 +08:00
'getLabel',
2015-12-29 21:18:27 +08:00
'clearSelection',
2015-12-29 11:46:13 +08:00
].forEach((method) => this[method] = this[method].bind(this));
}
2015-12-29 21:18:27 +08:00
componentWillReceiveProps(nextProps) {
if ('value' in nextProps) {
2016-01-06 11:45:47 +08:00
this.setState({ value: nextProps.value || [] });
2015-12-29 21:18:27 +08:00
}
}
2015-12-29 11:46:13 +08:00
handleChange(value, selectedOptions) {
2015-12-29 21:18:27 +08:00
this.setValue(value, selectedOptions);
}
handlePopupVisibleChange(popupVisible) {
this.setState({ popupVisible });
this.props.onPopupVisibleChange(popupVisible);
}
setValue(value, selectedOptions = []) {
if (!('value' in this.props)) {
this.setState({ value });
}
2015-12-29 11:46:13 +08:00
this.props.onChange(value, selectedOptions);
}
getLabel() {
const { options, displayRender } = this.props;
const label = arrayTreeFilter(options, (o, level) => o.value === this.state.value[level])
.map(o => o.label);
return displayRender(label);
}
2015-12-29 21:18:27 +08:00
clearSelection(e) {
e.preventDefault();
2015-12-29 22:34:23 +08:00
e.stopPropagation();
2015-12-29 21:18:27 +08:00
this.setValue([]);
this.setState({ popupVisible: false });
}
2015-12-29 11:46:13 +08:00
render() {
const { prefixCls, children, placeholder, size, disabled, className } = this.props;
2015-12-29 18:31:48 +08:00
const sizeCls = classNames({
'ant-input-lg': size === 'large',
'ant-input-sm': size === 'small',
});
2015-12-29 21:18:27 +08:00
const clearIcon = this.state.value.length > 0 ?
<Icon type="cross-circle"
className={`${prefixCls}-picker-clear`}
onClick={this.clearSelection} /> : null;
2015-12-29 22:34:23 +08:00
const arrowCls = classNames({
[`${prefixCls}-picker-arrow`]: true,
[`${prefixCls}-picker-arrow-expand`]: this.state.popupVisible,
});
2016-01-05 11:31:22 +08:00
const pickerCls = classNames({
[className]: !!className,
2016-01-05 11:31:22 +08:00
[`${prefixCls}-picker`]: true,
[`${prefixCls}-picker-disabled`]: disabled,
});
2015-12-29 11:46:13 +08:00
return (
2015-12-29 21:18:27 +08:00
<Cascader {...this.props}
value={this.state.value}
popupVisible={this.state.popupVisible}
onPopupVisibleChange={this.handlePopupVisibleChange}
onChange={this.handleChange}>
2015-12-29 11:46:13 +08:00
{children ||
2016-01-04 19:23:19 +08:00
<span
{...this.props}
2016-01-05 11:31:22 +08:00
className={pickerCls}>
2015-12-29 21:18:27 +08:00
<Input placeholder={placeholder}
className={`${prefixCls}-input ant-input ${sizeCls}`}
2016-01-05 14:42:06 +08:00
style={{ width: '100%' }}
2015-12-29 21:18:27 +08:00
value={this.getLabel()}
2016-01-05 11:31:22 +08:00
disabled={disabled}
2015-12-29 21:18:27 +08:00
readOnly />
{clearIcon}
2015-12-29 22:34:23 +08:00
<Icon type="down" className={arrowCls} />
2015-12-29 21:18:27 +08:00
</span>
}
2015-12-29 11:46:13 +08:00
</Cascader>
);
}
}
AntCascader.defaultProps = {
prefixCls: 'ant-cascader',
placeholder: '请选择',
transitionName: 'slide-up',
2016-02-19 11:31:45 +08:00
popupPlacement: 'bottomLeft',
2015-12-29 11:46:13 +08:00
onChange() {},
options: [],
displayRender(label) {
return label.join(' / ');
},
2016-01-05 11:31:22 +08:00
disabled: false,
2015-12-29 21:18:27 +08:00
onPopupVisibleChange() {},
2015-12-29 11:46:13 +08:00
};
export default AntCascader;