1.1.0 • Published 2 years ago
tree-handler v1.1.0
Tree Handler
tree-handler is a module to easily manipulate tree structures.
API
Parse tree
import treeHandler from 'tree-handler';
const model = {
id: 'root',
children: [
{ id: 'A', children: [] },
{ id: 'B', children: [] },
],
};
const tree = treeHandler.parse(model);
Parse with a custom children property
import treeHandler from 'tree-handler';
const model = {
id: 'root',
subtasks: [
{ id: 'A', subtasks: [] },
{ id: 'B', subtasks: [] },
],
};
const tree = treeHandler.parse(model, { childrenProperty: 'subtasks' });
Find a single node that matches a criteria
tree.findOne((node) => node.model.id === 'A');
Find many nodes that match a criteria
tree.find((node) => node.model.type === 'cake');
Add a new node as an object
tree.addChild({ id: '123', type: 'chocolate', children: [] });
Add a new node as a node
const newNode = treeHandler.parse({
id: '123',
type: 'chocolate',
children: [],
});
tree.addChild(newNode);
Delete a node
const node = tree.findOne((node) => node.model.id === 'A');
node.delete();
Move a node under a new parent
const modelA = {
id: 'A',
children: [
{ id: 'B', children: [{ id: 'B1', children: [] }] },
{
id: 'C',
children: [
{ id: 'C1', children: [] },
{ id: 'C2', children: [] },
],
},
],
};
const tree = treeHandler.parse(modelA);
tree.moveUnderParnet({
node: (node) => node.model.id === 'B1',
toParent: (node) => node.model.id === 'C',
atIndex: 1,
});
Move a node next to a sibling
tree.moveToSibling({
node: (node) => node.model.id === 'B1',
toSibling: (node) => node.model.id === 'C2',
at: 'BEFORE', // options: BEFORE, AFTER
});
Filter Tree Nodes
the filter function will return to us new TreeNode classes based on the filter conditions. There are two modes to filter a tree structure.
Remove Children Mode (Default)
this one is the "expected" way of filtering a tree structure's nodes. If a node should be filtered out, then that node along its children will be removed.
const dataTree = {
id: '1',
tag: 'pending',
subtasks: [
{
id: '2',
tag: 'pending',
subtasks: [
{ id: '4', tag: 'complete', subtasks: [] },
{ id: '46', tag: 'in progress', subtasks: [] },
],
},
{
id: '3',
tag: 'in progress',
subtasks: [
{
id: '4',
tag: 'pending',
subtasks: [
{
id: '6',
tag: 'complete',
subtasks: [
{
id: '10',
tag: 'pending',
subtasks: [{ id: '11', tag: 'complete', subtasks: [] }],
},
],
},
{
id: '7',
tag: 'complete',
subtasks: [{ id: '74', tag: 'in progress', subtasks: [] }],
},
],
},
{ id: '5', tag: 'pending', subtasks: [] },
],
},
{ id: '4', tag: 'complete', subtasks: [] },
],
};
const tree = treeHandler.parse(dataTree, {
childrenProperty: 'subtasks',
});
const newTree = tree.filter((node) => node.tag !== 'in progress');
console.log(newTree);
result:
{
id: '1',
tag: 'pending',
subtasks: [
{
id: '2',
tag: 'pending',
subtasks: [{ id: '4', tag: 'complete', subtasks: [] }],
},
{ id: '4', tag: 'complete', subtasks: [] },
],
};
Merge Children Mode
this filtering method is unique. What it does is that it filtering out each node indiviually. Meaning if a node should be filtered out, and if it has children that should not be filtered out, then those children will be moved to the same depth level and starting index number of their parent.
const dataTree = {
id: '1',
tag: 'pending',
subtasks: [
{ id: '2', tag: 'pending', subtasks: [] },
{
id: '3',
tag: 'in progress',
subtasks: [
{
id: '4',
tag: 'pending',
subtasks: [
{
id: '6',
tag: 'complete',
subtasks: [
{
id: '10',
tag: 'pending',
subtasks: [{ id: '10', tag: 'complete', subtasks: [] }],
},
],
},
{ id: '7', tag: 'complete', subtasks: [] },
],
},
{ id: '5', tag: 'pending', subtasks: [] },
],
},
{ id: '4', tag: 'complete', subtasks: [] },
],
};
const treeResult =
const tree = treeHandler.parse(dataTree, { childrenProperty: 'subtasks' });
const newTrees = tree.filter(
(node) => node.tag !== 'in progress',
'mergeChildren'
);
console.log(newTrees)
result:
[
{
id: '1',
tag: 'pending',
subtasks: [
{ id: '2', tag: 'pending', subtasks: [] },
{
id: '4',
tag: 'pending',
subtasks: [
{
id: '6',
tag: 'complete',
subtasks: [
{
id: '10',
tag: 'pending',
subtasks: [{ id: '10', tag: 'complete', subtasks: [] }],
},
],
},
{ id: '7', tag: 'complete', subtasks: [] },
],
},
{ id: '5', tag: 'pending', subtasks: [] },
{ id: '4', tag: 'complete', subtasks: [] },
],
},
];
Flatten tree to array of nodes
tree.flatten();
Loop across every node in the tree
tree.forEach((node) => {
console.log(node);
});
Credits
Heavily inspired by tree-model