Socket
Socket
Sign inDemoInstall

react-checkbox-tree

Package Overview
Dependencies
Maintainers
1
Versions
49
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-checkbox-tree - npm Package Compare versions

Comparing version 0.5.2 to 0.6.0

11

CHANGELOG.md
# CHANGELOG
## [v0.6.0](https://github.com/jakezatecky/react-checkbox-tree/compare/v0.5.2...v0.6.0) (2017-05-06)
### New Features
* [#32]: Allow customization of `className` at the node level
* [#30]: Add `showNodeIcon` property to optionally remove node icons
### Other
* [#14]: Component performance when rendering and updating a large number of nodes has been significantly increased
## [v0.5.2](https://github.com/jakezatecky/react-checkbox-tree/compare/v0.5.1...v0.5.2) (2017-05-03)

@@ -4,0 +15,0 @@

3

package.json
{
"name": "react-checkbox-tree",
"version": "0.5.2",
"version": "0.6.0",
"description": "A simple and elegant checkbox tree for React.",

@@ -62,2 +62,3 @@ "author": "Jake Zatecky",

"classnames": "^2.2.5",
"lodash": "^4.17.4",
"prop-types": "^15.5.8",

@@ -64,0 +65,0 @@ "shortid": "^2.2.6"

@@ -88,2 +88,4 @@ # react-checkbox-tree

All node objects **must** have a unique `value`. This value is serialized into the `checked` and `expanded` arrays and is also used for performance optimizations.
### Properties

@@ -96,7 +98,8 @@

| `expanded` | array | An array of expanded node values. | `[]` |
| `onCheck` | function | onCheck handler: `function(checked) {}` | `() => {}` |
| `onExpand` | function | onExpand handler: `function(expanded) {}` | `() => {}` |
| `name` | string | Optional name for the hidden `<input>` element. | `undefined` |
| `nameAsArray` | bool | If true, the hidden `<input>` will encode its values as an array rather than a joined string. | `false` |
| `optimisticToggle` | bool | If true, toggling a partially-checked node will select all children. If false, it will deselect. | `true` |
| `showNodeIcon` | bool | If true, each node will show a parent or leaf icon. | `true` |
| `onCheck` | function | onCheck handler: `function(checked) {}` | `() => {}` |
| `onExpand` | function | onExpand handler: `function(expanded) {}` | `() => {}` |

@@ -107,7 +110,8 @@ #### Node Properties

| Property | Type | Description |
| ---------- | ------ | ------------------------------- |
| `label` | string | **Required**. The node's label. |
| `value` | mixed | **Required**. The node's value. |
| `children` | array | An array of child nodes. |
| `icon` | mixed | A custom icon for the node. |
| Property | Type | Description |
| ----------- | ------ | ------------------------------- |
| `label` | string | **Required**. The node's label. |
| `value` | mixed | **Required**. The node's value. |
| `children` | array | An array of child nodes. |
| `className` | string | A className to add to the node. |
| `icon` | mixed | A custom icon for the node. |

@@ -0,1 +1,2 @@

import { isEqual } from 'lodash';
import PropTypes from 'prop-types';

@@ -12,7 +13,8 @@ import React from 'react';

checked: PropTypes.arrayOf(React.PropTypes.string),
expanded: PropTypes.arrayOf(React.PropTypes.string),
checked: PropTypes.arrayOf(PropTypes.string),
expanded: PropTypes.arrayOf(PropTypes.string),
name: PropTypes.string,
nameAsArray: PropTypes.bool,
optimisticToggle: PropTypes.bool,
showNodeIcon: PropTypes.bool,
onCheck: PropTypes.func,

@@ -29,2 +31,3 @@ onExpand: PropTypes.func,

optimisticToggle: true,
showNodeIcon: true,
onCheck: () => {},

@@ -37,28 +40,43 @@ onExpand: () => {},

this.id = `rct-${shortid.generate()}`;
this.nodes = {};
this.flattenNodes(props.nodes);
this.unserializeLists({
checked: props.checked,
expanded: props.expanded,
});
this.onCheck = this.onCheck.bind(this);
this.onExpand = this.onExpand.bind(this);
}
this.id = `rct-${shortid.generate()}`;
componentWillReceiveProps({ nodes, checked, expanded }) {
if (!isEqual(this.props.nodes, nodes)) {
this.flattenNodes(nodes);
}
this.unserializeLists({ checked, expanded });
}
onCheck(node) {
const { checked, onCheck } = this.props;
const { onCheck } = this.props;
onCheck(this.toggleChecked([...checked], node, node.checked));
this.toggleChecked(node, node.checked);
onCheck(this.serializeList('checked'));
}
onExpand(node) {
const { expanded, onExpand } = this.props;
const { onExpand } = this.props;
onExpand(this.toggleNode([...expanded], node, node.expanded));
this.toggleNode('expanded', node, node.expanded);
onExpand(this.serializeList('expanded'));
}
getFormattedNodes(nodes) {
const { checked, expanded } = this.props;
return nodes.map((node) => {
const formatted = { ...node };
formatted.checked = checked.indexOf(node.value) > -1;
formatted.expanded = expanded.indexOf(node.value) > -1;
formatted.checked = this.nodes[node.value].checked;
formatted.expanded = this.nodes[node.value].expanded;

@@ -91,25 +109,54 @@ if (Array.isArray(node.children) && node.children.length > 0) {

toggleChecked(checked, node, isChecked) {
toggleChecked(node, isChecked) {
if (node.children !== null) {
// Percolate check status down to all children
node.children.forEach((child) => {
this.toggleChecked(checked, child, isChecked);
this.toggleChecked(child, isChecked);
});
} else {
// Set leaf to check/unchecked state
this.toggleNode(checked, node, isChecked);
this.toggleNode('checked', node, isChecked);
}
}
return checked;
toggleNode(key, node, toggleValue) {
this.nodes[node.value][key] = toggleValue;
}
toggleNode(list, node, toggleValue) {
const index = list.indexOf(node.value);
if (index > -1 && !toggleValue) {
list.splice(index, 1);
} else if (index === -1 && toggleValue) {
list.push(node.value);
flattenNodes(nodes) {
if (!Array.isArray(nodes) || nodes.length === 0) {
return;
}
nodes.forEach((node) => {
this.nodes[node.value] = {};
this.flattenNodes(node.children);
});
}
unserializeLists(lists) {
// Reset values to false
Object.keys(this.nodes).forEach((value) => {
Object.keys(lists).forEach((listKey) => {
this.nodes[value][listKey] = false;
});
});
// Unserialize values and set their nodes to true
Object.keys(lists).forEach((listKey) => {
lists[listKey].forEach((value) => {
this.nodes[value][listKey] = true;
});
});
}
serializeList(key) {
const list = [];
Object.keys(this.nodes).forEach((value) => {
if (this.nodes[value][key]) {
list.push(value);
}
});
return list;

@@ -139,4 +186,4 @@ }

renderTreeNodes(nodes) {
const treeNodes = nodes.map((node, index) => {
const key = `${index}-${node.value}`;
const treeNodes = nodes.map((node) => {
const key = `${node.value}`;
const checked = this.getCheckState(node);

@@ -149,2 +196,3 @@ const children = this.renderChildNodes(node);

checked={checked}
className={node.className}
expanded={node.expanded}

@@ -155,2 +203,3 @@ icon={node.icon}

rawChildren={node.children}
showNodeIcon={this.props.showNodeIcon}
treeId={this.id}

@@ -157,0 +206,0 @@ value={node.value}

@@ -13,2 +13,3 @@ import classNames from 'classnames';

optimisticToggle: PropTypes.bool.isRequired,
showNodeIcon: PropTypes.bool.isRequired,
treeId: PropTypes.string.isRequired,

@@ -20,2 +21,3 @@ value: PropTypes.string.isRequired,

children: PropTypes.node,
className: PropTypes.string,
icon: PropTypes.node,

@@ -27,2 +29,3 @@ rawChildren: PropTypes.arrayOf(nodeShape),

children: null,
className: null,
icon: null,

@@ -70,10 +73,2 @@ rawChildren: null,

renderCollapseIcon() {
if (!this.props.expanded) {
return <span className="rct-icon rct-icon-expand-close" />;
}
return <span className="rct-icon rct-icon-expand-open" />;
}
renderCollapseButton() {

@@ -101,2 +96,10 @@ if (!this.hasChildren()) {

renderCollapseIcon() {
if (!this.props.expanded) {
return <span className="rct-icon rct-icon-expand-close" />;
}
return <span className="rct-icon rct-icon-expand-open" />;
}
renderCheckboxIcon() {

@@ -139,3 +142,3 @@ if (this.props.checked === 0) {

render() {
const { checked, treeId, label, value } = this.props;
const { checked, className, treeId, label, showNodeIcon, value } = this.props;
const inputId = `${treeId}-${value}`;

@@ -146,3 +149,3 @@ const nodeClass = classNames({

'rct-node-leaf': !this.hasChildren(),
});
}, className);

@@ -158,5 +161,7 @@ return (

</span>
<span className="rct-node-icon">
{this.renderNodeIcon()}
</span>
{showNodeIcon ? (
<span className="rct-node-icon">
{this.renderNodeIcon()}
</span>
) : null}
<span className="rct-title">

@@ -163,0 +168,0 @@ {label}

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc