@mantine/core 9.0.2 → 9.1.1
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/Card/Card.cjs +1 -1
- package/cjs/components/Card/Card.cjs.map +1 -1
- package/cjs/components/Combobox/ComboboxClearButton/ComboboxClearButton.cjs +1 -1
- package/cjs/components/Combobox/ComboboxClearButton/ComboboxClearButton.cjs.map +1 -1
- package/cjs/components/Combobox/ComboboxEventsTarget/ComboboxEventsTarget.cjs +1 -0
- package/cjs/components/Combobox/ComboboxEventsTarget/ComboboxEventsTarget.cjs.map +1 -1
- package/cjs/components/Combobox/ComboboxSearch/ComboboxSearch.cjs +2 -1
- package/cjs/components/Combobox/ComboboxSearch/ComboboxSearch.cjs.map +1 -1
- package/cjs/components/Combobox/ComboboxTarget/ComboboxTarget.cjs +1 -0
- package/cjs/components/Combobox/ComboboxTarget/ComboboxTarget.cjs.map +1 -1
- package/cjs/components/Combobox/use-combobox-target-props/use-combobox-target-props.cjs +18 -12
- package/cjs/components/Combobox/use-combobox-target-props/use-combobox-target-props.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/Highlight/highlighter/highlighter.cjs +3 -3
- package/cjs/components/Highlight/highlighter/highlighter.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/MultiSelect/MultiSelect.cjs.map +1 -1
- package/cjs/components/PasswordInput/PasswordInput.cjs +1 -1
- package/cjs/components/PasswordInput/PasswordInput.cjs.map +1 -1
- package/cjs/components/Popover/Popover.context.cjs.map +1 -1
- package/cjs/components/Popover/PopoverDropdown/PopoverDropdown.cjs +1 -1
- package/cjs/components/Popover/PopoverDropdown/PopoverDropdown.cjs.map +1 -1
- package/cjs/components/Radio/Radio.module.cjs.map +1 -1
- package/cjs/components/Rating/Rating.cjs +1 -2
- package/cjs/components/Rating/Rating.cjs.map +1 -1
- package/cjs/components/ScrollArea/ScrollArea.cjs +24 -10
- package/cjs/components/ScrollArea/ScrollArea.cjs.map +1 -1
- package/cjs/components/Select/Select.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/Tree/FlatTreeNode.cjs +103 -0
- package/cjs/components/Tree/FlatTreeNode.cjs.map +1 -0
- package/cjs/components/Tree/Tree.cjs +12 -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 +70 -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 +127 -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/styles-api/use-resolved-styles-api/use-resolved-styles-api.cjs +2 -2
- package/cjs/core/styles-api/use-resolved-styles-api/use-resolved-styles-api.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/Card/Card.mjs +1 -1
- package/esm/components/Card/Card.mjs.map +1 -1
- package/esm/components/Combobox/ComboboxClearButton/ComboboxClearButton.mjs +1 -1
- package/esm/components/Combobox/ComboboxClearButton/ComboboxClearButton.mjs.map +1 -1
- package/esm/components/Combobox/ComboboxEventsTarget/ComboboxEventsTarget.mjs +1 -0
- package/esm/components/Combobox/ComboboxEventsTarget/ComboboxEventsTarget.mjs.map +1 -1
- package/esm/components/Combobox/ComboboxSearch/ComboboxSearch.mjs +2 -1
- package/esm/components/Combobox/ComboboxSearch/ComboboxSearch.mjs.map +1 -1
- package/esm/components/Combobox/ComboboxTarget/ComboboxTarget.mjs +1 -0
- package/esm/components/Combobox/ComboboxTarget/ComboboxTarget.mjs.map +1 -1
- package/esm/components/Combobox/use-combobox-target-props/use-combobox-target-props.mjs +18 -12
- package/esm/components/Combobox/use-combobox-target-props/use-combobox-target-props.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/Highlight/highlighter/highlighter.mjs +3 -3
- package/esm/components/Highlight/highlighter/highlighter.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/MultiSelect/MultiSelect.mjs.map +1 -1
- package/esm/components/PasswordInput/PasswordInput.mjs +1 -1
- package/esm/components/PasswordInput/PasswordInput.mjs.map +1 -1
- package/esm/components/Popover/Popover.context.mjs.map +1 -1
- package/esm/components/Popover/PopoverDropdown/PopoverDropdown.mjs +1 -1
- package/esm/components/Popover/PopoverDropdown/PopoverDropdown.mjs.map +1 -1
- package/esm/components/Radio/Radio.module.mjs.map +1 -1
- package/esm/components/Rating/Rating.mjs +1 -2
- package/esm/components/Rating/Rating.mjs.map +1 -1
- package/esm/components/ScrollArea/ScrollArea.mjs +25 -11
- package/esm/components/ScrollArea/ScrollArea.mjs.map +1 -1
- package/esm/components/Select/Select.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/Tree/FlatTreeNode.mjs +102 -0
- package/esm/components/Tree/FlatTreeNode.mjs.map +1 -0
- package/esm/components/Tree/Tree.mjs +13 -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 +70 -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 +126 -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/styles-api/use-resolved-styles-api/use-resolved-styles-api.mjs +2 -2
- package/esm/core/styles-api/use-resolved-styles-api/use-resolved-styles-api.mjs.map +1 -1
- package/esm/index.mjs +9 -2
- package/lib/components/Combobox/ComboboxClearButton/ComboboxClearButton.d.ts +1 -1
- package/lib/components/Combobox/use-combobox-target-props/use-combobox-target-props.d.ts +3 -1
- 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/MultiSelect/MultiSelect.d.ts +1 -1
- package/lib/components/Popover/Popover.context.d.ts +1 -1
- package/lib/components/Select/Select.d.ts +1 -1
- 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 +31 -1
- package/lib/components/Tree/TreeNode.d.ts +9 -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 +10 -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 +30 -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/lib/core/styles-api/use-resolved-styles-api/use-resolved-styles-api.d.ts +2 -2
- package/package.json +5 -5
- package/styles/Radio.css +3 -2
- package/styles/Radio.layer.css +3 -2
- package/styles/Tree.css +66 -0
- package/styles/Tree.layer.css +66 -0
- package/styles.css +69 -2
- package/styles.layer.css +69 -2
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { findElementAncestor } from "../../core/utils/find-element-ancestor/find-element-ancestor.mjs";
|
|
3
3
|
import { Box } from "../../core/Box/Box.mjs";
|
|
4
|
+
import { Loader } from "../Loader/Loader.mjs";
|
|
5
|
+
import { useTreeNodeDragDrop } from "./use-tree-node-drag-drop.mjs";
|
|
4
6
|
import { Activity, useRef } from "react";
|
|
5
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
8
|
//#region packages/@mantine/core/src/components/Tree/TreeNode.tsx
|
|
@@ -12,8 +14,14 @@ function getValuesRange(anchor, value, flatValues) {
|
|
|
12
14
|
const end = Math.max(anchorIndex, valueIndex);
|
|
13
15
|
return flatValues.slice(start, end + 1);
|
|
14
16
|
}
|
|
15
|
-
function TreeNode({ node, getStyles, rootIndex, controller, expandOnClick, selectOnClick, isSubtree, level = 1, renderNode, flatValues, allowRangeSelection, expandOnSpace, checkOnSpace, keepMounted }) {
|
|
17
|
+
function TreeNode({ node, getStyles, rootIndex, controller, expandOnClick, selectOnClick, isSubtree, level = 1, renderNode, flatValues, allowRangeSelection, expandOnSpace, checkOnSpace, keepMounted, onDragDrop, allowDrop, withDragHandle, dragStateRef, data }) {
|
|
16
18
|
const ref = useRef(null);
|
|
19
|
+
const hasLoadedChildren = Array.isArray(node.children);
|
|
20
|
+
const hasAsyncChildren = !!node.hasChildren && !hasLoadedChildren;
|
|
21
|
+
const hasChildren = hasLoadedChildren || hasAsyncChildren;
|
|
22
|
+
const isLoading = controller.isNodeLoading(node.value);
|
|
23
|
+
const loadError = controller.getNodeLoadError(node.value);
|
|
24
|
+
const isExpanded = controller.expandedState[node.value] || false;
|
|
17
25
|
const nested = (node.children || []).map((child) => /* @__PURE__ */ jsx(TreeNode, {
|
|
18
26
|
node: child,
|
|
19
27
|
flatValues,
|
|
@@ -28,19 +36,33 @@ function TreeNode({ node, getStyles, rootIndex, controller, expandOnClick, selec
|
|
|
28
36
|
allowRangeSelection,
|
|
29
37
|
expandOnSpace,
|
|
30
38
|
checkOnSpace,
|
|
31
|
-
keepMounted
|
|
39
|
+
keepMounted,
|
|
40
|
+
onDragDrop,
|
|
41
|
+
allowDrop,
|
|
42
|
+
withDragHandle,
|
|
43
|
+
dragStateRef,
|
|
44
|
+
data
|
|
32
45
|
}, child.value));
|
|
46
|
+
const { elementProps: dragElementProps, dragHandleProps } = useTreeNodeDragDrop({
|
|
47
|
+
nodeValue: node.value,
|
|
48
|
+
hasChildren,
|
|
49
|
+
data,
|
|
50
|
+
onDragDrop,
|
|
51
|
+
dragStateRef,
|
|
52
|
+
allowDrop,
|
|
53
|
+
withDragHandle
|
|
54
|
+
});
|
|
33
55
|
const handleKeyDown = (event) => {
|
|
34
56
|
if (event.nativeEvent.code === "ArrowRight") {
|
|
35
57
|
event.stopPropagation();
|
|
36
58
|
event.preventDefault();
|
|
37
|
-
if (
|
|
59
|
+
if (isExpanded) event.currentTarget.querySelector("[role=treeitem]")?.focus();
|
|
38
60
|
else controller.expand(node.value);
|
|
39
61
|
}
|
|
40
62
|
if (event.nativeEvent.code === "ArrowLeft") {
|
|
41
63
|
event.stopPropagation();
|
|
42
64
|
event.preventDefault();
|
|
43
|
-
if (
|
|
65
|
+
if (isExpanded && hasChildren) controller.collapse(node.value);
|
|
44
66
|
else if (isSubtree) findElementAncestor(event.currentTarget, "[role=treeitem]")?.focus();
|
|
45
67
|
}
|
|
46
68
|
if (event.nativeEvent.code === "ArrowDown" || event.nativeEvent.code === "ArrowUp") {
|
|
@@ -77,7 +99,7 @@ function TreeNode({ node, getStyles, rootIndex, controller, expandOnClick, selec
|
|
|
77
99
|
controller.setSelectedState(getValuesRange(controller.anchorNode, node.value, flatValues));
|
|
78
100
|
ref.current?.focus();
|
|
79
101
|
} else {
|
|
80
|
-
expandOnClick
|
|
102
|
+
if (expandOnClick) controller.toggleExpanded(node.value);
|
|
81
103
|
selectOnClick && controller.select(node.value);
|
|
82
104
|
ref.current?.focus();
|
|
83
105
|
}
|
|
@@ -87,8 +109,10 @@ function TreeNode({ node, getStyles, rootIndex, controller, expandOnClick, selec
|
|
|
87
109
|
...getStyles("label"),
|
|
88
110
|
onClick: handleNodeClick,
|
|
89
111
|
"data-selected": selected || void 0,
|
|
90
|
-
"data-value": node.value
|
|
112
|
+
"data-value": node.value,
|
|
113
|
+
...dragElementProps
|
|
91
114
|
};
|
|
115
|
+
const withLoadingIndicator = isExpanded && isLoading && nested.length === 0;
|
|
92
116
|
return /* @__PURE__ */ jsxs("li", {
|
|
93
117
|
...getStyles("node", { style: { "--label-offset": `calc(var(--level-offset) * ${level - 1})` } }),
|
|
94
118
|
role: "treeitem",
|
|
@@ -99,33 +123,52 @@ function TreeNode({ node, getStyles, rootIndex, controller, expandOnClick, selec
|
|
|
99
123
|
tabIndex: rootIndex === 0 ? 0 : -1,
|
|
100
124
|
onKeyDown: handleKeyDown,
|
|
101
125
|
ref,
|
|
102
|
-
children: [
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
126
|
+
children: [
|
|
127
|
+
typeof renderNode === "function" ? renderNode({
|
|
128
|
+
node,
|
|
129
|
+
level,
|
|
130
|
+
selected,
|
|
131
|
+
tree: controller,
|
|
132
|
+
expanded: isExpanded,
|
|
133
|
+
hasChildren,
|
|
134
|
+
isLoading,
|
|
135
|
+
loadError,
|
|
136
|
+
elementProps,
|
|
137
|
+
dragHandleProps
|
|
138
|
+
}) : /* @__PURE__ */ jsx("div", {
|
|
139
|
+
...elementProps,
|
|
140
|
+
children: node.label
|
|
141
|
+
}),
|
|
142
|
+
withLoadingIndicator && /* @__PURE__ */ jsx(Box, {
|
|
143
|
+
component: "ul",
|
|
144
|
+
role: "group",
|
|
145
|
+
...getStyles("subtree"),
|
|
146
|
+
"data-level": level,
|
|
147
|
+
children: /* @__PURE__ */ jsx("li", {
|
|
148
|
+
...getStyles("node", { style: { "--label-offset": `calc(var(--level-offset) * ${level})` } }),
|
|
149
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
150
|
+
...getStyles("label"),
|
|
151
|
+
children: /* @__PURE__ */ jsx(Loader, { size: 16 })
|
|
152
|
+
})
|
|
153
|
+
})
|
|
154
|
+
}),
|
|
155
|
+
keepMounted && nested.length > 0 ? /* @__PURE__ */ jsx(Activity, {
|
|
156
|
+
mode: isExpanded ? "visible" : "hidden",
|
|
157
|
+
children: /* @__PURE__ */ jsx(Box, {
|
|
158
|
+
component: "ul",
|
|
159
|
+
role: "group",
|
|
160
|
+
...getStyles("subtree"),
|
|
161
|
+
"data-level": level,
|
|
162
|
+
children: nested
|
|
163
|
+
})
|
|
164
|
+
}) : isExpanded && nested.length > 0 && /* @__PURE__ */ jsx(Box, {
|
|
116
165
|
component: "ul",
|
|
117
166
|
role: "group",
|
|
118
167
|
...getStyles("subtree"),
|
|
119
168
|
"data-level": level,
|
|
120
169
|
children: nested
|
|
121
170
|
})
|
|
122
|
-
|
|
123
|
-
component: "ul",
|
|
124
|
-
role: "group",
|
|
125
|
-
...getStyles("subtree"),
|
|
126
|
-
"data-level": level,
|
|
127
|
-
children: nested
|
|
128
|
-
})]
|
|
171
|
+
]
|
|
129
172
|
});
|
|
130
173
|
}
|
|
131
174
|
TreeNode.displayName = "@mantine/core/TreeNode";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TreeNode.mjs","names":[],"sources":["../../../src/components/Tree/TreeNode.tsx"],"sourcesContent":["import { Activity, useRef } from 'react';\nimport { Box, findElementAncestor, GetStylesApi } from '../../core';\nimport type { RenderNode, TreeFactory, TreeNodeData } from './Tree';\nimport type { TreeController } from './use-tree';\n\nfunction getValuesRange(anchor: string | null, value: string | undefined, flatValues: string[]) {\n if (!anchor || !value) {\n return [];\n }\n\n const anchorIndex = flatValues.indexOf(anchor);\n const valueIndex = flatValues.indexOf(value);\n const start = Math.min(anchorIndex, valueIndex);\n const end = Math.max(anchorIndex, valueIndex);\n\n return flatValues.slice(start, end + 1);\n}\n\ninterface TreeNodeProps {\n node: TreeNodeData;\n getStyles: GetStylesApi<TreeFactory>;\n rootIndex: number | undefined;\n controller: TreeController;\n expandOnClick: boolean | undefined;\n flatValues: string[];\n isSubtree?: boolean;\n level?: number;\n renderNode: RenderNode | undefined;\n selectOnClick: boolean | undefined;\n allowRangeSelection: boolean | undefined;\n expandOnSpace: boolean | undefined;\n checkOnSpace: boolean | undefined;\n keepMounted: boolean | undefined;\n}\n\nexport function TreeNode({\n node,\n getStyles,\n rootIndex,\n controller,\n expandOnClick,\n selectOnClick,\n isSubtree,\n level = 1,\n renderNode,\n flatValues,\n allowRangeSelection,\n expandOnSpace,\n checkOnSpace,\n keepMounted,\n}: TreeNodeProps) {\n const ref = useRef<HTMLLIElement>(null);\n const nested = (node.children || []).map((child) => (\n <TreeNode\n key={child.value}\n node={child}\n flatValues={flatValues}\n getStyles={getStyles}\n rootIndex={undefined}\n level={level + 1}\n controller={controller}\n expandOnClick={expandOnClick}\n isSubtree\n renderNode={renderNode}\n selectOnClick={selectOnClick}\n allowRangeSelection={allowRangeSelection}\n expandOnSpace={expandOnSpace}\n checkOnSpace={checkOnSpace}\n keepMounted={keepMounted}\n />\n ));\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (event.nativeEvent.code === 'ArrowRight') {\n event.stopPropagation();\n event.preventDefault();\n\n if (controller.expandedState[node.value]) {\n event.currentTarget.querySelector<HTMLLIElement>('[role=treeitem]')?.focus();\n } else {\n controller.expand(node.value);\n }\n }\n\n if (event.nativeEvent.code === 'ArrowLeft') {\n event.stopPropagation();\n event.preventDefault();\n if (controller.expandedState[node.value] && (node.children || []).length > 0) {\n controller.collapse(node.value);\n } else if (isSubtree) {\n findElementAncestor(event.currentTarget as HTMLElement, '[role=treeitem]')?.focus();\n }\n }\n\n if (event.nativeEvent.code === 'ArrowDown' || event.nativeEvent.code === 'ArrowUp') {\n const root = findElementAncestor(event.currentTarget as HTMLElement, '[data-tree-root]');\n\n if (!root) {\n return;\n }\n\n event.stopPropagation();\n event.preventDefault();\n const nodes = Array.from(root.querySelectorAll<HTMLLIElement>('[role=treeitem]')).filter(\n (treeNode) => treeNode.style.display !== 'none'\n );\n const index = nodes.indexOf(event.currentTarget as HTMLLIElement);\n\n if (index === -1) {\n return;\n }\n\n const nextIndex = event.nativeEvent.code === 'ArrowDown' ? index + 1 : index - 1;\n nodes[nextIndex]?.focus();\n\n if (event.shiftKey) {\n const selectNode = nodes[nextIndex];\n\n if (selectNode) {\n controller.setSelectedState(\n getValuesRange(controller.anchorNode, selectNode.dataset.value, flatValues)\n );\n }\n }\n }\n\n if (event.nativeEvent.code === 'Space') {\n if (expandOnSpace) {\n event.stopPropagation();\n event.preventDefault();\n controller.toggleExpanded(node.value);\n }\n\n if (checkOnSpace) {\n event.stopPropagation();\n event.preventDefault();\n controller.isNodeChecked(node.value)\n ? controller.uncheckNode(node.value)\n : controller.checkNode(node.value);\n }\n }\n };\n\n const handleNodeClick = (event: React.MouseEvent) => {\n event.stopPropagation();\n\n if (allowRangeSelection && event.shiftKey && controller.anchorNode) {\n controller.setSelectedState(getValuesRange(controller.anchorNode, node.value, flatValues));\n ref.current?.focus();\n } else {\n expandOnClick && controller.toggleExpanded(node.value);\n selectOnClick && controller.select(node.value);\n ref.current?.focus();\n }\n };\n\n const selected = controller.selectedState.includes(node.value);\n const elementProps = {\n ...getStyles('label'),\n onClick: handleNodeClick,\n 'data-selected': selected || undefined,\n 'data-value': node.value,\n };\n\n return (\n <li\n {...getStyles('node', {\n style: { '--label-offset': `calc(var(--level-offset) * ${level - 1})` },\n })}\n role=\"treeitem\"\n aria-selected={selected}\n data-value={node.value}\n data-selected={selected || undefined}\n data-level={level}\n tabIndex={rootIndex === 0 ? 0 : -1}\n onKeyDown={handleKeyDown}\n ref={ref}\n >\n {typeof renderNode === 'function' ? (\n renderNode({\n node,\n level,\n selected,\n tree: controller,\n expanded: controller.expandedState[node.value] || false,\n hasChildren: Array.isArray(node.children) && node.children.length > 0,\n elementProps,\n })\n ) : (\n <div {...elementProps}>{node.label}</div>\n )}\n\n {keepMounted && nested.length > 0 ? (\n <Activity mode={controller.expandedState[node.value] ? 'visible' : 'hidden'}>\n <Box component=\"ul\" role=\"group\" {...getStyles('subtree')} data-level={level}>\n {nested}\n </Box>\n </Activity>\n ) : (\n controller.expandedState[node.value] &&\n nested.length > 0 && (\n <Box component=\"ul\" role=\"group\" {...getStyles('subtree')} data-level={level}>\n {nested}\n </Box>\n )\n )}\n </li>\n );\n}\n\nTreeNode.displayName = '@mantine/core/TreeNode';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TreeNode.mjs","names":[],"sources":["../../../src/components/Tree/TreeNode.tsx"],"sourcesContent":["import { Activity, useRef } from 'react';\nimport { Box, findElementAncestor, GetStylesApi } from '../../core';\nimport { Loader } from '../Loader';\nimport type { TreeDragDropPayload } from './move-tree-node/move-tree-node';\nimport type { RenderNode, TreeDragState, TreeFactory, TreeNodeData } from './Tree';\nimport type { TreeController } from './use-tree';\nimport { TreeAllowDrop, useTreeNodeDragDrop } from './use-tree-node-drag-drop';\n\nfunction getValuesRange(anchor: string | null, value: string | undefined, flatValues: string[]) {\n if (!anchor || !value) {\n return [];\n }\n\n const anchorIndex = flatValues.indexOf(anchor);\n const valueIndex = flatValues.indexOf(value);\n const start = Math.min(anchorIndex, valueIndex);\n const end = Math.max(anchorIndex, valueIndex);\n\n return flatValues.slice(start, end + 1);\n}\n\ninterface TreeNodeProps {\n node: TreeNodeData;\n getStyles: GetStylesApi<TreeFactory>;\n rootIndex: number | undefined;\n controller: TreeController;\n expandOnClick: boolean | undefined;\n flatValues: string[];\n isSubtree?: boolean;\n level?: number;\n renderNode: RenderNode | undefined;\n selectOnClick: boolean | undefined;\n allowRangeSelection: boolean | undefined;\n expandOnSpace: boolean | undefined;\n checkOnSpace: boolean | undefined;\n keepMounted: boolean | undefined;\n onDragDrop: ((payload: TreeDragDropPayload) => void) | undefined;\n allowDrop: TreeAllowDrop | undefined;\n withDragHandle: boolean | undefined;\n dragStateRef: React.RefObject<TreeDragState>;\n data: TreeNodeData[];\n}\n\nexport function TreeNode({\n node,\n getStyles,\n rootIndex,\n controller,\n expandOnClick,\n selectOnClick,\n isSubtree,\n level = 1,\n renderNode,\n flatValues,\n allowRangeSelection,\n expandOnSpace,\n checkOnSpace,\n keepMounted,\n onDragDrop,\n allowDrop,\n withDragHandle,\n dragStateRef,\n data,\n}: TreeNodeProps) {\n const ref = useRef<HTMLLIElement>(null);\n const hasLoadedChildren = Array.isArray(node.children);\n const hasAsyncChildren = !!node.hasChildren && !hasLoadedChildren;\n const hasChildren = hasLoadedChildren || hasAsyncChildren;\n const isLoading = controller.isNodeLoading(node.value);\n const loadError = controller.getNodeLoadError(node.value);\n const isExpanded = controller.expandedState[node.value] || false;\n\n const nested = (node.children || []).map((child) => (\n <TreeNode\n key={child.value}\n node={child}\n flatValues={flatValues}\n getStyles={getStyles}\n rootIndex={undefined}\n level={level + 1}\n controller={controller}\n expandOnClick={expandOnClick}\n isSubtree\n renderNode={renderNode}\n selectOnClick={selectOnClick}\n allowRangeSelection={allowRangeSelection}\n expandOnSpace={expandOnSpace}\n checkOnSpace={checkOnSpace}\n keepMounted={keepMounted}\n onDragDrop={onDragDrop}\n allowDrop={allowDrop}\n withDragHandle={withDragHandle}\n dragStateRef={dragStateRef}\n data={data}\n />\n ));\n\n const { elementProps: dragElementProps, dragHandleProps } = useTreeNodeDragDrop({\n nodeValue: node.value,\n hasChildren,\n data,\n onDragDrop,\n dragStateRef,\n allowDrop,\n withDragHandle,\n });\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (event.nativeEvent.code === 'ArrowRight') {\n event.stopPropagation();\n event.preventDefault();\n\n if (isExpanded) {\n event.currentTarget.querySelector<HTMLLIElement>('[role=treeitem]')?.focus();\n } else {\n controller.expand(node.value);\n }\n }\n\n if (event.nativeEvent.code === 'ArrowLeft') {\n event.stopPropagation();\n event.preventDefault();\n if (isExpanded && hasChildren) {\n controller.collapse(node.value);\n } else if (isSubtree) {\n findElementAncestor(event.currentTarget as HTMLElement, '[role=treeitem]')?.focus();\n }\n }\n\n if (event.nativeEvent.code === 'ArrowDown' || event.nativeEvent.code === 'ArrowUp') {\n const root = findElementAncestor(event.currentTarget as HTMLElement, '[data-tree-root]');\n\n if (!root) {\n return;\n }\n\n event.stopPropagation();\n event.preventDefault();\n const nodes = Array.from(root.querySelectorAll<HTMLLIElement>('[role=treeitem]')).filter(\n (treeNode) => treeNode.style.display !== 'none'\n );\n const index = nodes.indexOf(event.currentTarget as HTMLLIElement);\n\n if (index === -1) {\n return;\n }\n\n const nextIndex = event.nativeEvent.code === 'ArrowDown' ? index + 1 : index - 1;\n nodes[nextIndex]?.focus();\n\n if (event.shiftKey) {\n const selectNode = nodes[nextIndex];\n\n if (selectNode) {\n controller.setSelectedState(\n getValuesRange(controller.anchorNode, selectNode.dataset.value, flatValues)\n );\n }\n }\n }\n\n if (event.nativeEvent.code === 'Space') {\n if (expandOnSpace) {\n event.stopPropagation();\n event.preventDefault();\n controller.toggleExpanded(node.value);\n }\n\n if (checkOnSpace) {\n event.stopPropagation();\n event.preventDefault();\n controller.isNodeChecked(node.value)\n ? controller.uncheckNode(node.value)\n : controller.checkNode(node.value);\n }\n }\n };\n\n const handleNodeClick = (event: React.MouseEvent) => {\n event.stopPropagation();\n\n if (allowRangeSelection && event.shiftKey && controller.anchorNode) {\n controller.setSelectedState(getValuesRange(controller.anchorNode, node.value, flatValues));\n ref.current?.focus();\n } else {\n if (expandOnClick) {\n controller.toggleExpanded(node.value);\n }\n\n selectOnClick && controller.select(node.value);\n ref.current?.focus();\n }\n };\n\n const selected = controller.selectedState.includes(node.value);\n const elementProps = {\n ...getStyles('label'),\n onClick: handleNodeClick,\n 'data-selected': selected || undefined,\n 'data-value': node.value,\n ...dragElementProps,\n };\n\n const withLoadingIndicator = isExpanded && isLoading && nested.length === 0;\n\n return (\n <li\n {...getStyles('node', {\n style: { '--label-offset': `calc(var(--level-offset) * ${level - 1})` },\n })}\n role=\"treeitem\"\n aria-selected={selected}\n data-value={node.value}\n data-selected={selected || undefined}\n data-level={level}\n tabIndex={rootIndex === 0 ? 0 : -1}\n onKeyDown={handleKeyDown}\n ref={ref}\n >\n {typeof renderNode === 'function' ? (\n renderNode({\n node,\n level,\n selected,\n tree: controller,\n expanded: isExpanded,\n hasChildren,\n isLoading,\n loadError,\n elementProps,\n dragHandleProps,\n })\n ) : (\n <div {...elementProps}>{node.label}</div>\n )}\n\n {withLoadingIndicator && (\n <Box component=\"ul\" role=\"group\" {...getStyles('subtree')} data-level={level}>\n <li\n {...getStyles('node', {\n style: { '--label-offset': `calc(var(--level-offset) * ${level})` },\n })}\n >\n <div {...getStyles('label')}>\n <Loader size={16} />\n </div>\n </li>\n </Box>\n )}\n\n {keepMounted && nested.length > 0 ? (\n <Activity mode={isExpanded ? 'visible' : 'hidden'}>\n <Box component=\"ul\" role=\"group\" {...getStyles('subtree')} data-level={level}>\n {nested}\n </Box>\n </Activity>\n ) : (\n isExpanded &&\n nested.length > 0 && (\n <Box component=\"ul\" role=\"group\" {...getStyles('subtree')} data-level={level}>\n {nested}\n </Box>\n )\n )}\n </li>\n );\n}\n\nTreeNode.displayName = '@mantine/core/TreeNode';\n"],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
//#region packages/@mantine/core/src/components/Tree/filter-tree-data/filter-tree-data.ts
|
|
3
|
+
function defaultTreeNodeFilter(query, node) {
|
|
4
|
+
return (typeof node.label === "string" ? node.label : node.value).toLowerCase().includes(query.toLowerCase().trim());
|
|
5
|
+
}
|
|
6
|
+
function filterTreeData(data, query, filter = defaultTreeNodeFilter) {
|
|
7
|
+
if (!query.trim()) return data;
|
|
8
|
+
const result = [];
|
|
9
|
+
for (const node of data) {
|
|
10
|
+
const nodeMatches = filter(query, node);
|
|
11
|
+
const filteredChildren = Array.isArray(node.children) && node.children.length > 0 ? filterTreeData(node.children, query, filter) : [];
|
|
12
|
+
if (nodeMatches || filteredChildren.length > 0) result.push(filteredChildren.length > 0 ? {
|
|
13
|
+
...node,
|
|
14
|
+
children: filteredChildren
|
|
15
|
+
} : { ...node });
|
|
16
|
+
}
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
export { defaultTreeNodeFilter, filterTreeData };
|
|
21
|
+
|
|
22
|
+
//# sourceMappingURL=filter-tree-data.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter-tree-data.mjs","names":[],"sources":["../../../../src/components/Tree/filter-tree-data/filter-tree-data.ts"],"sourcesContent":["import type { TreeNodeData } from '../Tree';\n\nexport type TreeNodeFilter = (query: string, node: TreeNodeData) => boolean;\n\nexport function defaultTreeNodeFilter(query: string, node: TreeNodeData): boolean {\n const label = typeof node.label === 'string' ? node.label : node.value;\n return label.toLowerCase().includes(query.toLowerCase().trim());\n}\n\nexport function filterTreeData(\n data: TreeNodeData[],\n query: string,\n filter: TreeNodeFilter = defaultTreeNodeFilter\n): TreeNodeData[] {\n if (!query.trim()) {\n return data;\n }\n\n const result: TreeNodeData[] = [];\n\n for (const node of data) {\n const nodeMatches = filter(query, node);\n const filteredChildren =\n Array.isArray(node.children) && node.children.length > 0\n ? filterTreeData(node.children, query, filter)\n : [];\n\n if (nodeMatches || filteredChildren.length > 0) {\n result.push(\n filteredChildren.length > 0 ? { ...node, children: filteredChildren } : { ...node }\n );\n }\n }\n\n return result;\n}\n"],"mappings":";;AAIA,SAAgB,sBAAsB,OAAe,MAA6B;AAEhF,SADc,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ,KAAK,OACpD,aAAa,CAAC,SAAS,MAAM,aAAa,CAAC,MAAM,CAAC;;AAGjE,SAAgB,eACd,MACA,OACA,SAAyB,uBACT;AAChB,KAAI,CAAC,MAAM,MAAM,CACf,QAAO;CAGT,MAAM,SAAyB,EAAE;AAEjC,MAAK,MAAM,QAAQ,MAAM;EACvB,MAAM,cAAc,OAAO,OAAO,KAAK;EACvC,MAAM,mBACJ,MAAM,QAAQ,KAAK,SAAS,IAAI,KAAK,SAAS,SAAS,IACnD,eAAe,KAAK,UAAU,OAAO,OAAO,GAC5C,EAAE;AAER,MAAI,eAAe,iBAAiB,SAAS,EAC3C,QAAO,KACL,iBAAiB,SAAS,IAAI;GAAE,GAAG;GAAM,UAAU;GAAkB,GAAG,EAAE,GAAG,MAAM,CACpF;;AAIL,QAAO"}
|
|
@@ -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
|
+
export { flattenTreeData };
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=flatten-tree-data.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flatten-tree-data.mjs","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
|
+
export { mergeAsyncChildren };
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=merge-async-children.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge-async-children.mjs","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
|
+
import { findTreeNode } from "../get-children-nodes-values/get-children-nodes-values.mjs";
|
|
3
|
+
//#region packages/@mantine/core/src/components/Tree/move-tree-node/move-tree-node.ts
|
|
4
|
+
function isDescendant(data, ancestorValue, value) {
|
|
5
|
+
const ancestor = 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 (!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
|
+
export { moveTreeNode };
|
|
77
|
+
|
|
78
|
+
//# sourceMappingURL=move-tree-node.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"move-tree-node.mjs","names":[],"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,WAAW,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,CAAC,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,126 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { findTreeNode } from "./get-children-nodes-values/get-children-nodes-values.mjs";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
//#region packages/@mantine/core/src/components/Tree/use-tree-node-drag-drop.ts
|
|
5
|
+
function isDescendantOf(data, ancestorValue, descendantValue) {
|
|
6
|
+
const ancestor = findTreeNode(ancestorValue, data);
|
|
7
|
+
if (!ancestor || !ancestor.children) return false;
|
|
8
|
+
function check(nodes) {
|
|
9
|
+
for (const node of nodes) {
|
|
10
|
+
if (node.value === descendantValue) return true;
|
|
11
|
+
if (node.children && check(node.children)) return true;
|
|
12
|
+
}
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
return check(ancestor.children);
|
|
16
|
+
}
|
|
17
|
+
function getDragDropPosition(event, element, hasChildren) {
|
|
18
|
+
const rect = element.getBoundingClientRect();
|
|
19
|
+
const y = event.clientY - rect.top;
|
|
20
|
+
const height = rect.height;
|
|
21
|
+
if (hasChildren) {
|
|
22
|
+
if (y < height * .25) return "before";
|
|
23
|
+
if (y > height * .75) return "after";
|
|
24
|
+
return "inside";
|
|
25
|
+
}
|
|
26
|
+
if (y < height * .5) return "before";
|
|
27
|
+
return "after";
|
|
28
|
+
}
|
|
29
|
+
const EMPTY_DRAG_PROPS = {
|
|
30
|
+
elementProps: {},
|
|
31
|
+
dragHandleProps: void 0
|
|
32
|
+
};
|
|
33
|
+
function useTreeNodeDragDrop({ nodeValue, hasChildren, data, onDragDrop, dragStateRef, allowDrop, withDragHandle }) {
|
|
34
|
+
const [isDragHandleActive, setIsDragHandleActive] = useState(false);
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
if (!withDragHandle || !isDragHandleActive) return;
|
|
37
|
+
const handleWindowMouseUp = () => setIsDragHandleActive(false);
|
|
38
|
+
window.addEventListener("mouseup", handleWindowMouseUp);
|
|
39
|
+
return () => window.removeEventListener("mouseup", handleWindowMouseUp);
|
|
40
|
+
}, [withDragHandle, isDragHandleActive]);
|
|
41
|
+
if (!onDragDrop) return EMPTY_DRAG_PROPS;
|
|
42
|
+
const handleDragStart = (event) => {
|
|
43
|
+
if (withDragHandle && !isDragHandleActive) return;
|
|
44
|
+
event.stopPropagation();
|
|
45
|
+
event.dataTransfer.effectAllowed = "move";
|
|
46
|
+
event.dataTransfer.setData("text/plain", nodeValue);
|
|
47
|
+
dragStateRef.current.draggedValue = nodeValue;
|
|
48
|
+
const target = event.currentTarget;
|
|
49
|
+
requestAnimationFrame(() => {
|
|
50
|
+
target.setAttribute("data-dragging", "true");
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
const handleDragOver = (event) => {
|
|
54
|
+
const draggedValue = dragStateRef.current.draggedValue;
|
|
55
|
+
if (!draggedValue || draggedValue === nodeValue) return;
|
|
56
|
+
if (isDescendantOf(data, draggedValue, nodeValue)) return;
|
|
57
|
+
const target = event.currentTarget;
|
|
58
|
+
const position = getDragDropPosition(event, target, hasChildren);
|
|
59
|
+
if (allowDrop && !allowDrop({
|
|
60
|
+
draggedNode: draggedValue,
|
|
61
|
+
targetNode: nodeValue,
|
|
62
|
+
position
|
|
63
|
+
})) {
|
|
64
|
+
const prevTarget = dragStateRef.current.currentDropTarget;
|
|
65
|
+
if (prevTarget && prevTarget !== target) prevTarget.removeAttribute("data-drag-over");
|
|
66
|
+
target.removeAttribute("data-drag-over");
|
|
67
|
+
dragStateRef.current.currentDropTarget = null;
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
event.preventDefault();
|
|
71
|
+
event.stopPropagation();
|
|
72
|
+
event.dataTransfer.dropEffect = "move";
|
|
73
|
+
const prevTarget = dragStateRef.current.currentDropTarget;
|
|
74
|
+
if (prevTarget && prevTarget !== target) prevTarget.removeAttribute("data-drag-over");
|
|
75
|
+
target.setAttribute("data-drag-over", position);
|
|
76
|
+
dragStateRef.current.currentDropTarget = target;
|
|
77
|
+
};
|
|
78
|
+
const handleDragLeave = (event) => {
|
|
79
|
+
const target = event.currentTarget;
|
|
80
|
+
const related = event.relatedTarget;
|
|
81
|
+
if (related && target.contains(related)) return;
|
|
82
|
+
target.removeAttribute("data-drag-over");
|
|
83
|
+
if (dragStateRef.current.currentDropTarget === target) dragStateRef.current.currentDropTarget = null;
|
|
84
|
+
};
|
|
85
|
+
const handleDrop = (event) => {
|
|
86
|
+
event.preventDefault();
|
|
87
|
+
event.stopPropagation();
|
|
88
|
+
const target = event.currentTarget;
|
|
89
|
+
const position = target.getAttribute("data-drag-over");
|
|
90
|
+
target.removeAttribute("data-drag-over");
|
|
91
|
+
const draggedValue = dragStateRef.current.draggedValue;
|
|
92
|
+
if (draggedValue && position && draggedValue !== nodeValue) {
|
|
93
|
+
const payload = {
|
|
94
|
+
draggedNode: draggedValue,
|
|
95
|
+
targetNode: nodeValue,
|
|
96
|
+
position
|
|
97
|
+
};
|
|
98
|
+
if (!allowDrop || allowDrop(payload)) onDragDrop(payload);
|
|
99
|
+
}
|
|
100
|
+
dragStateRef.current.draggedValue = null;
|
|
101
|
+
dragStateRef.current.currentDropTarget = null;
|
|
102
|
+
};
|
|
103
|
+
const handleDragEnd = (event) => {
|
|
104
|
+
event.currentTarget.removeAttribute("data-dragging");
|
|
105
|
+
const prevTarget = dragStateRef.current.currentDropTarget;
|
|
106
|
+
if (prevTarget) prevTarget.removeAttribute("data-drag-over");
|
|
107
|
+
dragStateRef.current.draggedValue = null;
|
|
108
|
+
dragStateRef.current.currentDropTarget = null;
|
|
109
|
+
if (withDragHandle) setIsDragHandleActive(false);
|
|
110
|
+
};
|
|
111
|
+
return {
|
|
112
|
+
elementProps: {
|
|
113
|
+
draggable: withDragHandle ? isDragHandleActive : true,
|
|
114
|
+
onDragStart: handleDragStart,
|
|
115
|
+
onDragOver: handleDragOver,
|
|
116
|
+
onDragLeave: handleDragLeave,
|
|
117
|
+
onDrop: handleDrop,
|
|
118
|
+
onDragEnd: handleDragEnd
|
|
119
|
+
},
|
|
120
|
+
dragHandleProps: withDragHandle ? { onMouseDown: () => setIsDragHandleActive(true) } : void 0
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
//#endregion
|
|
124
|
+
export { useTreeNodeDragDrop };
|
|
125
|
+
|
|
126
|
+
//# sourceMappingURL=use-tree-node-drag-drop.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-tree-node-drag-drop.mjs","names":[],"sources":["../../../src/components/Tree/use-tree-node-drag-drop.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport { 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\nexport type TreeAllowDrop = (payload: TreeDragDropPayload) => boolean;\n\ninterface UseTreeNodeDragDropInput {\n nodeValue: string;\n hasChildren: boolean;\n data: TreeNodeData[];\n onDragDrop: ((payload: TreeDragDropPayload) => void) | undefined;\n dragStateRef: React.RefObject<TreeDragState>;\n allowDrop: TreeAllowDrop | undefined;\n withDragHandle: boolean | undefined;\n}\n\nexport interface TreeDragHandleProps {\n onMouseDown: (event: React.MouseEvent) => void;\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 = { elementProps: {}, dragHandleProps: undefined } as const;\n\nexport function useTreeNodeDragDrop({\n nodeValue,\n hasChildren,\n data,\n onDragDrop,\n dragStateRef,\n allowDrop,\n withDragHandle,\n}: UseTreeNodeDragDropInput) {\n const [isDragHandleActive, setIsDragHandleActive] = useState(false);\n\n useEffect(() => {\n if (!withDragHandle || !isDragHandleActive) {\n return undefined;\n }\n\n const handleWindowMouseUp = () => setIsDragHandleActive(false);\n window.addEventListener('mouseup', handleWindowMouseUp);\n return () => window.removeEventListener('mouseup', handleWindowMouseUp);\n }, [withDragHandle, isDragHandleActive]);\n\n if (!onDragDrop) {\n return EMPTY_DRAG_PROPS;\n }\n\n const handleDragStart = (event: React.DragEvent) => {\n if (withDragHandle && !isDragHandleActive) {\n return;\n }\n\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 const target = event.currentTarget as HTMLElement;\n const position = getDragDropPosition(event, target, hasChildren);\n\n if (allowDrop && !allowDrop({ draggedNode: draggedValue, targetNode: nodeValue, position })) {\n const prevTarget = dragStateRef.current.currentDropTarget;\n if (prevTarget && prevTarget !== target) {\n prevTarget.removeAttribute('data-drag-over');\n }\n target.removeAttribute('data-drag-over');\n dragStateRef.current.currentDropTarget = null;\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n event.dataTransfer.dropEffect = 'move';\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 const payload = { draggedNode: draggedValue, targetNode: nodeValue, position };\n if (!allowDrop || allowDrop(payload)) {\n onDragDrop(payload);\n }\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 if (withDragHandle) {\n setIsDragHandleActive(false);\n }\n };\n\n const elementProps = {\n draggable: withDragHandle ? isDragHandleActive : true,\n onDragStart: handleDragStart,\n onDragOver: handleDragOver,\n onDragLeave: handleDragLeave,\n onDrop: handleDrop,\n onDragEnd: handleDragEnd,\n };\n\n const dragHandleProps: TreeDragHandleProps | undefined = withDragHandle\n ? { onMouseDown: () => setIsDragHandleActive(true) }\n : undefined;\n\n return { elementProps, dragHandleProps };\n}\n"],"mappings":"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"}
|