Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

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.6.3 to 0.6.4

yarn.lock

6

CHANGELOG.md
# CHANGELOG
## [v0.6.4](https://github.com/jakezatecky/react-checkbox-tree/compare/v0.6.3...v0.6.4) (2017-07-22)
### Bug Fix
* [#42]: Fix npm package not aligning with Git version
## [v0.6.3](https://github.com/jakezatecky/react-checkbox-tree/compare/v0.6.2...v0.6.3) (2017-05-30)

@@ -4,0 +10,0 @@

10

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

@@ -37,10 +37,10 @@ "author": "Jake Zatecky",

"browser-sync": "^2.18.6",
"chai": "^3.5.0",
"chai": "^4.0.0",
"enzyme": "^2.7.1",
"eslint": "^3.15.0",
"eslint-config-airbnb": "^15.0.0",
"eslint-config-takiyon-react": "^0.0.0",
"eslint-import-resolver-webpack": "^0.8.1",
"eslint-plugin-import": "^2.2.0",
"eslint-plugin-jsx-a11y": "^5.0.1",
"eslint-plugin-react": "^7.0.1",
"eslint-plugin-react": "^7.1.0",
"gulp": "^3.9.1",

@@ -59,3 +59,3 @@ "gulp-autoprefixer": "^4.0.0",

"react-test-renderer": "^15.5.4",
"webpack": "^2.2.1",
"webpack": "^3.0.0",
"webpack-stream": "^3.2.0"

@@ -62,0 +62,0 @@ },

@@ -6,3 +6,3 @@ # react-checkbox-tree

[![Dependency Status](https://img.shields.io/david/jakezatecky/react-checkbox-tree.svg?style=flat-square)](https://david-dm.org/jakezatecky/react-checkbox-tree)
[![devDependency Status](https://david-dm.org/jakezatecky/react-checkbox-tree/dev-status.svg?style=flat-square)](https://david-dm.org/jakezatecky/react-checkbox-tree#info=devDependencies)
[![devDependency Status](https://david-dm.org/jakezatecky/react-checkbox-tree/dev-status.svg?style=flat-square)](https://david-dm.org/jakezatecky/react-checkbox-tree?type=dev)
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://raw.githubusercontent.com/jakezatecky/react-checkbox-tree/master/LICENSE.txt)

@@ -9,0 +9,0 @@

@@ -11,266 +11,266 @@ import classNames from 'classnames';

class CheckboxTree extends React.Component {
static propTypes = {
nodes: PropTypes.arrayOf(nodeShape).isRequired,
static propTypes = {
nodes: PropTypes.arrayOf(nodeShape).isRequired,
checked: PropTypes.arrayOf(PropTypes.string),
disabled: PropTypes.bool,
expandDisabled: PropTypes.bool,
expanded: PropTypes.arrayOf(PropTypes.string),
name: PropTypes.string,
nameAsArray: PropTypes.bool,
noCascade: PropTypes.bool,
optimisticToggle: PropTypes.bool,
showNodeIcon: PropTypes.bool,
onCheck: PropTypes.func,
onExpand: PropTypes.func,
};
checked: PropTypes.arrayOf(PropTypes.string),
disabled: PropTypes.bool,
expandDisabled: PropTypes.bool,
expanded: PropTypes.arrayOf(PropTypes.string),
name: PropTypes.string,
nameAsArray: PropTypes.bool,
noCascade: PropTypes.bool,
optimisticToggle: PropTypes.bool,
showNodeIcon: PropTypes.bool,
onCheck: PropTypes.func,
onExpand: PropTypes.func,
};
static defaultProps = {
checked: [],
disabled: false,
expandDisabled: false,
expanded: [],
name: undefined,
nameAsArray: false,
noCascade: false,
optimisticToggle: true,
showNodeIcon: true,
onCheck: () => {},
onExpand: () => {},
};
static defaultProps = {
checked: [],
disabled: false,
expandDisabled: false,
expanded: [],
name: undefined,
nameAsArray: false,
noCascade: false,
optimisticToggle: true,
showNodeIcon: true,
onCheck: () => {},
onExpand: () => {},
};
constructor(props) {
super(props);
constructor(props) {
super(props);
this.id = `rct-${shortid.generate()}`;
this.nodes = {};
this.id = `rct-${shortid.generate()}`;
this.nodes = {};
this.flattenNodes(props.nodes);
this.unserializeLists({
checked: props.checked,
expanded: props.expanded,
});
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.onCheck = this.onCheck.bind(this);
this.onExpand = this.onExpand.bind(this);
}
componentWillReceiveProps({ nodes, checked, expanded }) {
if (!isEqual(this.props.nodes, nodes)) {
this.flattenNodes(nodes);
}
componentWillReceiveProps({ nodes, checked, expanded }) {
if (!isEqual(this.props.nodes, nodes)) {
this.flattenNodes(nodes);
}
this.unserializeLists({ checked, expanded });
}
this.unserializeLists({ checked, expanded });
}
onCheck(node) {
const { noCascade, onCheck } = this.props;
onCheck(node) {
const { noCascade, onCheck } = this.props;
this.toggleChecked(node, node.checked, noCascade);
onCheck(this.serializeList('checked'));
}
this.toggleChecked(node, node.checked, noCascade);
onCheck(this.serializeList('checked'));
}
onExpand(node) {
const { onExpand } = this.props;
onExpand(node) {
const { onExpand } = this.props;
this.toggleNode('expanded', node, node.expanded);
onExpand(this.serializeList('expanded'));
}
this.toggleNode('expanded', node, node.expanded);
onExpand(this.serializeList('expanded'));
}
getFormattedNodes(nodes) {
return nodes.map((node) => {
const formatted = { ...node };
getFormattedNodes(nodes) {
return nodes.map((node) => {
const formatted = { ...node };
formatted.checked = this.nodes[node.value].checked;
formatted.expanded = this.nodes[node.value].expanded;
formatted.checked = this.nodes[node.value].checked;
formatted.expanded = this.nodes[node.value].expanded;
if (Array.isArray(node.children) && node.children.length > 0) {
formatted.children = this.getFormattedNodes(formatted.children);
} else {
formatted.children = null;
}
if (Array.isArray(node.children) && node.children.length > 0) {
formatted.children = this.getFormattedNodes(formatted.children);
} else {
formatted.children = null;
}
return formatted;
});
}
return formatted;
});
}
getCheckState(node, noCascade) {
if (node.children === null || noCascade) {
return node.checked ? 1 : 0;
}
getCheckState(node, noCascade) {
if (node.children === null || noCascade) {
return node.checked ? 1 : 0;
}
if (this.isEveryChildChecked(node)) {
return 1;
}
if (this.isEveryChildChecked(node)) {
return 1;
}
if (this.isSomeChildChecked(node)) {
return 2;
}
if (this.isSomeChildChecked(node)) {
return 2;
}
return 0;
}
return 0;
}
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);
});
}
}
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);
});
}
}
toggleNode(key, node, toggleValue) {
this.nodes[node.value][key] = toggleValue;
}
toggleNode(key, node, toggleValue) {
this.nodes[node.value][key] = toggleValue;
}
flattenNodes(nodes) {
if (!Array.isArray(nodes) || nodes.length === 0) {
return;
}
flattenNodes(nodes) {
if (!Array.isArray(nodes) || nodes.length === 0) {
return;
}
nodes.forEach((node) => {
this.nodes[node.value] = {};
this.flattenNodes(node.children);
});
}
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;
});
});
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;
});
});
}
// 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 = [];
serializeList(key) {
const list = [];
Object.keys(this.nodes).forEach((value) => {
if (this.nodes[value][key]) {
list.push(value);
}
});
Object.keys(this.nodes).forEach((value) => {
if (this.nodes[value][key]) {
list.push(value);
}
});
return list;
}
return list;
}
isEveryChildChecked(node) {
return node.children.every((child) => {
if (child.children !== null) {
return this.isEveryChildChecked(child);
}
isEveryChildChecked(node) {
return node.children.every((child) => {
if (child.children !== null) {
return this.isEveryChildChecked(child);
}
return child.checked;
});
}
return child.checked;
});
}
isSomeChildChecked(node) {
return node.children.some((child) => {
if (child.children !== null) {
return this.isSomeChildChecked(child);
}
isSomeChildChecked(node) {
return node.children.some((child) => {
if (child.children !== null) {
return this.isSomeChildChecked(child);
}
return child.checked;
});
}
return child.checked;
});
}
renderTreeNodes(nodes) {
const { disabled, expandDisabled, noCascade, optimisticToggle, showNodeIcon } = this.props;
const treeNodes = nodes.map((node) => {
const key = `${node.value}`;
const checked = this.getCheckState(node, noCascade);
const children = this.renderChildNodes(node);
renderTreeNodes(nodes) {
const { disabled, expandDisabled, noCascade, optimisticToggle, showNodeIcon } = this.props;
const treeNodes = nodes.map((node) => {
const key = `${node.value}`;
const checked = this.getCheckState(node, noCascade);
const children = this.renderChildNodes(node);
return (
<TreeNode
key={key}
checked={checked}
className={node.className}
disabled={disabled}
expandDisabled={expandDisabled}
expanded={node.expanded}
icon={node.icon}
label={node.label}
optimisticToggle={optimisticToggle}
rawChildren={node.children}
showNodeIcon={showNodeIcon}
treeId={this.id}
value={node.value}
onCheck={this.onCheck}
onExpand={this.onExpand}
>
{children}
</TreeNode>
);
});
return (
<TreeNode
key={key}
checked={checked}
className={node.className}
disabled={disabled}
expandDisabled={expandDisabled}
expanded={node.expanded}
icon={node.icon}
label={node.label}
optimisticToggle={optimisticToggle}
rawChildren={node.children}
showNodeIcon={showNodeIcon}
treeId={this.id}
value={node.value}
onCheck={this.onCheck}
onExpand={this.onExpand}
>
{children}
</TreeNode>
);
});
return (
<ol>
{treeNodes}
</ol>
);
}
return (
<ol>
{treeNodes}
</ol>
);
}
renderChildNodes(node) {
if (node.children !== null && node.expanded) {
return this.renderTreeNodes(node.children);
}
renderChildNodes(node) {
if (node.children !== null && node.expanded) {
return this.renderTreeNodes(node.children);
}
return null;
}
return null;
}
renderHiddenInput() {
if (this.props.name === undefined) {
return null;
}
renderHiddenInput() {
if (this.props.name === undefined) {
return null;
}
if (this.props.nameAsArray) {
return this.renderArrayHiddenInput();
}
if (this.props.nameAsArray) {
return this.renderArrayHiddenInput();
}
return this.renderJoinedHiddenInput();
}
return this.renderJoinedHiddenInput();
}
renderArrayHiddenInput() {
return this.props.checked.map((value) => {
const name = `${this.props.name}[]`;
renderArrayHiddenInput() {
return this.props.checked.map((value) => {
const name = `${this.props.name}[]`;
return <input key={value} name={name} type="hidden" value={value} />;
});
}
return <input key={value} name={name} type="hidden" value={value} />;
});
}
renderJoinedHiddenInput() {
const checked = this.props.checked.join(',');
renderJoinedHiddenInput() {
const checked = this.props.checked.join(',');
return <input name={this.props.name} type="hidden" value={checked} />;
}
return <input name={this.props.name} type="hidden" value={checked} />;
}
render() {
const nodes = this.getFormattedNodes(this.props.nodes);
const treeNodes = this.renderTreeNodes(nodes);
const className = classNames({
'react-checkbox-tree': true,
'rct-disabled': this.props.disabled,
});
render() {
const nodes = this.getFormattedNodes(this.props.nodes);
const treeNodes = this.renderTreeNodes(nodes);
const className = classNames({
'react-checkbox-tree': true,
'rct-disabled': this.props.disabled,
});
return (
<div className={className}>
{this.renderHiddenInput()}
{treeNodes}
</div>
);
}
return (
<div className={className}>
{this.renderHiddenInput()}
{treeNodes}
</div>
);
}
}
export default CheckboxTree;
import PropTypes from 'prop-types';
const nodeShape = {
label: PropTypes.string.isRequired,
value: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
]).isRequired,
label: PropTypes.string.isRequired,
value: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
]).isRequired,
icon: PropTypes.node,
icon: PropTypes.node,
};
const nodeShapeWithChildren = PropTypes.oneOfType([
PropTypes.shape(nodeShape),
PropTypes.shape({
...nodeShape,
children: PropTypes.arrayOf(nodeShape).isRequired,
}),
PropTypes.shape(nodeShape),
PropTypes.shape({
...nodeShape,
children: PropTypes.arrayOf(nodeShape).isRequired,
}),
]);
export default nodeShapeWithChildren;

@@ -8,175 +8,175 @@ import classNames from 'classnames';

class TreeNode extends React.Component {
static propTypes = {
checked: PropTypes.number.isRequired,
disabled: PropTypes.bool.isRequired,
expandDisabled: PropTypes.bool.isRequired,
expanded: PropTypes.bool.isRequired,
label: PropTypes.string.isRequired,
optimisticToggle: PropTypes.bool.isRequired,
showNodeIcon: PropTypes.bool.isRequired,
treeId: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
onCheck: PropTypes.func.isRequired,
onExpand: PropTypes.func.isRequired,
static propTypes = {
checked: PropTypes.number.isRequired,
disabled: PropTypes.bool.isRequired,
expandDisabled: PropTypes.bool.isRequired,
expanded: PropTypes.bool.isRequired,
label: PropTypes.string.isRequired,
optimisticToggle: PropTypes.bool.isRequired,
showNodeIcon: PropTypes.bool.isRequired,
treeId: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
onCheck: PropTypes.func.isRequired,
onExpand: PropTypes.func.isRequired,
children: PropTypes.node,
className: PropTypes.string,
icon: PropTypes.node,
rawChildren: PropTypes.arrayOf(nodeShape),
};
children: PropTypes.node,
className: PropTypes.string,
icon: PropTypes.node,
rawChildren: PropTypes.arrayOf(nodeShape),
};
static defaultProps = {
children: null,
className: null,
icon: null,
rawChildren: null,
};
static defaultProps = {
children: null,
className: null,
icon: null,
rawChildren: null,
};
constructor(props) {
super(props);
constructor(props) {
super(props);
this.onCheck = this.onCheck.bind(this);
this.onExpand = this.onExpand.bind(this);
}
this.onCheck = this.onCheck.bind(this);
this.onExpand = this.onExpand.bind(this);
}
onCheck() {
let isChecked = false;
onCheck() {
let isChecked = false;
// Toggle off state to checked
if (this.props.checked === 0) {
isChecked = true;
}
// Toggle off state to checked
if (this.props.checked === 0) {
isChecked = true;
}
// Toggle partial state based on cascade model
if (this.props.checked === 2) {
isChecked = this.props.optimisticToggle;
}
// Toggle partial state based on cascade model
if (this.props.checked === 2) {
isChecked = this.props.optimisticToggle;
}
this.props.onCheck({
value: this.props.value,
checked: isChecked,
children: this.props.rawChildren,
});
}
this.props.onCheck({
value: this.props.value,
checked: isChecked,
children: this.props.rawChildren,
});
}
onExpand() {
this.props.onExpand({
value: this.props.value,
expanded: !this.props.expanded,
});
}
onExpand() {
this.props.onExpand({
value: this.props.value,
expanded: !this.props.expanded,
});
}
hasChildren() {
return this.props.rawChildren !== null;
}
hasChildren() {
return this.props.rawChildren !== null;
}
renderCollapseButton() {
const { expandDisabled } = this.props;
renderCollapseButton() {
const { expandDisabled } = this.props;
if (!this.hasChildren()) {
return (
<span className="rct-collapse">
<span className="rct-icon" />
</span>
);
}
if (!this.hasChildren()) {
return (
<span className="rct-collapse">
<span className="rct-icon" />
</span>
);
}
return (
<button
aria-label="Toggle"
className="rct-collapse rct-collapse-btn"
disabled={expandDisabled}
title="Toggle"
type="button"
onClick={this.onExpand}
>
{this.renderCollapseIcon()}
</button>
);
}
return (
<button
aria-label="Toggle"
className="rct-collapse rct-collapse-btn"
disabled={expandDisabled}
title="Toggle"
type="button"
onClick={this.onExpand}
>
{this.renderCollapseIcon()}
</button>
);
}
renderCollapseIcon() {
if (!this.props.expanded) {
return <span className="rct-icon rct-icon-expand-close" />;
}
renderCollapseIcon() {
if (!this.props.expanded) {
return <span className="rct-icon rct-icon-expand-close" />;
}
return <span className="rct-icon rct-icon-expand-open" />;
}
return <span className="rct-icon rct-icon-expand-open" />;
}
renderCheckboxIcon() {
if (this.props.checked === 0) {
return <span className="rct-icon rct-icon-uncheck" />;
}
renderCheckboxIcon() {
if (this.props.checked === 0) {
return <span className="rct-icon rct-icon-uncheck" />;
}
if (this.props.checked === 1) {
return <span className="rct-icon rct-icon-check" />;
}
if (this.props.checked === 1) {
return <span className="rct-icon rct-icon-check" />;
}
return <span className="rct-icon rct-icon-half-check" />;
}
return <span className="rct-icon rct-icon-half-check" />;
}
renderNodeIcon() {
if (this.props.icon !== null) {
return this.props.icon;
}
renderNodeIcon() {
if (this.props.icon !== null) {
return this.props.icon;
}
if (!this.hasChildren()) {
return <span className="rct-icon rct-icon-leaf" />;
}
if (!this.hasChildren()) {
return <span className="rct-icon rct-icon-leaf" />;
}
if (!this.props.expanded) {
return <span className="rct-icon rct-icon-parent-close" />;
}
if (!this.props.expanded) {
return <span className="rct-icon rct-icon-parent-close" />;
}
return <span className="rct-icon rct-icon-parent-open" />;
}
return <span className="rct-icon rct-icon-parent-open" />;
}
renderChildren() {
if (!this.props.expanded) {
return null;
}
renderChildren() {
if (!this.props.expanded) {
return null;
}
return this.props.children;
}
return this.props.children;
}
render() {
const { checked, className, disabled, treeId, label, showNodeIcon, value } = this.props;
const inputId = `${treeId}-${value}`;
const nodeClass = classNames({
'rct-node': true,
'rct-node-parent': this.hasChildren(),
'rct-node-leaf': !this.hasChildren(),
}, className);
render() {
const { checked, className, disabled, treeId, label, showNodeIcon, value } = this.props;
const inputId = `${treeId}-${value}`;
const nodeClass = classNames({
'rct-node': true,
'rct-node-parent': this.hasChildren(),
'rct-node-leaf': !this.hasChildren(),
}, className);
return (
<li className={nodeClass}>
<span className="rct-text">
{this.renderCollapseButton()}
<label htmlFor={inputId}>
<input
checked={checked === 1}
disabled={disabled}
id={inputId}
type="checkbox"
onChange={this.onCheck}
/>
<span className="rct-checkbox">
{this.renderCheckboxIcon()}
</span>
{showNodeIcon ? (
<span className="rct-node-icon">
{this.renderNodeIcon()}
</span>
) : null}
<span className="rct-title">
{label}
</span>
</label>
</span>
{this.renderChildren()}
</li>
);
}
return (
<li className={nodeClass}>
<span className="rct-text">
{this.renderCollapseButton()}
<label htmlFor={inputId}>
<input
checked={checked === 1}
disabled={disabled}
id={inputId}
type="checkbox"
onChange={this.onCheck}
/>
<span className="rct-checkbox">
{this.renderCheckboxIcon()}
</span>
{showNodeIcon ? (
<span className="rct-node-icon">
{this.renderNodeIcon()}
</span>
) : null}
<span className="rct-title">
{label}
</span>
</label>
</span>
{this.renderChildren()}
</li>
);
}
}
export default TreeNode;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

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