@mantine/core 9.0.1 → 9.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/components/Blockquote/Blockquote.cjs +5 -6
- package/cjs/components/Blockquote/Blockquote.cjs.map +1 -1
- package/cjs/components/Flex/Flex.cjs +7 -2
- package/cjs/components/Flex/Flex.cjs.map +1 -1
- package/cjs/components/FloatingIndicator/FloatingIndicator.cjs +1 -2
- package/cjs/components/FloatingIndicator/FloatingIndicator.cjs.map +1 -1
- package/cjs/components/MaskInput/MaskInput.cjs +24 -0
- package/cjs/components/MaskInput/MaskInput.cjs.map +1 -0
- package/cjs/components/MaskInput/use-mask-input-props.cjs +29 -0
- package/cjs/components/MaskInput/use-mask-input-props.cjs.map +1 -0
- package/cjs/components/Rating/Rating.cjs +1 -2
- package/cjs/components/Rating/Rating.cjs.map +1 -1
- package/cjs/components/SemiCircleProgress/SemiCircleProgress.cjs +2 -0
- package/cjs/components/SemiCircleProgress/SemiCircleProgress.cjs.map +1 -1
- package/cjs/components/Slider/Marks/Marks.cjs +3 -2
- package/cjs/components/Slider/Marks/Marks.cjs.map +1 -1
- package/cjs/components/Slider/Marks/is-mark-filled.cjs +2 -1
- package/cjs/components/Slider/Marks/is-mark-filled.cjs.map +1 -1
- package/cjs/components/Slider/Slider/Slider.cjs +12 -3
- package/cjs/components/Slider/Slider/Slider.cjs.map +1 -1
- package/cjs/components/Slider/Track/Track.cjs +3 -2
- package/cjs/components/Slider/Track/Track.cjs.map +1 -1
- package/cjs/components/Tabs/Tabs.cjs +3 -1
- package/cjs/components/Tabs/Tabs.cjs.map +1 -1
- package/cjs/components/Tabs/Tabs.context.cjs.map +1 -1
- package/cjs/components/Tabs/TabsPanel/TabsPanel.cjs +2 -1
- package/cjs/components/Tabs/TabsPanel/TabsPanel.cjs.map +1 -1
- package/cjs/components/Textarea/Autosize.cjs +1 -0
- package/cjs/components/Textarea/Autosize.cjs.map +1 -1
- package/cjs/components/Tree/FlatTreeNode.cjs +102 -0
- package/cjs/components/Tree/FlatTreeNode.cjs.map +1 -0
- package/cjs/components/Tree/Tree.cjs +10 -2
- package/cjs/components/Tree/Tree.cjs.map +1 -1
- package/cjs/components/Tree/Tree.module.cjs.map +1 -1
- package/cjs/components/Tree/TreeNode.cjs +65 -27
- package/cjs/components/Tree/TreeNode.cjs.map +1 -1
- package/cjs/components/Tree/filter-tree-data/filter-tree-data.cjs +23 -0
- package/cjs/components/Tree/filter-tree-data/filter-tree-data.cjs.map +1 -0
- package/cjs/components/Tree/flatten-tree-data/flatten-tree-data.cjs +28 -0
- package/cjs/components/Tree/flatten-tree-data/flatten-tree-data.cjs.map +1 -0
- package/cjs/components/Tree/get-children-nodes-values/get-children-nodes-values.cjs +1 -0
- package/cjs/components/Tree/merge-async-children/merge-async-children.cjs +32 -0
- package/cjs/components/Tree/merge-async-children/merge-async-children.cjs.map +1 -0
- package/cjs/components/Tree/move-tree-node/move-tree-node.cjs +78 -0
- package/cjs/components/Tree/move-tree-node/move-tree-node.cjs.map +1 -0
- package/cjs/components/Tree/use-tree-node-drag-drop.cjs +96 -0
- package/cjs/components/Tree/use-tree-node-drag-drop.cjs.map +1 -0
- package/cjs/components/Tree/use-tree.cjs +176 -26
- package/cjs/components/Tree/use-tree.cjs.map +1 -1
- package/cjs/core/Box/Box.cjs +6 -2
- package/cjs/core/Box/Box.cjs.map +1 -1
- package/cjs/core/InlineStyles/InlineStyles.cjs +14 -2
- package/cjs/core/InlineStyles/InlineStyles.cjs.map +1 -1
- package/cjs/core/InlineStyles/hash-styles.cjs +15 -0
- package/cjs/core/InlineStyles/hash-styles.cjs.map +1 -0
- package/cjs/core/MantineProvider/Mantine.context.cjs +4 -0
- package/cjs/core/MantineProvider/Mantine.context.cjs.map +1 -1
- package/cjs/core/MantineProvider/MantineProvider.cjs +3 -2
- package/cjs/core/MantineProvider/MantineProvider.cjs.map +1 -1
- package/cjs/core/MantineProvider/color-functions/default-variant-colors-resolver/default-variant-colors-resolver.cjs +3 -4
- package/cjs/core/MantineProvider/color-functions/default-variant-colors-resolver/default-variant-colors-resolver.cjs.map +1 -1
- package/cjs/index.cjs +16 -0
- package/esm/components/Blockquote/Blockquote.mjs +5 -6
- package/esm/components/Blockquote/Blockquote.mjs.map +1 -1
- package/esm/components/Flex/Flex.mjs +7 -2
- package/esm/components/Flex/Flex.mjs.map +1 -1
- package/esm/components/FloatingIndicator/FloatingIndicator.mjs +1 -2
- package/esm/components/FloatingIndicator/FloatingIndicator.mjs.map +1 -1
- package/esm/components/MaskInput/MaskInput.mjs +23 -0
- package/esm/components/MaskInput/MaskInput.mjs.map +1 -0
- package/esm/components/MaskInput/use-mask-input-props.mjs +28 -0
- package/esm/components/MaskInput/use-mask-input-props.mjs.map +1 -0
- package/esm/components/Rating/Rating.mjs +1 -2
- package/esm/components/Rating/Rating.mjs.map +1 -1
- package/esm/components/SemiCircleProgress/SemiCircleProgress.mjs +2 -0
- package/esm/components/SemiCircleProgress/SemiCircleProgress.mjs.map +1 -1
- package/esm/components/Slider/Marks/Marks.mjs +3 -2
- package/esm/components/Slider/Marks/Marks.mjs.map +1 -1
- package/esm/components/Slider/Marks/is-mark-filled.mjs +2 -1
- package/esm/components/Slider/Marks/is-mark-filled.mjs.map +1 -1
- package/esm/components/Slider/Slider/Slider.mjs +12 -3
- package/esm/components/Slider/Slider/Slider.mjs.map +1 -1
- package/esm/components/Slider/Track/Track.mjs +3 -2
- package/esm/components/Slider/Track/Track.mjs.map +1 -1
- package/esm/components/Tabs/Tabs.context.mjs.map +1 -1
- package/esm/components/Tabs/Tabs.mjs +3 -1
- package/esm/components/Tabs/Tabs.mjs.map +1 -1
- package/esm/components/Tabs/TabsPanel/TabsPanel.mjs +2 -1
- package/esm/components/Tabs/TabsPanel/TabsPanel.mjs.map +1 -1
- package/esm/components/Textarea/Autosize.mjs +1 -0
- package/esm/components/Textarea/Autosize.mjs.map +1 -1
- package/esm/components/Tree/FlatTreeNode.mjs +101 -0
- package/esm/components/Tree/FlatTreeNode.mjs.map +1 -0
- package/esm/components/Tree/Tree.mjs +11 -3
- package/esm/components/Tree/Tree.mjs.map +1 -1
- package/esm/components/Tree/Tree.module.mjs.map +1 -1
- package/esm/components/Tree/TreeNode.mjs +65 -27
- package/esm/components/Tree/TreeNode.mjs.map +1 -1
- package/esm/components/Tree/filter-tree-data/filter-tree-data.mjs +22 -0
- package/esm/components/Tree/filter-tree-data/filter-tree-data.mjs.map +1 -0
- package/esm/components/Tree/flatten-tree-data/flatten-tree-data.mjs +28 -0
- package/esm/components/Tree/flatten-tree-data/flatten-tree-data.mjs.map +1 -0
- package/esm/components/Tree/get-children-nodes-values/get-children-nodes-values.mjs +1 -1
- package/esm/components/Tree/merge-async-children/merge-async-children.mjs +32 -0
- package/esm/components/Tree/merge-async-children/merge-async-children.mjs.map +1 -0
- package/esm/components/Tree/move-tree-node/move-tree-node.mjs +78 -0
- package/esm/components/Tree/move-tree-node/move-tree-node.mjs.map +1 -0
- package/esm/components/Tree/use-tree-node-drag-drop.mjs +96 -0
- package/esm/components/Tree/use-tree-node-drag-drop.mjs.map +1 -0
- package/esm/components/Tree/use-tree.mjs +177 -27
- package/esm/components/Tree/use-tree.mjs.map +1 -1
- package/esm/core/Box/Box.mjs +7 -3
- package/esm/core/Box/Box.mjs.map +1 -1
- package/esm/core/InlineStyles/InlineStyles.mjs +14 -2
- package/esm/core/InlineStyles/InlineStyles.mjs.map +1 -1
- package/esm/core/InlineStyles/hash-styles.mjs +15 -0
- package/esm/core/InlineStyles/hash-styles.mjs.map +1 -0
- package/esm/core/MantineProvider/Mantine.context.mjs +4 -1
- package/esm/core/MantineProvider/Mantine.context.mjs.map +1 -1
- package/esm/core/MantineProvider/MantineProvider.mjs +3 -2
- package/esm/core/MantineProvider/MantineProvider.mjs.map +1 -1
- package/esm/core/MantineProvider/color-functions/default-variant-colors-resolver/default-variant-colors-resolver.mjs +3 -4
- package/esm/core/MantineProvider/color-functions/default-variant-colors-resolver/default-variant-colors-resolver.mjs.map +1 -1
- package/esm/index.mjs +9 -2
- package/lib/components/MaskInput/MaskInput.d.ts +68 -0
- package/lib/components/MaskInput/index.d.ts +7 -0
- package/lib/components/MaskInput/use-mask-input-props.d.ts +428 -0
- package/lib/components/Slider/Marks/Marks.d.ts +2 -1
- package/lib/components/Slider/Marks/is-mark-filled.d.ts +2 -1
- package/lib/components/Slider/Slider/Slider.d.ts +2 -0
- package/lib/components/Slider/Track/Track.d.ts +2 -1
- package/lib/components/Tabs/Tabs.context.d.ts +1 -0
- package/lib/components/Tabs/Tabs.d.ts +2 -0
- package/lib/components/Tree/FlatTreeNode.d.ts +31 -0
- package/lib/components/Tree/Tree.d.ts +21 -1
- package/lib/components/Tree/TreeNode.d.ts +6 -2
- package/lib/components/Tree/filter-tree-data/filter-tree-data.d.ts +4 -0
- package/lib/components/Tree/flatten-tree-data/flatten-tree-data.d.ts +15 -0
- package/lib/components/Tree/index.d.ts +9 -0
- package/lib/components/Tree/merge-async-children/merge-async-children.d.ts +2 -0
- package/lib/components/Tree/move-tree-node/move-tree-node.d.ts +11 -0
- package/lib/components/Tree/use-tree-node-drag-drop.d.ts +18 -0
- package/lib/components/Tree/use-tree.d.ts +19 -1
- package/lib/components/index.d.ts +1 -0
- package/lib/core/InlineStyles/InlineStyles.d.ts +2 -1
- package/lib/core/InlineStyles/hash-styles.d.ts +2 -0
- package/lib/core/InlineStyles/index.d.ts +1 -0
- package/lib/core/MantineProvider/Mantine.context.d.ts +2 -0
- package/lib/core/MantineProvider/MantineProvider.d.ts +3 -1
- package/lib/core/MantineProvider/index.d.ts +1 -1
- package/package.json +5 -5
- package/styles/Tree.css +66 -0
- package/styles/Tree.layer.css +66 -0
- package/styles.css +66 -0
- package/styles.layer.css +66 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
//#region packages/@mantine/core/src/components/Tree/flatten-tree-data/flatten-tree-data.ts
|
|
3
|
+
function flattenTreeDataTo(acc, data, expandedState, parent, level) {
|
|
4
|
+
for (let i = 0; i < data.length; i++) {
|
|
5
|
+
const node = data[i];
|
|
6
|
+
const hasLoadedChildren = Array.isArray(node.children);
|
|
7
|
+
const hasAsyncChildren = !!node.hasChildren && !hasLoadedChildren;
|
|
8
|
+
const hasChildren = hasLoadedChildren || hasAsyncChildren;
|
|
9
|
+
const expanded = expandedState[node.value] || false;
|
|
10
|
+
acc.push({
|
|
11
|
+
node,
|
|
12
|
+
level,
|
|
13
|
+
parent,
|
|
14
|
+
hasChildren,
|
|
15
|
+
expanded
|
|
16
|
+
});
|
|
17
|
+
if (expanded && hasLoadedChildren) flattenTreeDataTo(acc, node.children, expandedState, node.value, level + 1);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function flattenTreeData(data, expandedState) {
|
|
21
|
+
const result = [];
|
|
22
|
+
flattenTreeDataTo(result, data, expandedState, null, 1);
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
exports.flattenTreeData = flattenTreeData;
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=flatten-tree-data.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flatten-tree-data.cjs","names":[],"sources":["../../../../src/components/Tree/flatten-tree-data/flatten-tree-data.ts"],"sourcesContent":["import type { TreeNodeData } from '../Tree';\nimport type { TreeExpandedState } from '../use-tree';\n\nexport interface FlattenedTreeNodeData {\n /** Node data from tree data */\n node: TreeNodeData;\n\n /** Nesting level of the node, starts at 1 */\n level: number;\n\n /** Value of the parent node, `null` for root nodes */\n parent: string | null;\n\n /** Whether the node has children */\n hasChildren: boolean;\n\n /** Whether the node is expanded */\n expanded: boolean;\n}\n\nfunction flattenTreeDataTo(\n acc: FlattenedTreeNodeData[],\n data: TreeNodeData[],\n expandedState: TreeExpandedState,\n parent: string | null,\n level: number\n): void {\n for (let i = 0; i < data.length; i++) {\n const node = data[i];\n const hasLoadedChildren = Array.isArray(node.children);\n const hasAsyncChildren = !!node.hasChildren && !hasLoadedChildren;\n const hasChildren = hasLoadedChildren || hasAsyncChildren;\n const expanded = expandedState[node.value] || false;\n\n acc.push({ node, level, parent, hasChildren, expanded });\n\n if (expanded && hasLoadedChildren) {\n flattenTreeDataTo(acc, node.children!, expandedState, node.value, level + 1);\n }\n }\n}\n\nexport function flattenTreeData(\n data: TreeNodeData[],\n expandedState: TreeExpandedState\n): FlattenedTreeNodeData[] {\n const result: FlattenedTreeNodeData[] = [];\n flattenTreeDataTo(result, data, expandedState, null, 1);\n return result;\n}\n"],"mappings":";;AAoBA,SAAS,kBACP,KACA,MACA,eACA,QACA,OACM;AACN,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;EACpC,MAAM,OAAO,KAAK;EAClB,MAAM,oBAAoB,MAAM,QAAQ,KAAK,SAAS;EACtD,MAAM,mBAAmB,CAAC,CAAC,KAAK,eAAe,CAAC;EAChD,MAAM,cAAc,qBAAqB;EACzC,MAAM,WAAW,cAAc,KAAK,UAAU;AAE9C,MAAI,KAAK;GAAE;GAAM;GAAO;GAAQ;GAAa;GAAU,CAAC;AAExD,MAAI,YAAY,kBACd,mBAAkB,KAAK,KAAK,UAAW,eAAe,KAAK,OAAO,QAAQ,EAAE;;;AAKlF,SAAgB,gBACd,MACA,eACyB;CACzB,MAAM,SAAkC,EAAE;AAC1C,mBAAkB,QAAQ,MAAM,eAAe,MAAM,EAAE;AACvD,QAAO"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
//#region packages/@mantine/core/src/components/Tree/merge-async-children/merge-async-children.ts
|
|
3
|
+
function mergeAsyncChildren(data, parentValue, children) {
|
|
4
|
+
let changed = false;
|
|
5
|
+
const result = data.map((node) => {
|
|
6
|
+
if (node.value === parentValue) {
|
|
7
|
+
changed = true;
|
|
8
|
+
const merged = {
|
|
9
|
+
...node,
|
|
10
|
+
children
|
|
11
|
+
};
|
|
12
|
+
delete merged.hasChildren;
|
|
13
|
+
return merged;
|
|
14
|
+
}
|
|
15
|
+
if (Array.isArray(node.children)) {
|
|
16
|
+
const updatedChildren = mergeAsyncChildren(node.children, parentValue, children);
|
|
17
|
+
if (updatedChildren !== node.children) {
|
|
18
|
+
changed = true;
|
|
19
|
+
return {
|
|
20
|
+
...node,
|
|
21
|
+
children: updatedChildren
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return node;
|
|
26
|
+
});
|
|
27
|
+
return changed ? result : data;
|
|
28
|
+
}
|
|
29
|
+
//#endregion
|
|
30
|
+
exports.mergeAsyncChildren = mergeAsyncChildren;
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=merge-async-children.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge-async-children.cjs","names":[],"sources":["../../../../src/components/Tree/merge-async-children/merge-async-children.ts"],"sourcesContent":["import type { TreeNodeData } from '../Tree';\n\nexport function mergeAsyncChildren(\n data: TreeNodeData[],\n parentValue: string,\n children: TreeNodeData[]\n): TreeNodeData[] {\n let changed = false;\n\n const result = data.map((node) => {\n if (node.value === parentValue) {\n changed = true;\n const merged: TreeNodeData = { ...node, children };\n delete merged.hasChildren;\n return merged;\n }\n\n if (Array.isArray(node.children)) {\n const updatedChildren = mergeAsyncChildren(node.children, parentValue, children);\n if (updatedChildren !== node.children) {\n changed = true;\n return { ...node, children: updatedChildren };\n }\n }\n\n return node;\n });\n\n return changed ? result : data;\n}\n"],"mappings":";;AAEA,SAAgB,mBACd,MACA,aACA,UACgB;CAChB,IAAI,UAAU;CAEd,MAAM,SAAS,KAAK,KAAK,SAAS;AAChC,MAAI,KAAK,UAAU,aAAa;AAC9B,aAAU;GACV,MAAM,SAAuB;IAAE,GAAG;IAAM;IAAU;AAClD,UAAO,OAAO;AACd,UAAO;;AAGT,MAAI,MAAM,QAAQ,KAAK,SAAS,EAAE;GAChC,MAAM,kBAAkB,mBAAmB,KAAK,UAAU,aAAa,SAAS;AAChF,OAAI,oBAAoB,KAAK,UAAU;AACrC,cAAU;AACV,WAAO;KAAE,GAAG;KAAM,UAAU;KAAiB;;;AAIjD,SAAO;GACP;AAEF,QAAO,UAAU,SAAS"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
const require_get_children_nodes_values = require("../get-children-nodes-values/get-children-nodes-values.cjs");
|
|
3
|
+
//#region packages/@mantine/core/src/components/Tree/move-tree-node/move-tree-node.ts
|
|
4
|
+
function isDescendant(data, ancestorValue, value) {
|
|
5
|
+
const ancestor = require_get_children_nodes_values.findTreeNode(ancestorValue, data);
|
|
6
|
+
if (!ancestor || !ancestor.children) return false;
|
|
7
|
+
function check(nodes) {
|
|
8
|
+
for (const node of nodes) {
|
|
9
|
+
if (node.value === value) return true;
|
|
10
|
+
if (node.children && check(node.children)) return true;
|
|
11
|
+
}
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
return check(ancestor.children);
|
|
15
|
+
}
|
|
16
|
+
function removeNode(data, value) {
|
|
17
|
+
let removed = null;
|
|
18
|
+
return {
|
|
19
|
+
data: data.reduce((acc, node) => {
|
|
20
|
+
if (node.value === value) {
|
|
21
|
+
removed = { ...node };
|
|
22
|
+
return acc;
|
|
23
|
+
}
|
|
24
|
+
if (node.children) {
|
|
25
|
+
const result = removeNode(node.children, value);
|
|
26
|
+
if (result.removed) {
|
|
27
|
+
removed = result.removed;
|
|
28
|
+
acc.push({
|
|
29
|
+
...node,
|
|
30
|
+
children: result.data
|
|
31
|
+
});
|
|
32
|
+
} else acc.push(node);
|
|
33
|
+
} else acc.push(node);
|
|
34
|
+
return acc;
|
|
35
|
+
}, []),
|
|
36
|
+
removed
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function insertNode(data, node, targetValue, position) {
|
|
40
|
+
if (position === "inside") return data.map((item) => {
|
|
41
|
+
if (item.value === targetValue) return {
|
|
42
|
+
...item,
|
|
43
|
+
children: [...item.children || [], node]
|
|
44
|
+
};
|
|
45
|
+
if (item.children) return {
|
|
46
|
+
...item,
|
|
47
|
+
children: insertNode(item.children, node, targetValue, position)
|
|
48
|
+
};
|
|
49
|
+
return item;
|
|
50
|
+
});
|
|
51
|
+
const targetIndex = data.findIndex((item) => item.value === targetValue);
|
|
52
|
+
if (targetIndex !== -1) {
|
|
53
|
+
const result = [...data];
|
|
54
|
+
const insertIndex = position === "before" ? targetIndex : targetIndex + 1;
|
|
55
|
+
result.splice(insertIndex, 0, node);
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
return data.map((item) => {
|
|
59
|
+
if (item.children) return {
|
|
60
|
+
...item,
|
|
61
|
+
children: insertNode(item.children, node, targetValue, position)
|
|
62
|
+
};
|
|
63
|
+
return item;
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
function moveTreeNode(data, payload) {
|
|
67
|
+
const { draggedNode, targetNode, position } = payload;
|
|
68
|
+
if (draggedNode === targetNode) return data;
|
|
69
|
+
if (!require_get_children_nodes_values.findTreeNode(targetNode, data)) return data;
|
|
70
|
+
if (isDescendant(data, draggedNode, targetNode)) return data;
|
|
71
|
+
const { data: dataWithout, removed } = removeNode(data, draggedNode);
|
|
72
|
+
if (!removed) return data;
|
|
73
|
+
return insertNode(dataWithout, removed, targetNode, position);
|
|
74
|
+
}
|
|
75
|
+
//#endregion
|
|
76
|
+
exports.moveTreeNode = moveTreeNode;
|
|
77
|
+
|
|
78
|
+
//# sourceMappingURL=move-tree-node.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"move-tree-node.cjs","names":["findTreeNode"],"sources":["../../../../src/components/Tree/move-tree-node/move-tree-node.ts"],"sourcesContent":["import { findTreeNode } from '../get-children-nodes-values/get-children-nodes-values';\nimport type { TreeNodeData } from '../Tree';\n\nexport type TreeDragDropPosition = 'before' | 'after' | 'inside';\n\nexport interface TreeDragDropPayload {\n /** Value of the dragged node */\n draggedNode: string;\n\n /** Value of the target node */\n targetNode: string;\n\n /** Position relative to the target node */\n position: TreeDragDropPosition;\n}\n\nfunction isDescendant(data: TreeNodeData[], ancestorValue: string, value: string): boolean {\n const ancestor = findTreeNode(ancestorValue, data);\n if (!ancestor || !ancestor.children) {\n return false;\n }\n\n function check(nodes: TreeNodeData[]): boolean {\n for (const node of nodes) {\n if (node.value === value) {\n return true;\n }\n\n if (node.children && check(node.children)) {\n return true;\n }\n }\n\n return false;\n }\n\n return check(ancestor.children);\n}\n\nfunction removeNode(\n data: TreeNodeData[],\n value: string\n): { data: TreeNodeData[]; removed: TreeNodeData | null } {\n let removed: TreeNodeData | null = null;\n\n const newData = data.reduce<TreeNodeData[]>((acc, node) => {\n if (node.value === value) {\n removed = { ...node };\n return acc;\n }\n\n if (node.children) {\n const result = removeNode(node.children, value);\n if (result.removed) {\n removed = result.removed;\n acc.push({ ...node, children: result.data });\n } else {\n acc.push(node);\n }\n } else {\n acc.push(node);\n }\n\n return acc;\n }, []);\n\n return { data: newData, removed };\n}\n\nfunction insertNode(\n data: TreeNodeData[],\n node: TreeNodeData,\n targetValue: string,\n position: TreeDragDropPosition\n): TreeNodeData[] {\n if (position === 'inside') {\n return data.map((item) => {\n if (item.value === targetValue) {\n return { ...item, children: [...(item.children || []), node] };\n }\n\n if (item.children) {\n return { ...item, children: insertNode(item.children, node, targetValue, position) };\n }\n\n return item;\n });\n }\n\n const targetIndex = data.findIndex((item) => item.value === targetValue);\n\n if (targetIndex !== -1) {\n const result = [...data];\n const insertIndex = position === 'before' ? targetIndex : targetIndex + 1;\n result.splice(insertIndex, 0, node);\n return result;\n }\n\n return data.map((item) => {\n if (item.children) {\n return { ...item, children: insertNode(item.children, node, targetValue, position) };\n }\n\n return item;\n });\n}\n\nexport function moveTreeNode(data: TreeNodeData[], payload: TreeDragDropPayload): TreeNodeData[] {\n const { draggedNode, targetNode, position } = payload;\n\n if (draggedNode === targetNode) {\n return data;\n }\n\n if (!findTreeNode(targetNode, data)) {\n return data;\n }\n\n if (isDescendant(data, draggedNode, targetNode)) {\n return data;\n }\n\n const { data: dataWithout, removed } = removeNode(data, draggedNode);\n\n if (!removed) {\n return data;\n }\n\n return insertNode(dataWithout, removed, targetNode, position);\n}\n"],"mappings":";;;AAgBA,SAAS,aAAa,MAAsB,eAAuB,OAAwB;CACzF,MAAM,WAAWA,kCAAAA,aAAa,eAAe,KAAK;AAClD,KAAI,CAAC,YAAY,CAAC,SAAS,SACzB,QAAO;CAGT,SAAS,MAAM,OAAgC;AAC7C,OAAK,MAAM,QAAQ,OAAO;AACxB,OAAI,KAAK,UAAU,MACjB,QAAO;AAGT,OAAI,KAAK,YAAY,MAAM,KAAK,SAAS,CACvC,QAAO;;AAIX,SAAO;;AAGT,QAAO,MAAM,SAAS,SAAS;;AAGjC,SAAS,WACP,MACA,OACwD;CACxD,IAAI,UAA+B;AAuBnC,QAAO;EAAE,MArBO,KAAK,QAAwB,KAAK,SAAS;AACzD,OAAI,KAAK,UAAU,OAAO;AACxB,cAAU,EAAE,GAAG,MAAM;AACrB,WAAO;;AAGT,OAAI,KAAK,UAAU;IACjB,MAAM,SAAS,WAAW,KAAK,UAAU,MAAM;AAC/C,QAAI,OAAO,SAAS;AAClB,eAAU,OAAO;AACjB,SAAI,KAAK;MAAE,GAAG;MAAM,UAAU,OAAO;MAAM,CAAC;UAE5C,KAAI,KAAK,KAAK;SAGhB,KAAI,KAAK,KAAK;AAGhB,UAAO;KACN,EAAE,CAAC;EAEkB;EAAS;;AAGnC,SAAS,WACP,MACA,MACA,aACA,UACgB;AAChB,KAAI,aAAa,SACf,QAAO,KAAK,KAAK,SAAS;AACxB,MAAI,KAAK,UAAU,YACjB,QAAO;GAAE,GAAG;GAAM,UAAU,CAAC,GAAI,KAAK,YAAY,EAAE,EAAG,KAAK;GAAE;AAGhE,MAAI,KAAK,SACP,QAAO;GAAE,GAAG;GAAM,UAAU,WAAW,KAAK,UAAU,MAAM,aAAa,SAAS;GAAE;AAGtF,SAAO;GACP;CAGJ,MAAM,cAAc,KAAK,WAAW,SAAS,KAAK,UAAU,YAAY;AAExE,KAAI,gBAAgB,IAAI;EACtB,MAAM,SAAS,CAAC,GAAG,KAAK;EACxB,MAAM,cAAc,aAAa,WAAW,cAAc,cAAc;AACxE,SAAO,OAAO,aAAa,GAAG,KAAK;AACnC,SAAO;;AAGT,QAAO,KAAK,KAAK,SAAS;AACxB,MAAI,KAAK,SACP,QAAO;GAAE,GAAG;GAAM,UAAU,WAAW,KAAK,UAAU,MAAM,aAAa,SAAS;GAAE;AAGtF,SAAO;GACP;;AAGJ,SAAgB,aAAa,MAAsB,SAA8C;CAC/F,MAAM,EAAE,aAAa,YAAY,aAAa;AAE9C,KAAI,gBAAgB,WAClB,QAAO;AAGT,KAAI,CAACA,kCAAAA,aAAa,YAAY,KAAK,CACjC,QAAO;AAGT,KAAI,aAAa,MAAM,aAAa,WAAW,CAC7C,QAAO;CAGT,MAAM,EAAE,MAAM,aAAa,YAAY,WAAW,MAAM,YAAY;AAEpE,KAAI,CAAC,QACH,QAAO;AAGT,QAAO,WAAW,aAAa,SAAS,YAAY,SAAS"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
const require_get_children_nodes_values = require("./get-children-nodes-values/get-children-nodes-values.cjs");
|
|
3
|
+
//#region packages/@mantine/core/src/components/Tree/use-tree-node-drag-drop.ts
|
|
4
|
+
function isDescendantOf(data, ancestorValue, descendantValue) {
|
|
5
|
+
const ancestor = require_get_children_nodes_values.findTreeNode(ancestorValue, data);
|
|
6
|
+
if (!ancestor || !ancestor.children) return false;
|
|
7
|
+
function check(nodes) {
|
|
8
|
+
for (const node of nodes) {
|
|
9
|
+
if (node.value === descendantValue) return true;
|
|
10
|
+
if (node.children && check(node.children)) return true;
|
|
11
|
+
}
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
return check(ancestor.children);
|
|
15
|
+
}
|
|
16
|
+
function getDragDropPosition(event, element, hasChildren) {
|
|
17
|
+
const rect = element.getBoundingClientRect();
|
|
18
|
+
const y = event.clientY - rect.top;
|
|
19
|
+
const height = rect.height;
|
|
20
|
+
if (hasChildren) {
|
|
21
|
+
if (y < height * .25) return "before";
|
|
22
|
+
if (y > height * .75) return "after";
|
|
23
|
+
return "inside";
|
|
24
|
+
}
|
|
25
|
+
if (y < height * .5) return "before";
|
|
26
|
+
return "after";
|
|
27
|
+
}
|
|
28
|
+
const EMPTY_DRAG_PROPS = {};
|
|
29
|
+
function useTreeNodeDragDrop({ nodeValue, hasChildren, data, onDragDrop, dragStateRef }) {
|
|
30
|
+
if (!onDragDrop) return EMPTY_DRAG_PROPS;
|
|
31
|
+
const handleDragStart = (event) => {
|
|
32
|
+
event.stopPropagation();
|
|
33
|
+
event.dataTransfer.effectAllowed = "move";
|
|
34
|
+
event.dataTransfer.setData("text/plain", nodeValue);
|
|
35
|
+
dragStateRef.current.draggedValue = nodeValue;
|
|
36
|
+
const target = event.currentTarget;
|
|
37
|
+
requestAnimationFrame(() => {
|
|
38
|
+
target.setAttribute("data-dragging", "true");
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
const handleDragOver = (event) => {
|
|
42
|
+
const draggedValue = dragStateRef.current.draggedValue;
|
|
43
|
+
if (!draggedValue || draggedValue === nodeValue) return;
|
|
44
|
+
if (isDescendantOf(data, draggedValue, nodeValue)) return;
|
|
45
|
+
event.preventDefault();
|
|
46
|
+
event.stopPropagation();
|
|
47
|
+
event.dataTransfer.dropEffect = "move";
|
|
48
|
+
const target = event.currentTarget;
|
|
49
|
+
const position = getDragDropPosition(event, target, hasChildren);
|
|
50
|
+
const prevTarget = dragStateRef.current.currentDropTarget;
|
|
51
|
+
if (prevTarget && prevTarget !== target) prevTarget.removeAttribute("data-drag-over");
|
|
52
|
+
target.setAttribute("data-drag-over", position);
|
|
53
|
+
dragStateRef.current.currentDropTarget = target;
|
|
54
|
+
};
|
|
55
|
+
const handleDragLeave = (event) => {
|
|
56
|
+
const target = event.currentTarget;
|
|
57
|
+
const related = event.relatedTarget;
|
|
58
|
+
if (related && target.contains(related)) return;
|
|
59
|
+
target.removeAttribute("data-drag-over");
|
|
60
|
+
if (dragStateRef.current.currentDropTarget === target) dragStateRef.current.currentDropTarget = null;
|
|
61
|
+
};
|
|
62
|
+
const handleDrop = (event) => {
|
|
63
|
+
event.preventDefault();
|
|
64
|
+
event.stopPropagation();
|
|
65
|
+
const target = event.currentTarget;
|
|
66
|
+
const position = target.getAttribute("data-drag-over");
|
|
67
|
+
target.removeAttribute("data-drag-over");
|
|
68
|
+
const draggedValue = dragStateRef.current.draggedValue;
|
|
69
|
+
if (draggedValue && position && draggedValue !== nodeValue) onDragDrop({
|
|
70
|
+
draggedNode: draggedValue,
|
|
71
|
+
targetNode: nodeValue,
|
|
72
|
+
position
|
|
73
|
+
});
|
|
74
|
+
dragStateRef.current.draggedValue = null;
|
|
75
|
+
dragStateRef.current.currentDropTarget = null;
|
|
76
|
+
};
|
|
77
|
+
const handleDragEnd = (event) => {
|
|
78
|
+
event.currentTarget.removeAttribute("data-dragging");
|
|
79
|
+
const prevTarget = dragStateRef.current.currentDropTarget;
|
|
80
|
+
if (prevTarget) prevTarget.removeAttribute("data-drag-over");
|
|
81
|
+
dragStateRef.current.draggedValue = null;
|
|
82
|
+
dragStateRef.current.currentDropTarget = null;
|
|
83
|
+
};
|
|
84
|
+
return {
|
|
85
|
+
draggable: true,
|
|
86
|
+
onDragStart: handleDragStart,
|
|
87
|
+
onDragOver: handleDragOver,
|
|
88
|
+
onDragLeave: handleDragLeave,
|
|
89
|
+
onDrop: handleDrop,
|
|
90
|
+
onDragEnd: handleDragEnd
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
//#endregion
|
|
94
|
+
exports.useTreeNodeDragDrop = useTreeNodeDragDrop;
|
|
95
|
+
|
|
96
|
+
//# sourceMappingURL=use-tree-node-drag-drop.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-tree-node-drag-drop.cjs","names":["findTreeNode"],"sources":["../../../src/components/Tree/use-tree-node-drag-drop.ts"],"sourcesContent":["import { findTreeNode } from './get-children-nodes-values/get-children-nodes-values';\nimport type { TreeDragDropPayload, TreeDragDropPosition } from './move-tree-node/move-tree-node';\nimport type { TreeDragState, TreeNodeData } from './Tree';\n\ninterface UseTreeNodeDragDropInput {\n nodeValue: string;\n hasChildren: boolean;\n data: TreeNodeData[];\n onDragDrop: ((payload: TreeDragDropPayload) => void) | undefined;\n dragStateRef: React.RefObject<TreeDragState>;\n}\n\nfunction isDescendantOf(\n data: TreeNodeData[],\n ancestorValue: string,\n descendantValue: string\n): boolean {\n const ancestor = findTreeNode(ancestorValue, data);\n if (!ancestor || !ancestor.children) {\n return false;\n }\n\n function check(nodes: TreeNodeData[]): boolean {\n for (const node of nodes) {\n if (node.value === descendantValue) {\n return true;\n }\n\n if (node.children && check(node.children)) {\n return true;\n }\n }\n\n return false;\n }\n\n return check(ancestor.children);\n}\n\nfunction getDragDropPosition(\n event: React.DragEvent,\n element: HTMLElement,\n hasChildren: boolean\n): TreeDragDropPosition {\n const rect = element.getBoundingClientRect();\n const y = event.clientY - rect.top;\n const height = rect.height;\n\n if (hasChildren) {\n if (y < height * 0.25) {\n return 'before';\n }\n\n if (y > height * 0.75) {\n return 'after';\n }\n\n return 'inside';\n }\n\n if (y < height * 0.5) {\n return 'before';\n }\n\n return 'after';\n}\n\nconst EMPTY_DRAG_PROPS: Record<string, never> = {};\n\nexport function useTreeNodeDragDrop({\n nodeValue,\n hasChildren,\n data,\n onDragDrop,\n dragStateRef,\n}: UseTreeNodeDragDropInput) {\n if (!onDragDrop) {\n return EMPTY_DRAG_PROPS;\n }\n\n const handleDragStart = (event: React.DragEvent) => {\n event.stopPropagation();\n event.dataTransfer.effectAllowed = 'move';\n event.dataTransfer.setData('text/plain', nodeValue);\n dragStateRef.current.draggedValue = nodeValue;\n\n const target = event.currentTarget as HTMLElement;\n requestAnimationFrame(() => {\n target.setAttribute('data-dragging', 'true');\n });\n };\n\n const handleDragOver = (event: React.DragEvent) => {\n const draggedValue = dragStateRef.current.draggedValue;\n if (!draggedValue || draggedValue === nodeValue) {\n return;\n }\n\n if (isDescendantOf(data, draggedValue, nodeValue)) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n event.dataTransfer.dropEffect = 'move';\n\n const target = event.currentTarget as HTMLElement;\n const position = getDragDropPosition(event, target, hasChildren);\n\n const prevTarget = dragStateRef.current.currentDropTarget;\n if (prevTarget && prevTarget !== target) {\n prevTarget.removeAttribute('data-drag-over');\n }\n\n target.setAttribute('data-drag-over', position);\n dragStateRef.current.currentDropTarget = target;\n };\n\n const handleDragLeave = (event: React.DragEvent) => {\n const target = event.currentTarget as HTMLElement;\n const related = event.relatedTarget as HTMLElement | null;\n\n if (related && target.contains(related)) {\n return;\n }\n\n target.removeAttribute('data-drag-over');\n\n if (dragStateRef.current.currentDropTarget === target) {\n dragStateRef.current.currentDropTarget = null;\n }\n };\n\n const handleDrop = (event: React.DragEvent) => {\n event.preventDefault();\n event.stopPropagation();\n\n const target = event.currentTarget as HTMLElement;\n const position = target.getAttribute('data-drag-over') as TreeDragDropPosition | null;\n target.removeAttribute('data-drag-over');\n\n const draggedValue = dragStateRef.current.draggedValue;\n if (draggedValue && position && draggedValue !== nodeValue) {\n onDragDrop({ draggedNode: draggedValue, targetNode: nodeValue, position });\n }\n\n dragStateRef.current.draggedValue = null;\n dragStateRef.current.currentDropTarget = null;\n };\n\n const handleDragEnd = (event: React.DragEvent) => {\n const target = event.currentTarget as HTMLElement;\n target.removeAttribute('data-dragging');\n\n const prevTarget = dragStateRef.current.currentDropTarget;\n if (prevTarget) {\n prevTarget.removeAttribute('data-drag-over');\n }\n\n dragStateRef.current.draggedValue = null;\n dragStateRef.current.currentDropTarget = null;\n };\n\n return {\n draggable: true as const,\n onDragStart: handleDragStart,\n onDragOver: handleDragOver,\n onDragLeave: handleDragLeave,\n onDrop: handleDrop,\n onDragEnd: handleDragEnd,\n };\n}\n"],"mappings":";;;AAYA,SAAS,eACP,MACA,eACA,iBACS;CACT,MAAM,WAAWA,kCAAAA,aAAa,eAAe,KAAK;AAClD,KAAI,CAAC,YAAY,CAAC,SAAS,SACzB,QAAO;CAGT,SAAS,MAAM,OAAgC;AAC7C,OAAK,MAAM,QAAQ,OAAO;AACxB,OAAI,KAAK,UAAU,gBACjB,QAAO;AAGT,OAAI,KAAK,YAAY,MAAM,KAAK,SAAS,CACvC,QAAO;;AAIX,SAAO;;AAGT,QAAO,MAAM,SAAS,SAAS;;AAGjC,SAAS,oBACP,OACA,SACA,aACsB;CACtB,MAAM,OAAO,QAAQ,uBAAuB;CAC5C,MAAM,IAAI,MAAM,UAAU,KAAK;CAC/B,MAAM,SAAS,KAAK;AAEpB,KAAI,aAAa;AACf,MAAI,IAAI,SAAS,IACf,QAAO;AAGT,MAAI,IAAI,SAAS,IACf,QAAO;AAGT,SAAO;;AAGT,KAAI,IAAI,SAAS,GACf,QAAO;AAGT,QAAO;;AAGT,MAAM,mBAA0C,EAAE;AAElD,SAAgB,oBAAoB,EAClC,WACA,aACA,MACA,YACA,gBAC2B;AAC3B,KAAI,CAAC,WACH,QAAO;CAGT,MAAM,mBAAmB,UAA2B;AAClD,QAAM,iBAAiB;AACvB,QAAM,aAAa,gBAAgB;AACnC,QAAM,aAAa,QAAQ,cAAc,UAAU;AACnD,eAAa,QAAQ,eAAe;EAEpC,MAAM,SAAS,MAAM;AACrB,8BAA4B;AAC1B,UAAO,aAAa,iBAAiB,OAAO;IAC5C;;CAGJ,MAAM,kBAAkB,UAA2B;EACjD,MAAM,eAAe,aAAa,QAAQ;AAC1C,MAAI,CAAC,gBAAgB,iBAAiB,UACpC;AAGF,MAAI,eAAe,MAAM,cAAc,UAAU,CAC/C;AAGF,QAAM,gBAAgB;AACtB,QAAM,iBAAiB;AACvB,QAAM,aAAa,aAAa;EAEhC,MAAM,SAAS,MAAM;EACrB,MAAM,WAAW,oBAAoB,OAAO,QAAQ,YAAY;EAEhE,MAAM,aAAa,aAAa,QAAQ;AACxC,MAAI,cAAc,eAAe,OAC/B,YAAW,gBAAgB,iBAAiB;AAG9C,SAAO,aAAa,kBAAkB,SAAS;AAC/C,eAAa,QAAQ,oBAAoB;;CAG3C,MAAM,mBAAmB,UAA2B;EAClD,MAAM,SAAS,MAAM;EACrB,MAAM,UAAU,MAAM;AAEtB,MAAI,WAAW,OAAO,SAAS,QAAQ,CACrC;AAGF,SAAO,gBAAgB,iBAAiB;AAExC,MAAI,aAAa,QAAQ,sBAAsB,OAC7C,cAAa,QAAQ,oBAAoB;;CAI7C,MAAM,cAAc,UAA2B;AAC7C,QAAM,gBAAgB;AACtB,QAAM,iBAAiB;EAEvB,MAAM,SAAS,MAAM;EACrB,MAAM,WAAW,OAAO,aAAa,iBAAiB;AACtD,SAAO,gBAAgB,iBAAiB;EAExC,MAAM,eAAe,aAAa,QAAQ;AAC1C,MAAI,gBAAgB,YAAY,iBAAiB,UAC/C,YAAW;GAAE,aAAa;GAAc,YAAY;GAAW;GAAU,CAAC;AAG5E,eAAa,QAAQ,eAAe;AACpC,eAAa,QAAQ,oBAAoB;;CAG3C,MAAM,iBAAiB,UAA2B;AACjC,QAAM,cACd,gBAAgB,gBAAgB;EAEvC,MAAM,aAAa,aAAa,QAAQ;AACxC,MAAI,WACF,YAAW,gBAAgB,iBAAiB;AAG9C,eAAa,QAAQ,eAAe;AACpC,eAAa,QAAQ,oBAAoB;;AAG3C,QAAO;EACL,WAAW;EACX,aAAa;EACb,YAAY;EACZ,aAAa;EACb,QAAQ;EACR,WAAW;EACZ"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
require("../../_virtual/_rolldown/runtime.cjs");
|
|
3
|
-
const require_get_all_checked_nodes = require("./get-all-checked-nodes/get-all-checked-nodes.cjs");
|
|
4
3
|
const require_get_children_nodes_values = require("./get-children-nodes-values/get-children-nodes-values.cjs");
|
|
4
|
+
const require_get_all_checked_nodes = require("./get-all-checked-nodes/get-all-checked-nodes.cjs");
|
|
5
5
|
const require_is_node_checked = require("./is-node-checked/is-node-checked.cjs");
|
|
6
6
|
const require_is_node_indeterminate = require("./is-node-indeterminate/is-node-indeterminate.cjs");
|
|
7
7
|
let react = require("react");
|
|
@@ -16,21 +16,32 @@ function getInitialTreeExpandedState(initialState, data, value, acc = {}) {
|
|
|
16
16
|
}
|
|
17
17
|
function getTreeExpandedState(data, expandedNodesValues) {
|
|
18
18
|
const state = getInitialTreeExpandedState({}, data, []);
|
|
19
|
-
if (expandedNodesValues === "*")
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
if (expandedNodesValues === "*") {
|
|
20
|
+
const result = {};
|
|
21
|
+
const keys = Object.keys(state);
|
|
22
|
+
for (let i = 0; i < keys.length; i++) result[keys[i]] = true;
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
23
25
|
expandedNodesValues.forEach((node) => {
|
|
24
26
|
state[node] = true;
|
|
25
27
|
});
|
|
26
28
|
return state;
|
|
27
29
|
}
|
|
28
|
-
function getInitialCheckedState(initialState, data) {
|
|
30
|
+
function getInitialCheckedState(initialState, data, checkStrictly) {
|
|
31
|
+
if (checkStrictly) return initialState;
|
|
29
32
|
const acc = [];
|
|
30
33
|
initialState.forEach((node) => acc.push(...require_get_children_nodes_values.getChildrenNodesValues(node, data)));
|
|
31
34
|
return Array.from(new Set(acc));
|
|
32
35
|
}
|
|
33
|
-
function
|
|
36
|
+
function getAllNodeValues(data) {
|
|
37
|
+
const acc = [];
|
|
38
|
+
for (const node of data) {
|
|
39
|
+
acc.push(node.value);
|
|
40
|
+
if (Array.isArray(node.children) && node.children.length > 0) acc.push(...getAllNodeValues(node.children));
|
|
41
|
+
}
|
|
42
|
+
return acc;
|
|
43
|
+
}
|
|
44
|
+
function useTree({ initialSelectedState = [], expandedState, initialCheckedState = [], checkedState, initialExpandedState = {}, selectedState, multiple = false, onNodeCollapse, onNodeExpand, onCheckedStateChange, onSelectedStateChange, onExpandedStateChange, onLoadChildren, checkStrictly = false } = {}) {
|
|
34
45
|
const [data, setData] = (0, react.useState)([]);
|
|
35
46
|
const [_expandedState, setExpandedState] = (0, _mantine_hooks.useUncontrolled)({
|
|
36
47
|
value: expandedState,
|
|
@@ -51,14 +62,53 @@ function useTree({ initialSelectedState = [], expandedState, initialCheckedState
|
|
|
51
62
|
onChange: onCheckedStateChange
|
|
52
63
|
});
|
|
53
64
|
const [anchorNode, setAnchorNode] = (0, react.useState)(null);
|
|
65
|
+
const loadingNodesRef = (0, react.useRef)(/* @__PURE__ */ new Set());
|
|
66
|
+
const loadedNodesRef = (0, react.useRef)(/* @__PURE__ */ new Set());
|
|
67
|
+
const [loadingNodes, setLoadingNodes] = (0, react.useState)([]);
|
|
68
|
+
const [loadErrors, setLoadErrors] = (0, react.useState)({});
|
|
54
69
|
const initialize = (0, react.useCallback)((_data) => {
|
|
55
70
|
setExpandedState(getInitialTreeExpandedState(_expandedState, _data, _selectedState));
|
|
56
|
-
setCheckedState(getInitialCheckedState(_checkedState, _data));
|
|
71
|
+
setCheckedState(getInitialCheckedState(_checkedState, _data, checkStrictly));
|
|
57
72
|
setData(_data);
|
|
58
73
|
}, [
|
|
59
74
|
_selectedState,
|
|
60
75
|
_checkedState,
|
|
61
|
-
_expandedState
|
|
76
|
+
_expandedState,
|
|
77
|
+
checkStrictly
|
|
78
|
+
]);
|
|
79
|
+
const loadNodeImpl = (0, react.useCallback)(async (value) => {
|
|
80
|
+
if (!onLoadChildren) return;
|
|
81
|
+
if (loadingNodesRef.current.has(value) || loadedNodesRef.current.has(value)) return;
|
|
82
|
+
loadingNodesRef.current.add(value);
|
|
83
|
+
setLoadingNodes(Array.from(loadingNodesRef.current));
|
|
84
|
+
setLoadErrors((prev) => {
|
|
85
|
+
if (!(value in prev)) return prev;
|
|
86
|
+
const next = { ...prev };
|
|
87
|
+
delete next[value];
|
|
88
|
+
return next;
|
|
89
|
+
});
|
|
90
|
+
try {
|
|
91
|
+
await onLoadChildren(value);
|
|
92
|
+
loadedNodesRef.current.add(value);
|
|
93
|
+
} catch (error) {
|
|
94
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
95
|
+
setLoadErrors((prev) => ({
|
|
96
|
+
...prev,
|
|
97
|
+
[value]: err
|
|
98
|
+
}));
|
|
99
|
+
} finally {
|
|
100
|
+
loadingNodesRef.current.delete(value);
|
|
101
|
+
setLoadingNodes(Array.from(loadingNodesRef.current));
|
|
102
|
+
}
|
|
103
|
+
}, [onLoadChildren]);
|
|
104
|
+
const tryLoadAsync = (0, react.useCallback)((value) => {
|
|
105
|
+
if (!onLoadChildren) return;
|
|
106
|
+
const node = require_get_children_nodes_values.findTreeNode(value, data);
|
|
107
|
+
if (node && node.hasChildren && !Array.isArray(node.children)) loadNodeImpl(value);
|
|
108
|
+
}, [
|
|
109
|
+
onLoadChildren,
|
|
110
|
+
data,
|
|
111
|
+
loadNodeImpl
|
|
62
112
|
]);
|
|
63
113
|
const toggleExpanded = (0, react.useCallback)((value) => {
|
|
64
114
|
const nextState = {
|
|
@@ -66,11 +116,13 @@ function useTree({ initialSelectedState = [], expandedState, initialCheckedState
|
|
|
66
116
|
[value]: !_expandedState[value]
|
|
67
117
|
};
|
|
68
118
|
nextState[value] ? onNodeExpand?.(value) : onNodeCollapse?.(value);
|
|
119
|
+
if (nextState[value]) tryLoadAsync(value);
|
|
69
120
|
setExpandedState(nextState);
|
|
70
121
|
}, [
|
|
71
122
|
onNodeCollapse,
|
|
72
123
|
onNodeExpand,
|
|
73
|
-
_expandedState
|
|
124
|
+
_expandedState,
|
|
125
|
+
tryLoadAsync
|
|
74
126
|
]);
|
|
75
127
|
const collapse = (0, react.useCallback)((value) => {
|
|
76
128
|
if (_expandedState[value] !== false) onNodeCollapse?.(value);
|
|
@@ -81,18 +133,24 @@ function useTree({ initialSelectedState = [], expandedState, initialCheckedState
|
|
|
81
133
|
}, [onNodeCollapse, _expandedState]);
|
|
82
134
|
const expand = (0, react.useCallback)((value) => {
|
|
83
135
|
if (_expandedState[value] !== true) onNodeExpand?.(value);
|
|
136
|
+
tryLoadAsync(value);
|
|
84
137
|
setExpandedState({
|
|
85
138
|
..._expandedState,
|
|
86
139
|
[value]: true
|
|
87
140
|
});
|
|
88
|
-
}, [
|
|
141
|
+
}, [
|
|
142
|
+
onNodeExpand,
|
|
143
|
+
_expandedState,
|
|
144
|
+
tryLoadAsync
|
|
145
|
+
]);
|
|
89
146
|
const expandAllNodes = (0, react.useCallback)(() => {
|
|
90
147
|
const nextState = { ..._expandedState };
|
|
91
148
|
Object.keys(nextState).forEach((key) => {
|
|
92
149
|
nextState[key] = true;
|
|
150
|
+
tryLoadAsync(key);
|
|
93
151
|
});
|
|
94
152
|
setExpandedState(nextState);
|
|
95
|
-
}, [_expandedState]);
|
|
153
|
+
}, [_expandedState, tryLoadAsync]);
|
|
96
154
|
const collapseAllNodes = (0, react.useCallback)(() => {
|
|
97
155
|
const nextState = { ..._expandedState };
|
|
98
156
|
Object.keys(nextState).forEach((key) => {
|
|
@@ -129,23 +187,80 @@ function useTree({ initialSelectedState = [], expandedState, initialCheckedState
|
|
|
129
187
|
setAnchorNode(null);
|
|
130
188
|
}, []);
|
|
131
189
|
const checkNode = (0, react.useCallback)((value) => {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
190
|
+
if (checkStrictly) {
|
|
191
|
+
if (!_checkedState.includes(value)) setCheckedState([..._checkedState, value]);
|
|
192
|
+
} else {
|
|
193
|
+
const checkedNodes = require_get_children_nodes_values.getChildrenNodesValues(value, data);
|
|
194
|
+
setCheckedState(Array.from(new Set([..._checkedState, ...checkedNodes])));
|
|
195
|
+
}
|
|
196
|
+
}, [
|
|
197
|
+
data,
|
|
198
|
+
_checkedState,
|
|
199
|
+
checkStrictly
|
|
200
|
+
]);
|
|
135
201
|
const uncheckNode = (0, react.useCallback)((value) => {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
202
|
+
if (checkStrictly) setCheckedState(_checkedState.filter((item) => item !== value));
|
|
203
|
+
else {
|
|
204
|
+
const checkedNodes = require_get_children_nodes_values.getChildrenNodesValues(value, data);
|
|
205
|
+
setCheckedState(_checkedState.filter((item) => !checkedNodes.includes(item)));
|
|
206
|
+
}
|
|
207
|
+
}, [
|
|
208
|
+
data,
|
|
209
|
+
_checkedState,
|
|
210
|
+
checkStrictly
|
|
211
|
+
]);
|
|
139
212
|
const checkAllNodes = (0, react.useCallback)(() => {
|
|
140
|
-
setCheckedState(
|
|
141
|
-
|
|
213
|
+
if (checkStrictly) setCheckedState(getAllNodeValues(data));
|
|
214
|
+
else setCheckedState(require_get_children_nodes_values.getAllChildrenNodes(data));
|
|
215
|
+
}, [data, checkStrictly]);
|
|
142
216
|
const uncheckAllNodes = (0, react.useCallback)(() => {
|
|
143
217
|
setCheckedState([]);
|
|
144
218
|
}, []);
|
|
145
|
-
const getCheckedNodes = () =>
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
219
|
+
const getCheckedNodes = (0, react.useCallback)(() => {
|
|
220
|
+
if (checkStrictly) return _checkedState.map((value) => {
|
|
221
|
+
const node = require_get_children_nodes_values.findTreeNode(value, data);
|
|
222
|
+
return {
|
|
223
|
+
checked: true,
|
|
224
|
+
indeterminate: false,
|
|
225
|
+
value,
|
|
226
|
+
hasChildren: node ? Array.isArray(node.children) && node.children.length > 0 || !!node.hasChildren : false
|
|
227
|
+
};
|
|
228
|
+
});
|
|
229
|
+
return require_get_all_checked_nodes.getAllCheckedNodes(data, _checkedState).result;
|
|
230
|
+
}, [
|
|
231
|
+
checkStrictly,
|
|
232
|
+
_checkedState,
|
|
233
|
+
data
|
|
234
|
+
]);
|
|
235
|
+
const isNodeChecked = (0, react.useCallback)((value) => {
|
|
236
|
+
if (checkStrictly) return _checkedState.includes(value);
|
|
237
|
+
return require_is_node_checked.memoizedIsNodeChecked(value, data, _checkedState);
|
|
238
|
+
}, [
|
|
239
|
+
checkStrictly,
|
|
240
|
+
_checkedState,
|
|
241
|
+
data
|
|
242
|
+
]);
|
|
243
|
+
const isNodeIndeterminate = (0, react.useCallback)((value) => {
|
|
244
|
+
if (checkStrictly) return false;
|
|
245
|
+
return require_is_node_indeterminate.memoizedIsNodeIndeterminate(value, data, _checkedState);
|
|
246
|
+
}, [
|
|
247
|
+
checkStrictly,
|
|
248
|
+
_checkedState,
|
|
249
|
+
data
|
|
250
|
+
]);
|
|
251
|
+
const isNodeLoading = (0, react.useCallback)((value) => loadingNodes.includes(value), [loadingNodes]);
|
|
252
|
+
const getNodeLoadError = (0, react.useCallback)((value) => loadErrors[value] || null, [loadErrors]);
|
|
253
|
+
const invalidateNode = (0, react.useCallback)((value) => {
|
|
254
|
+
loadedNodesRef.current.delete(value);
|
|
255
|
+
setLoadErrors((prev) => {
|
|
256
|
+
if (!(value in prev)) return prev;
|
|
257
|
+
const next = { ...prev };
|
|
258
|
+
delete next[value];
|
|
259
|
+
return next;
|
|
260
|
+
});
|
|
261
|
+
}, []);
|
|
262
|
+
return (0, react.useMemo)(() => ({
|
|
263
|
+
checkStrictly,
|
|
149
264
|
multiple,
|
|
150
265
|
expandedState: _expandedState,
|
|
151
266
|
selectedState: _selectedState,
|
|
@@ -170,8 +285,43 @@ function useTree({ initialSelectedState = [], expandedState, initialCheckedState
|
|
|
170
285
|
setSelectedState,
|
|
171
286
|
getCheckedNodes,
|
|
172
287
|
isNodeChecked,
|
|
173
|
-
isNodeIndeterminate
|
|
174
|
-
|
|
288
|
+
isNodeIndeterminate,
|
|
289
|
+
isNodeLoading,
|
|
290
|
+
getNodeLoadError,
|
|
291
|
+
loadNode: loadNodeImpl,
|
|
292
|
+
invalidateNode
|
|
293
|
+
}), [
|
|
294
|
+
checkStrictly,
|
|
295
|
+
multiple,
|
|
296
|
+
_expandedState,
|
|
297
|
+
_selectedState,
|
|
298
|
+
_checkedState,
|
|
299
|
+
anchorNode,
|
|
300
|
+
initialize,
|
|
301
|
+
toggleExpanded,
|
|
302
|
+
collapse,
|
|
303
|
+
expand,
|
|
304
|
+
expandAllNodes,
|
|
305
|
+
collapseAllNodes,
|
|
306
|
+
setExpandedState,
|
|
307
|
+
checkNode,
|
|
308
|
+
uncheckNode,
|
|
309
|
+
checkAllNodes,
|
|
310
|
+
uncheckAllNodes,
|
|
311
|
+
setCheckedState,
|
|
312
|
+
toggleSelected,
|
|
313
|
+
select,
|
|
314
|
+
deselect,
|
|
315
|
+
clearSelected,
|
|
316
|
+
setSelectedState,
|
|
317
|
+
getCheckedNodes,
|
|
318
|
+
isNodeChecked,
|
|
319
|
+
isNodeIndeterminate,
|
|
320
|
+
isNodeLoading,
|
|
321
|
+
getNodeLoadError,
|
|
322
|
+
loadNodeImpl,
|
|
323
|
+
invalidateNode
|
|
324
|
+
]);
|
|
175
325
|
}
|
|
176
326
|
//#endregion
|
|
177
327
|
exports.getTreeExpandedState = getTreeExpandedState;
|