cuz
Version:
Front-end modular development kit.
208 lines (193 loc) • 5.11 kB
JavaScript
import React, { cloneElement } from 'react';
import Button from '../Button';
import classNames from 'classnames';
import {utils} from 'react-bootstrap';
import CategoryGroup from './CategoryGroup';
import CategoryItem from './CategoryItem';
function getChildLength(data, length) {
if (data[0].children === undefined) {
return length;
}
return getChildLength(data[0].children, length + 1);
}
function getChild(index, start, key, indexArray) {
if ( index < 1 ) {
return key;
}
if (indexArray[start] === undefined) {
indexArray[start] = 0;
}
return getChild(index - 1, start + 1, key[indexArray[start]].children, indexArray);
}
const Category = React.createClass({
propTypes: {
children: React.PropTypes.any,
className: React.PropTypes.string,
confirmButton: React.PropTypes.bool,
cancelButton: React.PropTypes.bool,
onSelect: React.PropTypes.func,
onCancel: React.PropTypes.func,
onHover: React.PropTypes.func,
hide: React.PropTypes.bool,
open: React.PropTypes.bool,
triggerType: React.PropTypes.string,
confirmText: React.PropTypes.string,
cancelText: React.PropTypes.string,
data: React.PropTypes.array,
},
getDefaultProps() {
return {
confirmButton: false,
cancelButton: false,
triggerType: 'click',
confirmText: '确认',
cancelText: '取消',
};
},
getInitialState() {
return {
selected: {},
cateLevel: 0,
indexArray: [],
};
},
onSelect(key, children, level, index, event) {
const { onSelect, confirmButton, triggerType } = this.props;
const indexArray = this.state.indexArray.concat();
indexArray[level] = index;
if ( triggerType === 'click') {
this.setState({
cateLevel: level + 1,
indexArray: indexArray,
});
}
if (confirmButton) {
this.setState({
selected: {
key,
index,
children,
level,
event,
}
});
} else {
onSelect(key, children, level, index, event);
}
},
onHover(key, children, level, index, event) {
const { onHover, triggerType } = this.props;
const indexArray = this.state.indexArray.concat();
indexArray[level] = index;
if (triggerType === 'hover') {
this.setState({
cateLevel: level + 1,
indexArray: indexArray,
});
}
if (onHover) {
onHover(key, children, level, index, event);
}
},
onConfirm() {
const { key, children, level, index, event } = this.state.selected;
const { onSelect } = this.props;
if (onSelect) {
onSelect(key, children, level, index, event);
}
},
onCancel() {
const { onCancel } = this.props;
if (onCancel) {
onCancel();
}
},
renderGroup(child, index) {
const { triggerType, onHover } = this.props;
return cloneElement(
child,
{
level: index,
onSelect: this.onSelect,
onHover,
triggerType,
}
);
},
renderItem(level) {
const { data } = this.props;
const child = getChild(level, 0, data, this.state.indexArray);
const items = [];
if (child) {
child.map((item, num)=>{
items.push(
<CategoryItem
index={num}
key={item.id}
id={item.id}
onSelect={this.onSelect}
child={item.children}>
{
item.name
}
</CategoryItem>
);
});
}
return items;
},
renderCategory() {
const category = [];
const { data, open } = this.props;
let cateLevel;
if (open) {
cateLevel = getChildLength(data, 0);
} else {
cateLevel = this.state.cateLevel;
}
for (let index = 0; index <= cateLevel; index++) {
category.push(
<CategoryGroup
key={index}
level={index}
onSelect={this.onSelect}
onHover={this.onHover}
triggerType={this.props.triggerType}>
{this.renderItem(index)}
</CategoryGroup>
);
}
return category;
},
render() {
const { className, children, confirmButton, cancelButton, hide, confirmText, cancelText, data, ...props } = this.props;
return (
<div className={
classNames(
'category-container',
{'hide': hide},
className
)}>
<div className={
classNames(
'category',
{'has-button': confirmButton || cancelButton},
)
} { ...props }>
{data === undefined ? utils.ValidComponentChildren.map(this.props.children, this.renderGroup) : this.renderCategory() }
</div>
<div className="category-footer">
{
confirmButton &&
<Button bsStyle="primary" onClick={this.onConfirm} bsSize="small">{confirmText}</Button>
}
{
cancelButton &&
<Button onClick={this.onCancel} bsSize="small">{cancelText}</Button>
}
</div>
</div>
);
}
});
export default Category;