fk-react-ui-components
Version:
Step 1 : Create a file in [ Seeds / Plants / Trees ] <br> Step 2 : It should export an Object with component name and story Component [Refer other components] <br> Step 3 : Story Component should return a react component <br> Step 3 : Created file should
260 lines (223 loc) • 7.74 kB
JavaScript
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
/**
* Created by manoraj.k on 17/08/17.
*/
import React from 'react';
import _ from 'lodash';
import PropTypes from 'prop-types';
import { CheckboxTreeContainer } from './styles/checkbox-tree';
import CheckboxTreeItem from './js/tree-item';
class CheckboxTree extends React.Component {
static getDisabledState(node, parent, disabledProp, noCascade) {
if (disabledProp || !noCascade && parent.disabled) {
return true;
}
return false;
}
constructor(props) {
super(props);
this.valueNodesMap = {};
_.bindAll(this, 'addNodesToMap', 'unserializeLists', 'renderItems', 'renderChilds', 'onCheck', 'onExpand', 'prepareNodes');
this.prepareNodes(props.nodes, props.checked, props.expanded);
}
componentWillReceiveProps({ nodes, checked, expanded }) {
if (!_.isEqual(this.props.nodes, nodes)) {
this.addNodesToMap(nodes);
}
this.unserializeLists({ checked, expanded });
}
onExpand(node) {
const { onExpand } = this.props;
this.toggleNode('expanded', node, node.expanded);
onExpand(this.serializeList('expanded'));
}
onCheck(node) {
const { noCascade, onCheck } = this.props;
this.toggleChecked(node, node.checked, noCascade);
onCheck(this.serializeList('checked'));
}
getCheckState(node, noCascade) {
if (node.children === null || noCascade) {
return node.checked ? 1 : 0;
}
if (this.isEveryChildChecked(node)) {
return 1;
}
if (this.isSomeChildChecked(node)) {
return 2;
}
return 0;
}
getFormattedNodes(nodes) {
return _.map(nodes, node => {
const formatted = _extends({}, node);
formatted.checked = this.valueNodesMap[node.value].checked;
formatted.expanded = this.valueNodesMap[node.value].expanded;
if (_.isArray(node.children) && node.children.length > 0) {
formatted.children = this.getFormattedNodes(formatted.children);
} else {
formatted.children = null;
}
return formatted;
});
}
isEveryChildChecked(node) {
return _.every(node.children, child => {
if (child.children !== null) {
return this.isEveryChildChecked(child);
}
return child.checked;
});
}
isSomeChildChecked(node) {
return _.some(node.children, child => {
if (child.children !== null) {
return this.isSomeChildChecked(child);
}
return child.checked;
});
}
addNodesToMap(nodes) {
if (!_.isArray(nodes) || nodes.length === 0) {
return;
}
_.each(nodes, node => {
this.valueNodesMap[node.value] = {};
this.addNodesToMap(node.children);
});
}
serializeList(key) {
const list = [];
Object.keys(this.valueNodesMap).forEach(value => {
if (this.valueNodesMap[value][key]) {
list.push(value);
}
});
return list;
}
unserializeLists(nodeProperties) {
_.each(nodeProperties, (nodeNames, key) => {
_.each(this.valueNodesMap, node => {
node[key] = false;
});
});
_.each(nodeProperties, (nodeNames, key) => {
_.each(nodeNames, nodeName => {
this.valueNodesMap[nodeName][key] = true;
});
});
}
prepareNodes(nodes, checked, expanded) {
this.addNodesToMap(nodes);
this.unserializeLists({
checked,
expanded
});
}
toggleNode(key, node, toggleValue) {
this.valueNodesMap[node.value][key] = toggleValue;
}
toggleChecked(node, isChecked, noCascade) {
if (node.children === null || noCascade) {
// Set the check status of a leaf node or an uncoupled parent
this.toggleNode('checked', node, isChecked);
} else {
// Percolate check status down to all children
node.children.forEach(child => {
this.toggleChecked(child, isChecked);
});
}
}
renderChilds(node) {
if (node.children !== null && node.expanded) {
return this.renderItems(node.children, node);
}
return null;
}
renderItems(nodes, parentNode = {}) {
const {
disabled,
expandDisabled,
noCascade,
getCollapseIcon,
getCheckboxIcon,
labelClassName
} = this.props;
const treeNodes = nodes.map(node => {
const key = `${node.value}`;
const checked = this.getCheckState(node, noCascade);
const children = this.renderChilds(node);
const nodeDisabled = CheckboxTree.getDisabledState(node, parentNode, disabled, noCascade);
return React.createElement(
CheckboxTreeItem,
{
key: key,
checked: checked,
className: node.className,
disabled: nodeDisabled,
expandDisabled: expandDisabled,
expanded: node.expanded,
getCollapseIcon: getCollapseIcon,
getCheckboxIcon: getCheckboxIcon,
label: node.label,
value: node.value,
onCheck: this.onCheck,
onExpand: this.onExpand,
listChildren: node.children,
labelClassName: labelClassName,
noCheckbox: node.noCheckbox
},
children
);
});
return React.createElement(
'ol',
null,
treeNodes
);
}
render() {
const nodes = this.getFormattedNodes(this.props.nodes);
const treeNodes = this.renderItems(nodes);
return React.createElement(
CheckboxTreeContainer,
{
width: this.props.width,
maxHeight: this.props.height,
className: this.props.className
},
treeNodes
);
}
}
export default CheckboxTree;
CheckboxTree.propTypes = {
nodes: PropTypes.arrayOf(PropTypes.shape({
label: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
className: PropTypes.string,
children: PropTypes.array
})).isRequired,
checked: PropTypes.arrayOf(PropTypes.string).isRequired,
expanded: PropTypes.arrayOf(PropTypes.string).isRequired,
onExpand: PropTypes.func.isRequired,
onCheck: PropTypes.func.isRequired,
width: PropTypes.string.isRequired,
height: PropTypes.string.isRequired,
className: PropTypes.string.isRequired,
labelClassName: PropTypes.string,
getCheckboxIcon: PropTypes.func,
getCollapseIcon: PropTypes.string,
expandDisabled: PropTypes.bool,
disabled: PropTypes.bool,
noCascade: PropTypes.bool
};
CheckboxTree.defaultProps = {
labelClassName: '',
getCheckboxIcon: undefined,
getCollapseIcon: undefined,
expandDisabled: false,
disabled: false,
noCascade: undefined
};
//# sourceMappingURL=index.js.map