React Checkbox Menu Tree is a versatile and customizable tree menu component for Reactjs applications. It allows users to navigate through hierarchical data and select multiple nodes using checkboxes. This component is suitable for creating complex nested menus, category trees, or any other hierarchical data representation with selectable options, although you can access to each node data without using checkboxes with onClick function that is accessible on each node.
click here to see all the examples.
Help me to stack sats!
0xB4B2008f50E945fA28a99f2A650a9bF97C3d55eC
Flexible Data Structure: The component supports a customizable approach to data, allowing you to define various properties for each node in the tree, allowing you to define custom theme and set custom text for buttons title.
Feature include:
The easiest way to use react-checkbox-menu-tree is to install it from npm and build it into your app with Webpack.
yarn add react-checkbox-menu-tree
or
npm i --save react-checkbox-menu-tree
import React from "react";
import ReactDOM from "react-dom/client";
import MenuTree from "react-checkbox-menu-tree";
import {
TCallbackData,
TCallbackIds,
TLeftSideWidgetData,
} from "./types/common.ts";
const MockData = [
{
id: 1204,
title: "node_1",
description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
ticked: "FULL",
checkedStatus: "FULL",
parentId: null,
tags: ["tag_1", "tag_2", "tag_3"],
repeat: [],
},
{
id: 1205,
title: "node_2",
description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
ticked: "FULL",
checkedStatus: "FULL",
parentId: null,
repeat: [
{
id: 1206,
title: "node_2_1",
description:
"Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
ticked: "FULL",
checkedStatus: "FULL",
parentId: 1205,
repeat: [],
},
{
id: 1207,
title: "node_2_2",
description:
"Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
ticked: "FULL",
checkedStatus: "FULL",
parentId: 1205,
tags: ["tag_1", "tag_2", "tag_3"],
repeat: [],
},
],
},
{
id: 1208,
title: "node_3",
description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
ticked: "FULL",
checkedStatus: "FULL",
parentId: null,
repeat: [],
},
];
const CustomTheme = {
name: "custom-theme",
colors: {
white: "#FFFFFF",
white_200: "#f5f5f5",
white_300: "#e8e8e8",
white_500: "#eae9e9",
black_100: "#C9C9C9",
black_200: "#545454",
black_300: "#575757",
black_400: "#1E1E1E",
primary: "#238103",
secondary_100: "#c0d8df",
tertiary: "#ff4e05",
warning: "#ff0000",
shadow_100: "#f2f3f5",
shadow_200: "#bfbfbf",
},
fontSize: {
h5: "18px",
h6: "14px",
h8: "12px",
},
fontWeight: {
bold: "bold",
normal: 400,
high: 500,
},
};
const PropertiesMapper = {
id: "id",
title: "title",
description: "description",
checked: "ticked",
parentId: "parentId",
tags: "tags",
children: "repeat",
iconName: "iconName",
};
const Translation = {
result: "result",
resultCount: "result count",
close: "close",
search: "search",
closeAll: "close all",
openAll: "open all",
};
const handleClick = (data: TCallbackData, ids: TCallbackIds) => {
console.log("data: ", data);
console.log("ids: ", ids);
};
const handleWidgetClick = (data: TLeftSideWidgetData) => {
return (
<button onClick={() => console.log("current node data:", data)}>
click me
</button>
);
};
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<MenuTree
data={MockData}
title="Menu Tree"
leftSideWidget={handleWidgetClick}
onClick={handleClick}
hasCheckBox
loading={false}
headerLess={false}
disabled={false}
theme={CustomTheme}
propertiesMapper={PropertiesMapper}
translation={Translation}
/>
);
title: string | number (required) |
checked: NOT | FULL | HAF (required if hasCheckBox will true) |
checked: NOT | FULL | HAF (required if hasCheckBox will true) |
propertiesMapper: This built-in variable is used to specify the variables of each node that may exist in the data array with a different name. You can use this option to introduce the necessary variables required by react-checkbox-menu-tree component to it.
import React from "react";
import ReactDOM from "react-dom/client";
import MenuTree from "react-checkbox-menu-tree";
const MockData = [
{
id: 1204,
title: "node_1",
},
{
id: 1205,
title: "node_2",
children: [
{
id: 1206,
title: "node_2_1",
},
{
id: 1207,
title: "node_2_2",
},
],
},
];
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<MenuTree data={MockData} title="Menu Tree" />);
import React from "react";
import ReactDOM from "react-dom/client";
import MenuTree from "react-checkbox-menu-tree";
const MockData = [
{
id: 1204,
title: "node_1",
checked: "FULL",
parentId: null,
},
{
id: 1205,
title: "node_2",
checked: "HALF",
parentId: null,
children: [
{
id: 1206,
title: "node_2_1",
checked: "NOT",
parentId: 1205,
},
{
id: 1207,
title: "node_2_2",
checked: "FULL",
parentId: 1205,
},
],
},
{
id: 1208,
title: "node_3",
checked: "FULL",
parentId: null,
},
];
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<MenuTree data={MockData} title="Menu Tree" hasCheckBox />);
import React from "react";
import ReactDOM from "react-dom/client";
import MenuTree from "react-checkbox-menu-tree";
const MockData = [
{
id: 1204,
title: "node_1",
},
{
id: 1205,
title: "node_2",
children: [
{
id: 1206,
title: "node_2_1",
},
{
id: 1207,
title: "node_2_2",
},
],
},
];
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<MenuTree
data={MockData}
title="Menu Tree"
leftSideWidget={(data) => {
return (
<button onClick={() => console.log("current node data:", data)}>
click me
</button>
);
}}
/>
);
import React from "react";
import ReactDOM from "react-dom/client";
import MenuTree from "react-checkbox-menu-tree";
const MockData = [
{
id: 1204,
title: "node_1",
},
{
id: 1205,
title: "node_2",
children: [
{
id: 1206,
title: "node_2_1",
},
{
id: 1207,
title: "node_2_2",
},
],
},
];
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<MenuTree
data={MockData}
title="Menu Tree"
onClick={(data, ids) => {
console.log("data: ", data);
console.log("ids: ", ids);
}}
/>
);
Notice: The onClick functionality toggles the selected node. When a node is selected, the callback method returns the current node data; otherwise, it returns null.
import React from "react";
import ReactDOM from "react-dom/client";
import MenuTree from "react-checkbox-menu-tree";
const MockData = [
{
id: 1204,
title: "node_1",
description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
checked: "FULL",
parentId: null,
tags: ["tag_1", "tag_2"],
},
{
id: 1205,
title: "node_2",
description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
checked: "FULL",
tags: ["tag_1", "tag_2", "tag_3"],
parentId: null,
children: [
{
id: 1206,
title: "node_2_1",
description:
"Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
checked: "FULL",
parentId: 1205,
},
{
id: 1207,
title: "node_2_2",
description:
"Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
checked: "FULL",
parentId: 1205,
},
],
},
{
id: 1208,
title: "node_3",
description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
checked: "FULL",
parentId: null,
},
];
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<MenuTree data={MockData} headerLess title="Menu Tree" hasCheckBox />
);
import React from "react";
import ReactDOM from "react-dom/client";
import MenuTree from "react-checkbox-menu-tree";
const MockData = [
{
id: 1204,
title: "node_1",
checked: "FULL",
parentId: null,
},
{
id: 1205,
title: "node_2",
checked: "FULL",
parentId: null,
repeat: [
{
id: 1206,
title: "node_2_1",
checked: "FULL",
parentId: 1205,
},
{
id: 1207,
title: "node_2_2",
checked: "FULL",
parentId: 1205,
},
],
},
{
id: 1208,
title: "node_3",
checked: "FULL",
},
];
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<MenuTree
data={MockData}
title="Menu Tree"
propertiesMapper=
hasCheckBox
/>
);
Notice: Sometimes, your data may have different property names, but the structure remains the same as recursive data. You might use different keys in your array of objects, which you can map using a propertyMapper. For example, instead of ‘children’, you might have ‘repeat’ in your object. By mapping it, everything works perfectly.
import React from "react";
import ReactDOM from "react-dom/client";
import MenuTree from "react-checkbox-menu-tree";
import {
TCallbackData,
TCallbackIds,
TLeftSideWidgetData,
} from "./types/common.ts";
const MockData = [
{
id: 1204,
title: "node_1",
description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
ticked: "FULL",
checkedStatus: "FULL",
parentId: null,
tags: ["tag_1", "tag_2", "tag_3"],
repeat: [],
},
{
id: 1205,
title: "node_2",
description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
ticked: "FULL",
checkedStatus: "FULL",
parentId: null,
repeat: [
{
id: 1206,
title: "node_2_1",
description:
"Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
ticked: "FULL",
checkedStatus: "FULL",
parentId: 1205,
repeat: [],
},
{
id: 1207,
title: "node_2_2",
description:
"Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
ticked: "FULL",
checkedStatus: "FULL",
parentId: 1205,
tags: ["tag_1", "tag_2", "tag_3"],
repeat: [],
},
],
},
{
id: 1208,
title: "node_3",
description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
ticked: "FULL",
checkedStatus: "FULL",
parentId: null,
repeat: [],
},
];
const CustomTheme = {
name: "custom-theme",
colors: {
white: "#FFFFFF",
white_200: "#f5f5f5",
white_300: "#e8e8e8",
white_500: "#eae9e9",
black_100: "#C9C9C9",
black_200: "#545454",
black_300: "#575757",
black_400: "#1E1E1E",
primary: "#238103",
secondary_100: "#c0d8df",
tertiary: "#ff4e05",
warning: "#ff0000",
shadow_100: "#f2f3f5",
shadow_200: "#bfbfbf",
},
fontSize: {
h5: "18px",
h6: "14px",
h8: "12px",
},
fontWeight: {
bold: "bold",
normal: 400,
high: 500,
},
};
const PropertiesMapper = {
id: "id",
title: "title",
description: "description",
checked: "ticked",
parentId: "parentId",
tags: "tags",
children: "repeat",
iconName: "iconName",
};
const Translation = {
result: "result",
resultCount: "result count",
close: "close",
search: "search",
closeAll: "close all",
openAll: "open all",
};
const handleClick = (data: TCallbackData, ids: TCallbackIds) => {
console.log("data: ", data);
console.log("ids: ", ids);
};
const handleWidgetClick = (data: TLeftSideWidgetData) => {
return (
<button onClick={() => console.log("current node data:", data)}>
click me
</button>
);
};
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<MenuTree
data={MockData}
title="Menu Tree"
leftSideWidget={handleWidgetClick}
onClick={handleClick}
hasCheckBox
loading={false}
headerLess={false}
disabled={false}
theme={CustomTheme}
propertiesMapper={PropertiesMapper}
translation={Translation}
/>
);
Pull requests are welcome. For major changes, please open an issue first
to discuss what you would like to change.
Join me in making React-Checkbox-Menu-Tree even better.
If you have any questions or suggestions, please let me know
hosein.mohajer@gmail.com