@hitachivantara/uikit-react-core 5.36.1 → 5.36.3
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/dist/cjs/components/Card/Header/Header.cjs +1 -0
- package/dist/cjs/components/Card/Header/Header.cjs.map +1 -1
- package/dist/cjs/components/Card/Header/Header.styles.cjs +6 -10
- package/dist/cjs/components/Card/Header/Header.styles.cjs.map +1 -1
- package/dist/cjs/components/Section/Section.cjs +4 -3
- package/dist/cjs/components/Section/Section.cjs.map +1 -1
- package/dist/cjs/components/TreeView/TreeItem/DefaultContent.cjs +24 -8
- package/dist/cjs/components/TreeView/TreeItem/DefaultContent.cjs.map +1 -1
- package/dist/cjs/components/TreeView/TreeItem/TreeItem.cjs +7 -6
- package/dist/cjs/components/TreeView/TreeItem/TreeItem.cjs.map +1 -1
- package/dist/cjs/components/TreeView/TreeItem/useHvTreeItem.cjs +2 -3
- package/dist/cjs/components/TreeView/TreeItem/useHvTreeItem.cjs.map +1 -1
- package/dist/cjs/components/TreeView/TreeView.cjs +4 -4
- package/dist/cjs/components/TreeView/TreeView.cjs.map +1 -1
- package/dist/cjs/components/TreeView/internals/DescendantProvider.cjs +146 -0
- package/dist/cjs/components/TreeView/internals/DescendantProvider.cjs.map +1 -0
- package/dist/cjs/components/TreeView/internals/TreeViewProvider.cjs +34 -0
- package/dist/cjs/components/TreeView/internals/TreeViewProvider.cjs.map +1 -0
- package/dist/cjs/components/TreeView/internals/corePlugins.cjs +6 -0
- package/dist/cjs/components/TreeView/internals/corePlugins.cjs.map +1 -0
- package/dist/cjs/components/TreeView/internals/hooks/plugins/defaultPlugins.cjs +11 -0
- package/dist/cjs/components/TreeView/internals/hooks/plugins/defaultPlugins.cjs.map +1 -0
- package/dist/cjs/components/TreeView/internals/hooks/plugins/useTreeViewContextValueBuilder.cjs +28 -0
- package/dist/cjs/components/TreeView/internals/hooks/plugins/useTreeViewContextValueBuilder.cjs.map +1 -0
- package/dist/cjs/components/TreeView/internals/hooks/plugins/useTreeViewExpansion.cjs +80 -0
- package/dist/cjs/components/TreeView/internals/hooks/plugins/useTreeViewExpansion.cjs.map +1 -0
- package/dist/cjs/components/TreeView/internals/hooks/plugins/useTreeViewFocus.cjs +105 -0
- package/dist/cjs/components/TreeView/internals/hooks/plugins/useTreeViewFocus.cjs.map +1 -0
- package/dist/cjs/components/TreeView/internals/hooks/plugins/useTreeViewKeyboardNavigation.cjs +237 -0
- package/dist/cjs/components/TreeView/internals/hooks/plugins/useTreeViewKeyboardNavigation.cjs.map +1 -0
- package/dist/cjs/components/TreeView/internals/hooks/plugins/useTreeViewNodes.cjs +82 -0
- package/dist/cjs/components/TreeView/internals/hooks/plugins/useTreeViewNodes.cjs.map +1 -0
- package/dist/cjs/components/TreeView/internals/hooks/plugins/useTreeViewSelection.cjs +232 -0
- package/dist/cjs/components/TreeView/internals/hooks/plugins/useTreeViewSelection.cjs.map +1 -0
- package/dist/cjs/components/TreeView/internals/hooks/useInstanceEventHandler.cjs +93 -0
- package/dist/cjs/components/TreeView/internals/hooks/useInstanceEventHandler.cjs.map +1 -0
- package/dist/cjs/components/TreeView/internals/hooks/useTreeView.cjs +87 -0
- package/dist/cjs/components/TreeView/internals/hooks/useTreeView.cjs.map +1 -0
- package/dist/cjs/components/TreeView/internals/hooks/useTreeViewInstanceEvents.cjs +52 -0
- package/dist/cjs/components/TreeView/internals/hooks/useTreeViewInstanceEvents.cjs.map +1 -0
- package/dist/cjs/components/TreeView/internals/hooks/useTreeViewModels.cjs +58 -0
- package/dist/cjs/components/TreeView/internals/hooks/useTreeViewModels.cjs.map +1 -0
- package/dist/cjs/components/TreeView/internals/hooks/utils.cjs +47 -0
- package/dist/cjs/components/TreeView/internals/hooks/utils.cjs.map +1 -0
- package/dist/cjs/components/TreeView/internals/utils/EventManager.cjs +62 -0
- package/dist/cjs/components/TreeView/internals/utils/EventManager.cjs.map +1 -0
- package/dist/cjs/components/TreeView/internals/utils/FinalizationRegistryBasedCleanupTracking.cjs +22 -0
- package/dist/cjs/components/TreeView/internals/utils/FinalizationRegistryBasedCleanupTracking.cjs.map +1 -0
- package/dist/cjs/components/TreeView/internals/utils/TimerBasedCleanupTracking.cjs +41 -0
- package/dist/cjs/components/TreeView/internals/utils/TimerBasedCleanupTracking.cjs.map +1 -0
- package/dist/cjs/components/TreeView/internals/utils/publishTreeViewEvent.cjs +7 -0
- package/dist/cjs/components/TreeView/internals/utils/publishTreeViewEvent.cjs.map +1 -0
- package/dist/esm/components/Card/Header/Header.js +1 -0
- package/dist/esm/components/Card/Header/Header.js.map +1 -1
- package/dist/esm/components/Card/Header/Header.styles.js +6 -10
- package/dist/esm/components/Card/Header/Header.styles.js.map +1 -1
- package/dist/esm/components/Section/Section.js +4 -3
- package/dist/esm/components/Section/Section.js.map +1 -1
- package/dist/esm/components/TreeView/TreeItem/DefaultContent.js +18 -2
- package/dist/esm/components/TreeView/TreeItem/DefaultContent.js.map +1 -1
- package/dist/esm/components/TreeView/TreeItem/TreeItem.js +3 -4
- package/dist/esm/components/TreeView/TreeItem/TreeItem.js.map +1 -1
- package/dist/esm/components/TreeView/TreeItem/useHvTreeItem.js +1 -2
- package/dist/esm/components/TreeView/TreeItem/useHvTreeItem.js.map +1 -1
- package/dist/esm/components/TreeView/TreeView.js +4 -4
- package/dist/esm/components/TreeView/TreeView.js.map +1 -1
- package/dist/esm/components/TreeView/internals/DescendantProvider.js +127 -0
- package/dist/esm/components/TreeView/internals/DescendantProvider.js.map +1 -0
- package/dist/esm/components/TreeView/internals/TreeViewProvider.js +34 -0
- package/dist/esm/components/TreeView/internals/TreeViewProvider.js.map +1 -0
- package/dist/esm/components/TreeView/internals/corePlugins.js +6 -0
- package/dist/esm/components/TreeView/internals/corePlugins.js.map +1 -0
- package/dist/esm/components/TreeView/internals/hooks/plugins/defaultPlugins.js +11 -0
- package/dist/esm/components/TreeView/internals/hooks/plugins/defaultPlugins.js.map +1 -0
- package/dist/esm/components/TreeView/internals/hooks/plugins/useTreeViewContextValueBuilder.js +28 -0
- package/dist/esm/components/TreeView/internals/hooks/plugins/useTreeViewContextValueBuilder.js.map +1 -0
- package/dist/esm/components/TreeView/internals/hooks/plugins/useTreeViewExpansion.js +61 -0
- package/dist/esm/components/TreeView/internals/hooks/plugins/useTreeViewExpansion.js.map +1 -0
- package/dist/esm/components/TreeView/internals/hooks/plugins/useTreeViewFocus.js +86 -0
- package/dist/esm/components/TreeView/internals/hooks/plugins/useTreeViewFocus.js.map +1 -0
- package/dist/esm/components/TreeView/internals/hooks/plugins/useTreeViewKeyboardNavigation.js +218 -0
- package/dist/esm/components/TreeView/internals/hooks/plugins/useTreeViewKeyboardNavigation.js.map +1 -0
- package/dist/esm/components/TreeView/internals/hooks/plugins/useTreeViewNodes.js +63 -0
- package/dist/esm/components/TreeView/internals/hooks/plugins/useTreeViewNodes.js.map +1 -0
- package/dist/esm/components/TreeView/internals/hooks/plugins/useTreeViewSelection.js +213 -0
- package/dist/esm/components/TreeView/internals/hooks/plugins/useTreeViewSelection.js.map +1 -0
- package/dist/esm/components/TreeView/internals/hooks/useInstanceEventHandler.js +74 -0
- package/dist/esm/components/TreeView/internals/hooks/useInstanceEventHandler.js.map +1 -0
- package/dist/esm/components/TreeView/internals/hooks/useTreeView.js +68 -0
- package/dist/esm/components/TreeView/internals/hooks/useTreeView.js.map +1 -0
- package/dist/esm/components/TreeView/internals/hooks/useTreeViewInstanceEvents.js +33 -0
- package/dist/esm/components/TreeView/internals/hooks/useTreeViewInstanceEvents.js.map +1 -0
- package/dist/esm/components/TreeView/internals/hooks/useTreeViewModels.js +39 -0
- package/dist/esm/components/TreeView/internals/hooks/useTreeViewModels.js.map +1 -0
- package/dist/esm/components/TreeView/internals/hooks/utils.js +47 -0
- package/dist/esm/components/TreeView/internals/hooks/utils.js.map +1 -0
- package/dist/esm/components/TreeView/internals/utils/EventManager.js +62 -0
- package/dist/esm/components/TreeView/internals/utils/EventManager.js.map +1 -0
- package/dist/esm/components/TreeView/internals/utils/FinalizationRegistryBasedCleanupTracking.js +22 -0
- package/dist/esm/components/TreeView/internals/utils/FinalizationRegistryBasedCleanupTracking.js.map +1 -0
- package/dist/esm/components/TreeView/internals/utils/TimerBasedCleanupTracking.js +41 -0
- package/dist/esm/components/TreeView/internals/utils/TimerBasedCleanupTracking.js.map +1 -0
- package/dist/esm/components/TreeView/internals/utils/publishTreeViewEvent.js +7 -0
- package/dist/esm/components/TreeView/internals/utils/publishTreeViewEvent.js.map +1 -0
- package/dist/types/index.d.ts +216 -14
- package/package.json +5 -6
- package/dist/cjs/components/TreeView/internals.cjs +0 -30
- package/dist/cjs/components/TreeView/internals.cjs.map +0 -1
- package/dist/esm/components/TreeView/internals.js +0 -15
- package/dist/esm/components/TreeView/internals.js.map +0 -1
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { useTheme } from "@mui/material/styles";
|
|
3
|
+
import { useEventCallback } from "@mui/material/utils";
|
|
4
|
+
import { populateInstance, getFirstNode, getLastNode, getPreviousNode, getNextNode } from "../utils.js";
|
|
5
|
+
function isPrintableCharacter(string) {
|
|
6
|
+
return string && string.length === 1 && string.match(/\S/);
|
|
7
|
+
}
|
|
8
|
+
function findNextFirstChar(firstChars, startIndex, char) {
|
|
9
|
+
for (let i = startIndex; i < firstChars.length; i += 1) {
|
|
10
|
+
if (char === firstChars[i]) {
|
|
11
|
+
return i;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return -1;
|
|
15
|
+
}
|
|
16
|
+
const useTreeViewKeyboardNavigation = ({
|
|
17
|
+
instance,
|
|
18
|
+
params,
|
|
19
|
+
state
|
|
20
|
+
}) => {
|
|
21
|
+
const theme = useTheme();
|
|
22
|
+
const isRtl = theme.direction === "rtl";
|
|
23
|
+
const firstCharMap = React.useRef({});
|
|
24
|
+
const mapFirstChar = useEventCallback((nodeId, firstChar) => {
|
|
25
|
+
firstCharMap.current[nodeId] = firstChar;
|
|
26
|
+
return () => {
|
|
27
|
+
const newMap = {
|
|
28
|
+
...firstCharMap.current
|
|
29
|
+
};
|
|
30
|
+
delete newMap[nodeId];
|
|
31
|
+
firstCharMap.current = newMap;
|
|
32
|
+
};
|
|
33
|
+
});
|
|
34
|
+
populateInstance(instance, {
|
|
35
|
+
mapFirstChar
|
|
36
|
+
});
|
|
37
|
+
const handleNextArrow = (event) => {
|
|
38
|
+
if (state.focusedNodeId != null && instance.isNodeExpandable(state.focusedNodeId)) {
|
|
39
|
+
if (instance.isNodeExpanded(state.focusedNodeId)) {
|
|
40
|
+
instance.focusNode(event, getNextNode(instance, state.focusedNodeId));
|
|
41
|
+
} else if (!instance.isNodeDisabled(state.focusedNodeId)) {
|
|
42
|
+
instance.toggleNodeExpansion(event, state.focusedNodeId);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return true;
|
|
46
|
+
};
|
|
47
|
+
const handlePreviousArrow = (event) => {
|
|
48
|
+
if (state.focusedNodeId == null) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
if (instance.isNodeExpanded(state.focusedNodeId) && !instance.isNodeDisabled(state.focusedNodeId)) {
|
|
52
|
+
instance.toggleNodeExpansion(event, state.focusedNodeId);
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
const parent = instance.getNode(state.focusedNodeId).parentId;
|
|
56
|
+
if (parent) {
|
|
57
|
+
instance.focusNode(event, parent);
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
return false;
|
|
61
|
+
};
|
|
62
|
+
const focusByFirstCharacter = (event, nodeId, firstChar) => {
|
|
63
|
+
let start;
|
|
64
|
+
let index;
|
|
65
|
+
const lowercaseChar = firstChar.toLowerCase();
|
|
66
|
+
const firstCharIds = [];
|
|
67
|
+
const firstChars = [];
|
|
68
|
+
Object.keys(firstCharMap.current).forEach((mapNodeId) => {
|
|
69
|
+
const map = instance.getNode(mapNodeId);
|
|
70
|
+
const visible = map.parentId ? instance.isNodeExpanded(map.parentId) : true;
|
|
71
|
+
const shouldBeSkipped = params.disabledItemsFocusable ? false : instance.isNodeDisabled(mapNodeId);
|
|
72
|
+
if (visible && !shouldBeSkipped) {
|
|
73
|
+
firstCharIds.push(mapNodeId);
|
|
74
|
+
firstChars.push(firstCharMap.current[mapNodeId]);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
start = firstCharIds.indexOf(nodeId) + 1;
|
|
78
|
+
if (start >= firstCharIds.length) {
|
|
79
|
+
start = 0;
|
|
80
|
+
}
|
|
81
|
+
index = findNextFirstChar(firstChars, start, lowercaseChar);
|
|
82
|
+
if (index === -1) {
|
|
83
|
+
index = findNextFirstChar(firstChars, 0, lowercaseChar);
|
|
84
|
+
}
|
|
85
|
+
if (index > -1) {
|
|
86
|
+
instance.focusNode(event, firstCharIds[index]);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
const selectNextNode = (event, id) => {
|
|
90
|
+
if (!instance.isNodeDisabled(getNextNode(instance, id))) {
|
|
91
|
+
instance.selectRange(event, {
|
|
92
|
+
end: getNextNode(instance, id),
|
|
93
|
+
current: id
|
|
94
|
+
}, true);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
const selectPreviousNode = (event, nodeId) => {
|
|
98
|
+
if (!instance.isNodeDisabled(getPreviousNode(instance, nodeId))) {
|
|
99
|
+
instance.selectRange(event, {
|
|
100
|
+
end: getPreviousNode(instance, nodeId),
|
|
101
|
+
current: nodeId
|
|
102
|
+
}, true);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
const createHandleKeyDown = (otherHandlers) => (event) => {
|
|
106
|
+
otherHandlers.onKeyDown?.(event);
|
|
107
|
+
let flag = false;
|
|
108
|
+
const {
|
|
109
|
+
key
|
|
110
|
+
} = event;
|
|
111
|
+
if (event.altKey || event.currentTarget !== event.target || state.focusedNodeId == null) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const ctrlPressed = event.ctrlKey || event.metaKey;
|
|
115
|
+
switch (key) {
|
|
116
|
+
case " ":
|
|
117
|
+
if (!params.disableSelection && !instance.isNodeDisabled(state.focusedNodeId)) {
|
|
118
|
+
flag = true;
|
|
119
|
+
if (params.multiSelect && event.shiftKey) {
|
|
120
|
+
instance.selectRange(event, {
|
|
121
|
+
end: state.focusedNodeId
|
|
122
|
+
});
|
|
123
|
+
} else if (params.multiSelect) {
|
|
124
|
+
instance.selectNode(event, state.focusedNodeId, true);
|
|
125
|
+
} else {
|
|
126
|
+
instance.selectNode(event, state.focusedNodeId);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
event.stopPropagation();
|
|
130
|
+
break;
|
|
131
|
+
case "Enter":
|
|
132
|
+
if (!instance.isNodeDisabled(state.focusedNodeId)) {
|
|
133
|
+
if (instance.isNodeExpandable(state.focusedNodeId)) {
|
|
134
|
+
instance.toggleNodeExpansion(event, state.focusedNodeId);
|
|
135
|
+
flag = true;
|
|
136
|
+
} else if (!params.disableSelection) {
|
|
137
|
+
flag = true;
|
|
138
|
+
if (params.multiSelect) {
|
|
139
|
+
instance.selectNode(event, state.focusedNodeId, true);
|
|
140
|
+
} else {
|
|
141
|
+
instance.selectNode(event, state.focusedNodeId);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
event.stopPropagation();
|
|
146
|
+
break;
|
|
147
|
+
case "ArrowDown":
|
|
148
|
+
if (params.multiSelect && event.shiftKey && !params.disableSelection) {
|
|
149
|
+
selectNextNode(event, state.focusedNodeId);
|
|
150
|
+
}
|
|
151
|
+
instance.focusNode(event, getNextNode(instance, state.focusedNodeId));
|
|
152
|
+
flag = true;
|
|
153
|
+
break;
|
|
154
|
+
case "ArrowUp":
|
|
155
|
+
if (params.multiSelect && event.shiftKey && !params.disableSelection) {
|
|
156
|
+
selectPreviousNode(event, state.focusedNodeId);
|
|
157
|
+
}
|
|
158
|
+
instance.focusNode(event, getPreviousNode(instance, state.focusedNodeId));
|
|
159
|
+
flag = true;
|
|
160
|
+
break;
|
|
161
|
+
case "ArrowRight":
|
|
162
|
+
if (isRtl) {
|
|
163
|
+
flag = handlePreviousArrow(event);
|
|
164
|
+
} else {
|
|
165
|
+
flag = handleNextArrow(event);
|
|
166
|
+
}
|
|
167
|
+
break;
|
|
168
|
+
case "ArrowLeft":
|
|
169
|
+
if (isRtl) {
|
|
170
|
+
flag = handleNextArrow(event);
|
|
171
|
+
} else {
|
|
172
|
+
flag = handlePreviousArrow(event);
|
|
173
|
+
}
|
|
174
|
+
break;
|
|
175
|
+
case "Home":
|
|
176
|
+
if (params.multiSelect && ctrlPressed && event.shiftKey && !params.disableSelection && !instance.isNodeDisabled(state.focusedNodeId)) {
|
|
177
|
+
instance.rangeSelectToFirst(event, state.focusedNodeId);
|
|
178
|
+
}
|
|
179
|
+
instance.focusNode(event, getFirstNode(instance));
|
|
180
|
+
flag = true;
|
|
181
|
+
break;
|
|
182
|
+
case "End":
|
|
183
|
+
if (params.multiSelect && ctrlPressed && event.shiftKey && !params.disableSelection && !instance.isNodeDisabled(state.focusedNodeId)) {
|
|
184
|
+
instance.rangeSelectToLast(event, state.focusedNodeId);
|
|
185
|
+
}
|
|
186
|
+
instance.focusNode(event, getLastNode(instance));
|
|
187
|
+
flag = true;
|
|
188
|
+
break;
|
|
189
|
+
default:
|
|
190
|
+
if (key === "*") {
|
|
191
|
+
instance.expandAllSiblings(event, state.focusedNodeId);
|
|
192
|
+
flag = true;
|
|
193
|
+
} else if (params.multiSelect && ctrlPressed && key.toLowerCase() === "a" && !params.disableSelection) {
|
|
194
|
+
instance.selectRange(event, {
|
|
195
|
+
start: getFirstNode(instance),
|
|
196
|
+
end: getLastNode(instance)
|
|
197
|
+
});
|
|
198
|
+
flag = true;
|
|
199
|
+
} else if (!ctrlPressed && !event.shiftKey && isPrintableCharacter(key)) {
|
|
200
|
+
focusByFirstCharacter(event, state.focusedNodeId, key);
|
|
201
|
+
flag = true;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
if (flag) {
|
|
205
|
+
event.preventDefault();
|
|
206
|
+
event.stopPropagation();
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
return {
|
|
210
|
+
getRootProps: (otherHandlers) => ({
|
|
211
|
+
onKeyDown: createHandleKeyDown(otherHandlers)
|
|
212
|
+
})
|
|
213
|
+
};
|
|
214
|
+
};
|
|
215
|
+
export {
|
|
216
|
+
useTreeViewKeyboardNavigation
|
|
217
|
+
};
|
|
218
|
+
//# sourceMappingURL=useTreeViewKeyboardNavigation.js.map
|
package/dist/esm/components/TreeView/internals/hooks/plugins/useTreeViewKeyboardNavigation.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTreeViewKeyboardNavigation.js","sources":["../../../../../../../src/components/TreeView/internals/hooks/plugins/useTreeViewKeyboardNavigation.ts"],"sourcesContent":["import * as React from \"react\";\nimport { useTheme } from \"@mui/material/styles\";\nimport { useEventCallback } from \"@mui/material/utils\";\nimport { EventHandlers } from \"@mui/base/utils\";\n\nimport { TreeViewPlugin, TreeViewPluginSignature } from \"../../types\";\nimport {\n getFirstNode,\n getLastNode,\n getNextNode,\n getPreviousNode,\n populateInstance,\n} from \"../utils\";\nimport type { UseTreeViewNodesSignature } from \"./useTreeViewNodes\";\nimport type { UseTreeViewSelectionSignature } from \"./useTreeViewSelection\";\nimport type { UseTreeViewFocusSignature } from \"./useTreeViewFocus\";\nimport type { UseTreeViewExpansionSignature } from \"./useTreeViewExpansion\";\n\nfunction isPrintableCharacter(string: string) {\n return string && string.length === 1 && string.match(/\\S/);\n}\n\nfunction findNextFirstChar(\n firstChars: string[],\n startIndex: number,\n char: string\n) {\n for (let i = startIndex; i < firstChars.length; i += 1) {\n if (char === firstChars[i]) {\n return i;\n }\n }\n return -1;\n}\n\nexport interface UseTreeViewKeyboardNavigationInstance {\n mapFirstChar: (nodeId: string, firstChar: string) => () => void;\n}\n\nexport type UseTreeViewKeyboardNavigationSignature = TreeViewPluginSignature<\n {},\n {},\n UseTreeViewKeyboardNavigationInstance,\n {},\n {},\n never,\n [\n UseTreeViewNodesSignature,\n UseTreeViewSelectionSignature<any>,\n UseTreeViewFocusSignature,\n UseTreeViewExpansionSignature\n ]\n>;\n\nexport const useTreeViewKeyboardNavigation: TreeViewPlugin<\n UseTreeViewKeyboardNavigationSignature\n> = ({ instance, params, state }) => {\n const theme = useTheme();\n const isRtl = theme.direction === \"rtl\";\n const firstCharMap = React.useRef<{ [nodeId: string]: string }>({});\n\n const mapFirstChar = useEventCallback((nodeId: string, firstChar: string) => {\n firstCharMap.current[nodeId] = firstChar;\n\n return () => {\n const newMap = { ...firstCharMap.current };\n delete newMap[nodeId];\n firstCharMap.current = newMap;\n };\n });\n\n populateInstance<UseTreeViewKeyboardNavigationSignature>(instance, {\n mapFirstChar,\n });\n\n const handleNextArrow = (event: React.KeyboardEvent<HTMLUListElement>) => {\n if (\n state.focusedNodeId != null &&\n instance.isNodeExpandable(state.focusedNodeId)\n ) {\n if (instance.isNodeExpanded(state.focusedNodeId)) {\n instance.focusNode(event, getNextNode(instance, state.focusedNodeId));\n } else if (!instance.isNodeDisabled(state.focusedNodeId)) {\n instance.toggleNodeExpansion(event, state.focusedNodeId);\n }\n }\n return true;\n };\n\n const handlePreviousArrow = (\n event: React.KeyboardEvent<HTMLUListElement>\n ) => {\n if (state.focusedNodeId == null) {\n return false;\n }\n\n if (\n instance.isNodeExpanded(state.focusedNodeId) &&\n !instance.isNodeDisabled(state.focusedNodeId)\n ) {\n instance.toggleNodeExpansion(event, state.focusedNodeId!);\n return true;\n }\n\n const parent = instance.getNode(state.focusedNodeId).parentId;\n if (parent) {\n instance.focusNode(event, parent);\n return true;\n }\n return false;\n };\n\n const focusByFirstCharacter = (\n event: React.KeyboardEvent<HTMLUListElement>,\n nodeId: string,\n firstChar: string\n ) => {\n let start: number;\n let index: number;\n const lowercaseChar = firstChar.toLowerCase();\n\n const firstCharIds: string[] = [];\n const firstChars: string[] = [];\n // This really only works since the ids are strings\n Object.keys(firstCharMap.current).forEach((mapNodeId) => {\n const map = instance.getNode(mapNodeId);\n const visible = map.parentId\n ? instance.isNodeExpanded(map.parentId)\n : true;\n const shouldBeSkipped = params.disabledItemsFocusable\n ? false\n : instance.isNodeDisabled(mapNodeId);\n\n if (visible && !shouldBeSkipped) {\n firstCharIds.push(mapNodeId);\n firstChars.push(firstCharMap.current[mapNodeId]);\n }\n });\n\n // Get start index for search based on position of currentItem\n start = firstCharIds.indexOf(nodeId) + 1;\n if (start >= firstCharIds.length) {\n start = 0;\n }\n\n // Check remaining slots in the menu\n index = findNextFirstChar(firstChars, start, lowercaseChar);\n\n // If not found in remaining slots, check from beginning\n if (index === -1) {\n index = findNextFirstChar(firstChars, 0, lowercaseChar);\n }\n\n // If match was found...\n if (index > -1) {\n instance.focusNode(event, firstCharIds[index]);\n }\n };\n\n const selectNextNode = (\n event: React.KeyboardEvent<HTMLUListElement>,\n id: string\n ) => {\n if (!instance.isNodeDisabled(getNextNode(instance, id))) {\n instance.selectRange(\n event,\n {\n end: getNextNode(instance, id),\n current: id,\n },\n true\n );\n }\n };\n\n const selectPreviousNode = (\n event: React.KeyboardEvent<HTMLUListElement>,\n nodeId: string\n ) => {\n if (!instance.isNodeDisabled(getPreviousNode(instance, nodeId))) {\n instance.selectRange(\n event,\n {\n end: getPreviousNode(instance, nodeId)!,\n current: nodeId,\n },\n true\n );\n }\n };\n\n const createHandleKeyDown =\n (otherHandlers: EventHandlers) =>\n (event: React.KeyboardEvent<HTMLUListElement>) => {\n otherHandlers.onKeyDown?.(event);\n\n let flag = false;\n const { key } = event;\n\n // If the tree is empty there will be no focused node\n if (\n event.altKey ||\n event.currentTarget !== event.target ||\n state.focusedNodeId == null\n ) {\n return;\n }\n\n const ctrlPressed = event.ctrlKey || event.metaKey;\n switch (key) {\n case \" \":\n if (\n !params.disableSelection &&\n !instance.isNodeDisabled(state.focusedNodeId)\n ) {\n flag = true;\n if (params.multiSelect && event.shiftKey) {\n instance.selectRange(event, { end: state.focusedNodeId });\n } else if (params.multiSelect) {\n instance.selectNode(event, state.focusedNodeId, true);\n } else {\n instance.selectNode(event, state.focusedNodeId);\n }\n }\n event.stopPropagation();\n break;\n case \"Enter\":\n if (!instance.isNodeDisabled(state.focusedNodeId)) {\n if (instance.isNodeExpandable(state.focusedNodeId)) {\n instance.toggleNodeExpansion(event, state.focusedNodeId);\n flag = true;\n } else if (!params.disableSelection) {\n flag = true;\n if (params.multiSelect) {\n instance.selectNode(event, state.focusedNodeId, true);\n } else {\n instance.selectNode(event, state.focusedNodeId);\n }\n }\n }\n event.stopPropagation();\n break;\n case \"ArrowDown\":\n if (\n params.multiSelect &&\n event.shiftKey &&\n !params.disableSelection\n ) {\n selectNextNode(event, state.focusedNodeId);\n }\n instance.focusNode(event, getNextNode(instance, state.focusedNodeId));\n flag = true;\n break;\n case \"ArrowUp\":\n if (\n params.multiSelect &&\n event.shiftKey &&\n !params.disableSelection\n ) {\n selectPreviousNode(event, state.focusedNodeId);\n }\n instance.focusNode(\n event,\n getPreviousNode(instance, state.focusedNodeId)\n );\n flag = true;\n break;\n case \"ArrowRight\":\n if (isRtl) {\n flag = handlePreviousArrow(event);\n } else {\n flag = handleNextArrow(event);\n }\n break;\n case \"ArrowLeft\":\n if (isRtl) {\n flag = handleNextArrow(event);\n } else {\n flag = handlePreviousArrow(event);\n }\n break;\n case \"Home\":\n if (\n params.multiSelect &&\n ctrlPressed &&\n event.shiftKey &&\n !params.disableSelection &&\n !instance.isNodeDisabled(state.focusedNodeId)\n ) {\n instance.rangeSelectToFirst(event, state.focusedNodeId);\n }\n instance.focusNode(event, getFirstNode(instance));\n flag = true;\n break;\n case \"End\":\n if (\n params.multiSelect &&\n ctrlPressed &&\n event.shiftKey &&\n !params.disableSelection &&\n !instance.isNodeDisabled(state.focusedNodeId)\n ) {\n instance.rangeSelectToLast(event, state.focusedNodeId);\n }\n instance.focusNode(event, getLastNode(instance));\n flag = true;\n break;\n default:\n if (key === \"*\") {\n instance.expandAllSiblings(event, state.focusedNodeId);\n flag = true;\n } else if (\n params.multiSelect &&\n ctrlPressed &&\n key.toLowerCase() === \"a\" &&\n !params.disableSelection\n ) {\n instance.selectRange(event, {\n start: getFirstNode(instance),\n end: getLastNode(instance),\n });\n flag = true;\n } else if (\n !ctrlPressed &&\n !event.shiftKey &&\n isPrintableCharacter(key)\n ) {\n focusByFirstCharacter(event, state.focusedNodeId, key);\n flag = true;\n }\n }\n\n if (flag) {\n event.preventDefault();\n event.stopPropagation();\n }\n };\n\n return {\n getRootProps: (otherHandlers) => ({\n onKeyDown: createHandleKeyDown(otherHandlers),\n }),\n };\n};\n"],"names":["isPrintableCharacter","string","length","match","findNextFirstChar","firstChars","startIndex","char","i","useTreeViewKeyboardNavigation","instance","params","state","theme","useTheme","isRtl","direction","firstCharMap","React","useRef","mapFirstChar","useEventCallback","nodeId","firstChar","current","newMap","populateInstance","handleNextArrow","event","focusedNodeId","isNodeExpandable","isNodeExpanded","focusNode","getNextNode","isNodeDisabled","toggleNodeExpansion","handlePreviousArrow","parent","getNode","parentId","focusByFirstCharacter","start","index","lowercaseChar","toLowerCase","firstCharIds","Object","keys","forEach","mapNodeId","map","visible","shouldBeSkipped","disabledItemsFocusable","push","indexOf","selectNextNode","id","selectRange","end","selectPreviousNode","getPreviousNode","createHandleKeyDown","otherHandlers","onKeyDown","flag","key","altKey","currentTarget","target","ctrlPressed","ctrlKey","metaKey","disableSelection","multiSelect","shiftKey","selectNode","stopPropagation","rangeSelectToFirst","getFirstNode","rangeSelectToLast","getLastNode","expandAllSiblings","preventDefault","getRootProps"],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { useEventCallback } from "@mui/material/utils";
|
|
3
|
+
import { populateInstance } from "../utils.js";
|
|
4
|
+
import { publishTreeViewEvent } from "../../utils/publishTreeViewEvent.js";
|
|
5
|
+
const useTreeViewNodes = ({
|
|
6
|
+
instance,
|
|
7
|
+
params
|
|
8
|
+
}) => {
|
|
9
|
+
const nodeMap = React.useRef({});
|
|
10
|
+
const getNode = React.useCallback((nodeId) => nodeMap.current[nodeId], []);
|
|
11
|
+
const insertNode = React.useCallback((node) => {
|
|
12
|
+
nodeMap.current[node.id] = node;
|
|
13
|
+
}, []);
|
|
14
|
+
const removeNode = React.useCallback((nodeId) => {
|
|
15
|
+
const newMap = {
|
|
16
|
+
...nodeMap.current
|
|
17
|
+
};
|
|
18
|
+
delete newMap[nodeId];
|
|
19
|
+
nodeMap.current = newMap;
|
|
20
|
+
publishTreeViewEvent(instance, "removeNode", {
|
|
21
|
+
id: nodeId
|
|
22
|
+
});
|
|
23
|
+
}, [instance]);
|
|
24
|
+
const isNodeDisabled = React.useCallback((nodeId) => {
|
|
25
|
+
if (nodeId == null) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
let node = instance.getNode(nodeId);
|
|
29
|
+
if (!node) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
if (node.disabled) {
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
while (node.parentId != null) {
|
|
36
|
+
node = instance.getNode(node.parentId);
|
|
37
|
+
if (node.disabled) {
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return false;
|
|
42
|
+
}, [instance]);
|
|
43
|
+
const getChildrenIds = useEventCallback((nodeId) => Object.values(nodeMap.current).filter((node) => node.parentId === nodeId).sort((a, b) => a.index - b.index).map((child) => child.id));
|
|
44
|
+
const getNavigableChildrenIds = (nodeId) => {
|
|
45
|
+
let childrenIds = instance.getChildrenIds(nodeId);
|
|
46
|
+
if (!params.disabledItemsFocusable) {
|
|
47
|
+
childrenIds = childrenIds.filter((node) => !instance.isNodeDisabled(node));
|
|
48
|
+
}
|
|
49
|
+
return childrenIds;
|
|
50
|
+
};
|
|
51
|
+
populateInstance(instance, {
|
|
52
|
+
getNode,
|
|
53
|
+
updateNode: insertNode,
|
|
54
|
+
removeNode,
|
|
55
|
+
getChildrenIds,
|
|
56
|
+
getNavigableChildrenIds,
|
|
57
|
+
isNodeDisabled
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
export {
|
|
61
|
+
useTreeViewNodes
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=useTreeViewNodes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTreeViewNodes.js","sources":["../../../../../../../src/components/TreeView/internals/hooks/plugins/useTreeViewNodes.ts"],"sourcesContent":["import * as React from \"react\";\nimport { useEventCallback } from \"@mui/material/utils\";\n\nimport {\n DefaultizedProps,\n TreeViewNode,\n TreeViewPlugin,\n TreeViewPluginSignature,\n} from \"../../types\";\nimport { populateInstance } from \"../utils\";\nimport { publishTreeViewEvent } from \"../../utils/publishTreeViewEvent\";\n\nexport interface UseTreeViewNodesInstance {\n getNode: (nodeId: string) => TreeViewNode;\n updateNode: (node: TreeViewNode) => void;\n removeNode: (nodeId: string) => void;\n getChildrenIds: (nodeId: string | null) => string[];\n getNavigableChildrenIds: (nodeId: string | null) => string[];\n isNodeDisabled: (nodeId: string | null) => nodeId is string;\n}\n\nexport interface UseTreeViewNodesParameters {\n /**\n * If `true`, will allow focus on disabled items.\n * @default false\n */\n disabledItemsFocusable?: boolean;\n}\n\nexport type UseTreeViewNodesDefaultizedParameters = DefaultizedProps<\n UseTreeViewNodesParameters,\n \"disabledItemsFocusable\"\n>;\n\ninterface UseTreeViewNodesEventLookup {\n removeNode: {\n params: { id: string };\n };\n}\n\nexport type UseTreeViewNodesSignature = TreeViewPluginSignature<\n UseTreeViewNodesParameters,\n UseTreeViewNodesDefaultizedParameters,\n UseTreeViewNodesInstance,\n UseTreeViewNodesEventLookup,\n {},\n never,\n []\n>;\n\nexport const useTreeViewNodes: TreeViewPlugin<UseTreeViewNodesSignature> = ({\n instance,\n params,\n}) => {\n const nodeMap = React.useRef<{ [nodeId: string]: TreeViewNode }>({});\n\n const getNode = React.useCallback(\n (nodeId: string) => nodeMap.current[nodeId],\n []\n );\n\n const insertNode = React.useCallback((node: TreeViewNode) => {\n nodeMap.current[node.id] = node;\n }, []);\n\n const removeNode = React.useCallback(\n (nodeId: string) => {\n const newMap = { ...nodeMap.current };\n delete newMap[nodeId];\n nodeMap.current = newMap;\n publishTreeViewEvent(instance as any, \"removeNode\", { id: nodeId });\n },\n [instance]\n );\n\n const isNodeDisabled = React.useCallback(\n (nodeId: string | null): nodeId is string => {\n if (nodeId == null) {\n return false;\n }\n\n let node = instance.getNode(nodeId);\n\n // This can be called before the node has been added to the node map.\n if (!node) {\n return false;\n }\n\n if (node.disabled) {\n return true;\n }\n\n while (node.parentId != null) {\n node = instance.getNode(node.parentId);\n if (node.disabled) {\n return true;\n }\n }\n\n return false;\n },\n [instance]\n );\n\n const getChildrenIds = useEventCallback((nodeId: string | null) =>\n Object.values(nodeMap.current)\n .filter((node) => node.parentId === nodeId)\n .sort((a, b) => a.index - b.index)\n .map((child) => child.id)\n );\n\n const getNavigableChildrenIds = (nodeId: string | null) => {\n let childrenIds = instance.getChildrenIds(nodeId);\n\n if (!params.disabledItemsFocusable) {\n childrenIds = childrenIds.filter(\n (node) => !instance.isNodeDisabled(node)\n );\n }\n return childrenIds;\n };\n\n populateInstance<UseTreeViewNodesSignature>(instance, {\n getNode,\n updateNode: insertNode,\n removeNode,\n getChildrenIds,\n getNavigableChildrenIds,\n isNodeDisabled,\n });\n};\n"],"names":["useTreeViewNodes","instance","params","nodeMap","React","useRef","getNode","useCallback","nodeId","current","insertNode","node","id","removeNode","newMap","publishTreeViewEvent","isNodeDisabled","disabled","parentId","getChildrenIds","useEventCallback","Object","values","filter","sort","a","b","index","map","child","getNavigableChildrenIds","childrenIds","disabledItemsFocusable","populateInstance","updateNode"],"mappings":";;;;AAkDO,MAAMA,mBAA8DA,CAAC;AAAA,EAC1EC;AAAAA,EACAC;AACF,MAAM;AACJ,QAAMC,UAAUC,MAAMC,OAA2C,CAAE,CAAA;AAE7DC,QAAAA,UAAUF,MAAMG,YACpB,CAACC,WAAmBL,QAAQM,QAAQD,MAAM,GAC1C,CAAA,CACF;AAEA,QAAME,aAAaN,MAAMG,YAAY,CAACI,SAAuB;AACnDF,YAAAA,QAAQE,KAAKC,EAAE,IAAID;AAAAA,EAC7B,GAAG,CAAE,CAAA;AAEL,QAAME,aAAaT,MAAMG,YACvB,CAACC,WAAmB;AAClB,UAAMM,SAAS;AAAA,MAAE,GAAGX,QAAQM;AAAAA,IAAAA;AAC5B,WAAOK,OAAON,MAAM;AACpBL,YAAQM,UAAUK;AAClBC,yBAAqBd,UAAiB,cAAc;AAAA,MAAEW,IAAIJ;AAAAA,IAAAA,CAAQ;AAAA,EAAA,GAEpE,CAACP,QAAQ,CACX;AAEA,QAAMe,iBAAiBZ,MAAMG,YAC3B,CAACC,WAA4C;AAC3C,QAAIA,UAAU,MAAM;AACX,aAAA;AAAA,IACT;AAEIG,QAAAA,OAAOV,SAASK,QAAQE,MAAM;AAGlC,QAAI,CAACG,MAAM;AACF,aAAA;AAAA,IACT;AAEA,QAAIA,KAAKM,UAAU;AACV,aAAA;AAAA,IACT;AAEON,WAAAA,KAAKO,YAAY,MAAM;AACrBjB,aAAAA,SAASK,QAAQK,KAAKO,QAAQ;AACrC,UAAIP,KAAKM,UAAU;AACV,eAAA;AAAA,MACT;AAAA,IACF;AAEO,WAAA;AAAA,EAAA,GAET,CAAChB,QAAQ,CACX;AAEA,QAAMkB,iBAAiBC,iBAAiB,CAACZ,WACvCa,OAAOC,OAAOnB,QAAQM,OAAO,EAC1Bc,OAAQZ,CAASA,SAAAA,KAAKO,aAAaV,MAAM,EACzCgB,KAAK,CAACC,GAAGC,MAAMD,EAAEE,QAAQD,EAAEC,KAAK,EAChCC,IAAKC,CAAAA,UAAUA,MAAMjB,EAAE,CAC5B;AAEMkB,QAAAA,0BAA0BA,CAACtB,WAA0B;AACrDuB,QAAAA,cAAc9B,SAASkB,eAAeX,MAAM;AAE5C,QAAA,CAACN,OAAO8B,wBAAwB;AAClCD,oBAAcA,YAAYR,OACvBZ,CAAAA,SAAS,CAACV,SAASe,eAAeL,IAAI,CACzC;AAAA,IACF;AACOoB,WAAAA;AAAAA,EAAAA;AAGTE,mBAA4ChC,UAAU;AAAA,IACpDK;AAAAA,IACA4B,YAAYxB;AAAAA,IACZG;AAAAA,IACAM;AAAAA,IACAW;AAAAA,IACAd;AAAAA,EAAAA,CACD;AACH;"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { populateInstance, getFirstNode, getLastNode, getNextNode } from "../utils.js";
|
|
3
|
+
const findOrderInTremauxTree = (instance, nodeAId, nodeBId) => {
|
|
4
|
+
if (nodeAId === nodeBId) {
|
|
5
|
+
return [nodeAId, nodeBId];
|
|
6
|
+
}
|
|
7
|
+
const nodeA = instance.getNode(nodeAId);
|
|
8
|
+
const nodeB = instance.getNode(nodeBId);
|
|
9
|
+
if (nodeA.parentId === nodeB.id || nodeB.parentId === nodeA.id) {
|
|
10
|
+
return nodeB.parentId === nodeA.id ? [nodeA.id, nodeB.id] : [nodeB.id, nodeA.id];
|
|
11
|
+
}
|
|
12
|
+
const aFamily = [nodeA.id];
|
|
13
|
+
const bFamily = [nodeB.id];
|
|
14
|
+
let aAncestor = nodeA.parentId;
|
|
15
|
+
let bAncestor = nodeB.parentId;
|
|
16
|
+
let aAncestorIsCommon = bFamily.indexOf(aAncestor) !== -1;
|
|
17
|
+
let bAncestorIsCommon = aFamily.indexOf(bAncestor) !== -1;
|
|
18
|
+
let continueA = true;
|
|
19
|
+
let continueB = true;
|
|
20
|
+
while (!bAncestorIsCommon && !aAncestorIsCommon) {
|
|
21
|
+
if (continueA) {
|
|
22
|
+
aFamily.push(aAncestor);
|
|
23
|
+
aAncestorIsCommon = bFamily.indexOf(aAncestor) !== -1;
|
|
24
|
+
continueA = aAncestor !== null;
|
|
25
|
+
if (!aAncestorIsCommon && continueA) {
|
|
26
|
+
aAncestor = instance.getNode(aAncestor).parentId;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (continueB && !aAncestorIsCommon) {
|
|
30
|
+
bFamily.push(bAncestor);
|
|
31
|
+
bAncestorIsCommon = aFamily.indexOf(bAncestor) !== -1;
|
|
32
|
+
continueB = bAncestor !== null;
|
|
33
|
+
if (!bAncestorIsCommon && continueB) {
|
|
34
|
+
bAncestor = instance.getNode(bAncestor).parentId;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const commonAncestor = aAncestorIsCommon ? aAncestor : bAncestor;
|
|
39
|
+
const ancestorFamily = instance.getChildrenIds(commonAncestor);
|
|
40
|
+
const aSide = aFamily[aFamily.indexOf(commonAncestor) - 1];
|
|
41
|
+
const bSide = bFamily[bFamily.indexOf(commonAncestor) - 1];
|
|
42
|
+
return ancestorFamily.indexOf(aSide) < ancestorFamily.indexOf(bSide) ? [nodeAId, nodeBId] : [nodeBId, nodeAId];
|
|
43
|
+
};
|
|
44
|
+
const useTreeViewSelection = ({
|
|
45
|
+
instance,
|
|
46
|
+
params,
|
|
47
|
+
models
|
|
48
|
+
}) => {
|
|
49
|
+
const lastSelectedNode = React.useRef(null);
|
|
50
|
+
const lastSelectionWasRange = React.useRef(false);
|
|
51
|
+
const currentRangeSelection = React.useRef([]);
|
|
52
|
+
const isNodeSelected = (nodeId) => Array.isArray(models.selected.value) ? models.selected.value.indexOf(nodeId) !== -1 : models.selected.value === nodeId;
|
|
53
|
+
const selectNode = (event, nodeId, multiple = false) => {
|
|
54
|
+
if (params.disableSelection) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (multiple) {
|
|
58
|
+
if (Array.isArray(models.selected.value)) {
|
|
59
|
+
let newSelected;
|
|
60
|
+
if (models.selected.value.indexOf(nodeId) !== -1) {
|
|
61
|
+
newSelected = models.selected.value.filter((id) => id !== nodeId);
|
|
62
|
+
} else {
|
|
63
|
+
newSelected = [nodeId].concat(models.selected.value);
|
|
64
|
+
}
|
|
65
|
+
if (params.onNodeSelect) {
|
|
66
|
+
params.onNodeSelect(event, newSelected);
|
|
67
|
+
}
|
|
68
|
+
models.selected.setValue(newSelected);
|
|
69
|
+
}
|
|
70
|
+
} else {
|
|
71
|
+
const newSelected = params.multiSelect ? [nodeId] : nodeId;
|
|
72
|
+
if (params.onNodeSelect) {
|
|
73
|
+
params.onNodeSelect(event, newSelected);
|
|
74
|
+
}
|
|
75
|
+
models.selected.setValue(newSelected);
|
|
76
|
+
}
|
|
77
|
+
lastSelectedNode.current = nodeId;
|
|
78
|
+
lastSelectionWasRange.current = false;
|
|
79
|
+
currentRangeSelection.current = [];
|
|
80
|
+
};
|
|
81
|
+
const getNodesInRange = (nodeAId, nodeBId) => {
|
|
82
|
+
const [first, last] = findOrderInTremauxTree(instance, nodeAId, nodeBId);
|
|
83
|
+
const nodes = [first];
|
|
84
|
+
let current = first;
|
|
85
|
+
while (current !== last) {
|
|
86
|
+
current = getNextNode(instance, current);
|
|
87
|
+
nodes.push(current);
|
|
88
|
+
}
|
|
89
|
+
return nodes;
|
|
90
|
+
};
|
|
91
|
+
const handleRangeArrowSelect = (event, nodes) => {
|
|
92
|
+
let base = models.selected.value.slice();
|
|
93
|
+
const {
|
|
94
|
+
start,
|
|
95
|
+
next,
|
|
96
|
+
current
|
|
97
|
+
} = nodes;
|
|
98
|
+
if (!next || !current) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (currentRangeSelection.current.indexOf(current) === -1) {
|
|
102
|
+
currentRangeSelection.current = [];
|
|
103
|
+
}
|
|
104
|
+
if (lastSelectionWasRange.current) {
|
|
105
|
+
if (currentRangeSelection.current.indexOf(next) !== -1) {
|
|
106
|
+
base = base.filter((id) => id === start || id !== current);
|
|
107
|
+
currentRangeSelection.current = currentRangeSelection.current.filter((id) => id === start || id !== current);
|
|
108
|
+
} else {
|
|
109
|
+
base.push(next);
|
|
110
|
+
currentRangeSelection.current.push(next);
|
|
111
|
+
}
|
|
112
|
+
} else {
|
|
113
|
+
base.push(next);
|
|
114
|
+
currentRangeSelection.current.push(current, next);
|
|
115
|
+
}
|
|
116
|
+
if (params.onNodeSelect) {
|
|
117
|
+
params.onNodeSelect(event, base);
|
|
118
|
+
}
|
|
119
|
+
models.selected.setValue(base);
|
|
120
|
+
};
|
|
121
|
+
const handleRangeSelect = (event, nodes) => {
|
|
122
|
+
let base = models.selected.value.slice();
|
|
123
|
+
const {
|
|
124
|
+
start,
|
|
125
|
+
end
|
|
126
|
+
} = nodes;
|
|
127
|
+
if (lastSelectionWasRange.current) {
|
|
128
|
+
base = base.filter((id) => currentRangeSelection.current.indexOf(id) === -1);
|
|
129
|
+
}
|
|
130
|
+
let range = getNodesInRange(start, end);
|
|
131
|
+
range = range.filter((node) => !instance.isNodeDisabled(node));
|
|
132
|
+
currentRangeSelection.current = range;
|
|
133
|
+
let newSelected = base.concat(range);
|
|
134
|
+
newSelected = newSelected.filter((id, i) => newSelected.indexOf(id) === i);
|
|
135
|
+
if (params.onNodeSelect) {
|
|
136
|
+
params.onNodeSelect(event, newSelected);
|
|
137
|
+
}
|
|
138
|
+
models.selected.setValue(newSelected);
|
|
139
|
+
};
|
|
140
|
+
const selectRange = (event, nodes, stacked = false) => {
|
|
141
|
+
if (params.disableSelection) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const {
|
|
145
|
+
start = lastSelectedNode.current,
|
|
146
|
+
end,
|
|
147
|
+
current
|
|
148
|
+
} = nodes;
|
|
149
|
+
if (stacked) {
|
|
150
|
+
handleRangeArrowSelect(event, {
|
|
151
|
+
start,
|
|
152
|
+
next: end,
|
|
153
|
+
current
|
|
154
|
+
});
|
|
155
|
+
} else if (start != null && end != null) {
|
|
156
|
+
handleRangeSelect(event, {
|
|
157
|
+
start,
|
|
158
|
+
end
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
lastSelectionWasRange.current = true;
|
|
162
|
+
};
|
|
163
|
+
const rangeSelectToFirst = (event, nodeId) => {
|
|
164
|
+
if (!lastSelectedNode.current) {
|
|
165
|
+
lastSelectedNode.current = nodeId;
|
|
166
|
+
}
|
|
167
|
+
const start = lastSelectionWasRange.current ? lastSelectedNode.current : nodeId;
|
|
168
|
+
instance.selectRange(event, {
|
|
169
|
+
start,
|
|
170
|
+
end: getFirstNode(instance)
|
|
171
|
+
});
|
|
172
|
+
};
|
|
173
|
+
const rangeSelectToLast = (event, nodeId) => {
|
|
174
|
+
if (!lastSelectedNode.current) {
|
|
175
|
+
lastSelectedNode.current = nodeId;
|
|
176
|
+
}
|
|
177
|
+
const start = lastSelectionWasRange.current ? lastSelectedNode.current : nodeId;
|
|
178
|
+
instance.selectRange(event, {
|
|
179
|
+
start,
|
|
180
|
+
end: getLastNode(instance)
|
|
181
|
+
});
|
|
182
|
+
};
|
|
183
|
+
populateInstance(instance, {
|
|
184
|
+
isNodeSelected,
|
|
185
|
+
selectNode,
|
|
186
|
+
selectRange,
|
|
187
|
+
rangeSelectToLast,
|
|
188
|
+
rangeSelectToFirst
|
|
189
|
+
});
|
|
190
|
+
return {
|
|
191
|
+
getRootProps: () => ({
|
|
192
|
+
"aria-multiselectable": params.multiSelect
|
|
193
|
+
})
|
|
194
|
+
};
|
|
195
|
+
};
|
|
196
|
+
useTreeViewSelection.models = {
|
|
197
|
+
selected: {
|
|
198
|
+
controlledProp: "selected",
|
|
199
|
+
defaultProp: "defaultSelected"
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
const DEFAULT_SELECTED = [];
|
|
203
|
+
useTreeViewSelection.getDefaultizedParams = (params) => ({
|
|
204
|
+
...params,
|
|
205
|
+
disableSelection: params.disableSelection ?? false,
|
|
206
|
+
multiSelect: params.multiSelect ?? false,
|
|
207
|
+
defaultSelected: params.defaultSelected ?? (params.multiSelect ? DEFAULT_SELECTED : null)
|
|
208
|
+
});
|
|
209
|
+
export {
|
|
210
|
+
findOrderInTremauxTree,
|
|
211
|
+
useTreeViewSelection
|
|
212
|
+
};
|
|
213
|
+
//# sourceMappingURL=useTreeViewSelection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTreeViewSelection.js","sources":["../../../../../../../src/components/TreeView/internals/hooks/plugins/useTreeViewSelection.ts"],"sourcesContent":["import * as React from \"react\";\n\nimport type {\n TreeViewPlugin,\n TreeViewItemRange,\n DefaultizedProps,\n TreeViewPluginSignature,\n TreeViewInstance,\n} from \"../../types\";\nimport {\n populateInstance,\n getNextNode,\n getFirstNode,\n getLastNode,\n} from \"../utils\";\nimport type { UseTreeViewNodesSignature } from \"./useTreeViewNodes\";\nimport type { UseTreeViewExpansionSignature } from \"./useTreeViewExpansion\";\n\n/**\n * This is used to determine the start and end of a selection range so\n * we can get the nodes between the two border nodes.\n *\n * It finds the nodes' common ancestor using\n * a naive implementation of a lowest common ancestor algorithm\n * (https://en.wikipedia.org/wiki/Lowest_common_ancestor).\n * Then compares the ancestor's 2 children that are ancestors of nodeA and NodeB\n * so we can compare their indexes to work out which node comes first in a depth first search.\n * (https://en.wikipedia.org/wiki/Depth-first_search)\n *\n * Another way to put it is which node is shallower in a trémaux tree\n * https://en.wikipedia.org/wiki/Tr%C3%A9maux_tree\n */\nexport const findOrderInTremauxTree = (\n instance: TreeViewInstance<[UseTreeViewNodesSignature]>,\n nodeAId: string,\n nodeBId: string\n) => {\n if (nodeAId === nodeBId) {\n return [nodeAId, nodeBId];\n }\n\n const nodeA = instance.getNode(nodeAId);\n const nodeB = instance.getNode(nodeBId);\n\n if (nodeA.parentId === nodeB.id || nodeB.parentId === nodeA.id) {\n return nodeB.parentId === nodeA.id\n ? [nodeA.id, nodeB.id]\n : [nodeB.id, nodeA.id];\n }\n\n const aFamily: (string | null)[] = [nodeA.id];\n const bFamily: (string | null)[] = [nodeB.id];\n\n let aAncestor = nodeA.parentId;\n let bAncestor = nodeB.parentId;\n\n let aAncestorIsCommon = bFamily.indexOf(aAncestor) !== -1;\n let bAncestorIsCommon = aFamily.indexOf(bAncestor) !== -1;\n\n let continueA = true;\n let continueB = true;\n\n while (!bAncestorIsCommon && !aAncestorIsCommon) {\n if (continueA) {\n aFamily.push(aAncestor);\n aAncestorIsCommon = bFamily.indexOf(aAncestor) !== -1;\n continueA = aAncestor !== null;\n if (!aAncestorIsCommon && continueA) {\n aAncestor = instance.getNode(aAncestor!).parentId;\n }\n }\n\n if (continueB && !aAncestorIsCommon) {\n bFamily.push(bAncestor);\n bAncestorIsCommon = aFamily.indexOf(bAncestor) !== -1;\n continueB = bAncestor !== null;\n if (!bAncestorIsCommon && continueB) {\n bAncestor = instance.getNode(bAncestor!).parentId;\n }\n }\n }\n\n const commonAncestor = aAncestorIsCommon ? aAncestor : bAncestor;\n const ancestorFamily = instance.getChildrenIds(commonAncestor);\n\n const aSide = aFamily[aFamily.indexOf(commonAncestor) - 1];\n const bSide = bFamily[bFamily.indexOf(commonAncestor) - 1];\n\n return ancestorFamily.indexOf(aSide!) < ancestorFamily.indexOf(bSide!)\n ? [nodeAId, nodeBId]\n : [nodeBId, nodeAId];\n};\n\nexport interface UseTreeViewSelectionInstance {\n isNodeSelected: (nodeId: string) => boolean;\n selectNode: (\n event: React.SyntheticEvent,\n nodeId: string,\n multiple?: boolean\n ) => void;\n selectRange: (\n event: React.SyntheticEvent,\n nodes: TreeViewItemRange,\n stacked?: boolean\n ) => void;\n rangeSelectToFirst: (\n event: React.KeyboardEvent<HTMLUListElement>,\n nodeId: string\n ) => void;\n rangeSelectToLast: (\n event: React.KeyboardEvent<HTMLUListElement>,\n nodeId: string\n ) => void;\n}\n\ntype TreeViewSelectionValue<Multiple extends boolean | undefined> =\n Multiple extends true ? string[] : string | null;\n\nexport interface UseTreeViewSelectionParameters<\n Multiple extends boolean | undefined\n> {\n /**\n * If `true` selection is disabled.\n * @default false\n */\n disableSelection?: boolean;\n /**\n * Selected node ids. (Uncontrolled)\n * When `multiSelect` is true this takes an array of strings; when false (default) a string.\n * @default []\n */\n defaultSelected?: TreeViewSelectionValue<Multiple>;\n /**\n * Selected node ids. (Controlled)\n * When `multiSelect` is true this takes an array of strings; when false (default) a string.\n */\n selected?: TreeViewSelectionValue<Multiple>;\n /**\n * If true `ctrl` and `shift` will trigger multiselect.\n * @default false\n */\n multiSelect?: Multiple;\n /**\n * Callback fired when tree items are selected/unselected.\n * @param {React.SyntheticEvent} event The event source of the callback\n * @param {string[] | string} nodeIds Ids of the selected nodes. When `multiSelect` is true\n * this is an array of strings; when false (default) a string.\n */\n onNodeSelect?: (\n event: React.SyntheticEvent,\n nodeIds: Exclude<TreeViewSelectionValue<Multiple>, null>\n ) => void;\n}\n\nexport type UseTreeViewSelectionDefaultizedParameters<\n Multiple extends boolean\n> = DefaultizedProps<\n UseTreeViewSelectionParameters<Multiple>,\n \"disableSelection\" | \"defaultSelected\" | \"multiSelect\"\n>;\n\nexport type UseTreeViewSelectionSignature<\n Multiple extends boolean | undefined\n> = TreeViewPluginSignature<\n UseTreeViewSelectionParameters<Multiple>,\n UseTreeViewSelectionDefaultizedParameters<\n Multiple extends undefined ? false : Multiple\n >,\n UseTreeViewSelectionInstance,\n {},\n {},\n \"selected\",\n [\n UseTreeViewNodesSignature,\n UseTreeViewExpansionSignature,\n UseTreeViewNodesSignature\n ]\n>;\n\nexport const useTreeViewSelection: TreeViewPlugin<\n UseTreeViewSelectionSignature<any>\n> = ({ instance, params, models }) => {\n const lastSelectedNode = React.useRef<string | null>(null);\n const lastSelectionWasRange = React.useRef(false);\n const currentRangeSelection = React.useRef<string[]>([]);\n\n const isNodeSelected = (nodeId: string) =>\n Array.isArray(models.selected.value)\n ? models.selected.value.indexOf(nodeId) !== -1\n : models.selected.value === nodeId;\n\n const selectNode = (\n event: React.SyntheticEvent,\n nodeId: string,\n multiple = false\n ) => {\n if (params.disableSelection) {\n return;\n }\n\n if (multiple) {\n if (Array.isArray(models.selected.value)) {\n let newSelected: string[];\n if (models.selected.value.indexOf(nodeId) !== -1) {\n newSelected = models.selected.value.filter((id) => id !== nodeId);\n } else {\n newSelected = [nodeId].concat(models.selected.value);\n }\n\n if (params.onNodeSelect) {\n (params.onNodeSelect as UseTreeViewSelectionDefaultizedParameters<true>[\"onNodeSelect\"])!(\n event,\n newSelected\n );\n }\n\n models.selected.setValue(newSelected);\n }\n } else {\n const newSelected = params.multiSelect ? [nodeId] : nodeId;\n\n if (params.onNodeSelect) {\n params.onNodeSelect(event, newSelected as string & string[]);\n }\n\n models.selected.setValue(newSelected);\n }\n lastSelectedNode.current = nodeId;\n lastSelectionWasRange.current = false;\n currentRangeSelection.current = [];\n };\n\n const getNodesInRange = (nodeAId: string, nodeBId: string) => {\n const [first, last] = findOrderInTremauxTree(instance, nodeAId, nodeBId);\n const nodes = [first];\n\n let current = first;\n\n while (current !== last) {\n current = getNextNode(instance, current)!;\n nodes.push(current);\n }\n\n return nodes;\n };\n\n const handleRangeArrowSelect = (\n event: React.SyntheticEvent,\n nodes: TreeViewItemRange\n ) => {\n let base = (models.selected.value as string[]).slice();\n const { start, next, current } = nodes;\n\n if (!next || !current) {\n return;\n }\n\n if (currentRangeSelection.current.indexOf(current) === -1) {\n currentRangeSelection.current = [];\n }\n\n if (lastSelectionWasRange.current) {\n if (currentRangeSelection.current.indexOf(next) !== -1) {\n base = base.filter((id) => id === start || id !== current);\n currentRangeSelection.current = currentRangeSelection.current.filter(\n (id) => id === start || id !== current\n );\n } else {\n base.push(next);\n currentRangeSelection.current.push(next);\n }\n } else {\n base.push(next);\n currentRangeSelection.current.push(current, next);\n }\n\n if (params.onNodeSelect) {\n (params.onNodeSelect as UseTreeViewSelectionDefaultizedParameters<true>[\"onNodeSelect\"])!(\n event,\n base\n );\n }\n\n models.selected.setValue(base);\n };\n\n const handleRangeSelect = (\n event: React.SyntheticEvent,\n nodes: { start: string; end: string }\n ) => {\n let base = (models.selected.value as string[]).slice();\n const { start, end } = nodes;\n // If last selection was a range selection ignore nodes that were selected.\n if (lastSelectionWasRange.current) {\n base = base.filter(\n (id) => currentRangeSelection.current.indexOf(id) === -1\n );\n }\n\n let range = getNodesInRange(start, end);\n range = range.filter((node) => !instance.isNodeDisabled(node));\n currentRangeSelection.current = range;\n let newSelected = base.concat(range);\n newSelected = newSelected.filter((id, i) => newSelected.indexOf(id) === i);\n\n if (params.onNodeSelect) {\n (params.onNodeSelect as UseTreeViewSelectionDefaultizedParameters<true>[\"onNodeSelect\"])!(\n event,\n newSelected\n );\n }\n\n models.selected.setValue(newSelected);\n };\n\n const selectRange = (\n event: React.SyntheticEvent,\n nodes: TreeViewItemRange,\n stacked = false\n ) => {\n if (params.disableSelection) {\n return;\n }\n\n const { start = lastSelectedNode.current, end, current } = nodes;\n if (stacked) {\n handleRangeArrowSelect(event, { start, next: end, current });\n } else if (start != null && end != null) {\n handleRangeSelect(event, { start, end });\n }\n lastSelectionWasRange.current = true;\n };\n\n const rangeSelectToFirst = (\n event: React.KeyboardEvent<HTMLUListElement>,\n nodeId: string\n ) => {\n if (!lastSelectedNode.current) {\n lastSelectedNode.current = nodeId;\n }\n\n const start = lastSelectionWasRange.current\n ? lastSelectedNode.current\n : nodeId;\n\n instance.selectRange(event, {\n start,\n end: getFirstNode(instance),\n });\n };\n\n const rangeSelectToLast = (\n event: React.KeyboardEvent<HTMLUListElement>,\n nodeId: string\n ) => {\n if (!lastSelectedNode.current) {\n lastSelectedNode.current = nodeId;\n }\n\n const start = lastSelectionWasRange.current\n ? lastSelectedNode.current\n : nodeId;\n\n instance.selectRange(event, {\n start,\n end: getLastNode(instance),\n });\n };\n\n populateInstance<UseTreeViewSelectionSignature<any>>(instance, {\n isNodeSelected,\n selectNode,\n selectRange,\n rangeSelectToLast,\n rangeSelectToFirst,\n });\n\n return {\n getRootProps: () => ({\n \"aria-multiselectable\": params.multiSelect,\n }),\n };\n};\n\nuseTreeViewSelection.models = {\n selected: { controlledProp: \"selected\", defaultProp: \"defaultSelected\" },\n};\n\nconst DEFAULT_SELECTED: string[] = [];\n\nuseTreeViewSelection.getDefaultizedParams = (params) => ({\n ...params,\n disableSelection: params.disableSelection ?? false,\n multiSelect: params.multiSelect ?? false,\n defaultSelected:\n params.defaultSelected ?? (params.multiSelect ? DEFAULT_SELECTED : null),\n});\n"],"names":["findOrderInTremauxTree","instance","nodeAId","nodeBId","nodeA","getNode","nodeB","parentId","id","aFamily","bFamily","aAncestor","bAncestor","aAncestorIsCommon","indexOf","bAncestorIsCommon","continueA","continueB","push","commonAncestor","ancestorFamily","getChildrenIds","aSide","bSide","useTreeViewSelection","params","models","lastSelectedNode","React","useRef","lastSelectionWasRange","currentRangeSelection","isNodeSelected","nodeId","Array","isArray","selected","value","selectNode","event","multiple","disableSelection","newSelected","filter","concat","onNodeSelect","setValue","multiSelect","current","getNodesInRange","first","last","nodes","getNextNode","handleRangeArrowSelect","base","slice","start","next","handleRangeSelect","end","range","node","isNodeDisabled","i","selectRange","stacked","rangeSelectToFirst","getFirstNode","rangeSelectToLast","getLastNode","populateInstance","getRootProps","controlledProp","defaultProp","DEFAULT_SELECTED","getDefaultizedParams","defaultSelected"],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { TimerBasedCleanupTracking } from "../utils/TimerBasedCleanupTracking.js";
|
|
3
|
+
import { FinalizationRegistryBasedCleanupTracking } from "../utils/FinalizationRegistryBasedCleanupTracking.js";
|
|
4
|
+
class ObjectToBeRetainedByReact {
|
|
5
|
+
}
|
|
6
|
+
function createUseInstanceEventHandler(registryContainer2) {
|
|
7
|
+
let cleanupTokensCounter = 0;
|
|
8
|
+
return function useInstanceEventHandler2(instance, eventName, handler) {
|
|
9
|
+
if (registryContainer2.registry === null) {
|
|
10
|
+
registryContainer2.registry = typeof FinalizationRegistry !== "undefined" ? new FinalizationRegistryBasedCleanupTracking() : new TimerBasedCleanupTracking();
|
|
11
|
+
}
|
|
12
|
+
const [objectRetainedByReact] = React.useState(new ObjectToBeRetainedByReact());
|
|
13
|
+
const subscription = React.useRef(null);
|
|
14
|
+
const handlerRef = React.useRef();
|
|
15
|
+
handlerRef.current = handler;
|
|
16
|
+
const cleanupTokenRef = React.useRef(null);
|
|
17
|
+
if (!subscription.current && handlerRef.current) {
|
|
18
|
+
const enhancedHandler = (params, event) => {
|
|
19
|
+
if (!event.defaultMuiPrevented) {
|
|
20
|
+
handlerRef.current?.(params, event);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
subscription.current = instance.$$subscribeEvent(eventName, enhancedHandler);
|
|
24
|
+
cleanupTokensCounter += 1;
|
|
25
|
+
cleanupTokenRef.current = {
|
|
26
|
+
cleanupToken: cleanupTokensCounter
|
|
27
|
+
};
|
|
28
|
+
registryContainer2.registry.register(
|
|
29
|
+
objectRetainedByReact,
|
|
30
|
+
// The callback below will be called once this reference stops being retained
|
|
31
|
+
() => {
|
|
32
|
+
subscription.current?.();
|
|
33
|
+
subscription.current = null;
|
|
34
|
+
cleanupTokenRef.current = null;
|
|
35
|
+
},
|
|
36
|
+
cleanupTokenRef.current
|
|
37
|
+
);
|
|
38
|
+
} else if (!handlerRef.current && subscription.current) {
|
|
39
|
+
subscription.current();
|
|
40
|
+
subscription.current = null;
|
|
41
|
+
if (cleanupTokenRef.current) {
|
|
42
|
+
registryContainer2.registry.unregister(cleanupTokenRef.current);
|
|
43
|
+
cleanupTokenRef.current = null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
React.useEffect(() => {
|
|
47
|
+
if (!subscription.current && handlerRef.current) {
|
|
48
|
+
const enhancedHandler = (params, event) => {
|
|
49
|
+
if (!event.defaultMuiPrevented) {
|
|
50
|
+
handlerRef.current?.(params, event);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
subscription.current = instance.$$subscribeEvent(eventName, enhancedHandler);
|
|
54
|
+
}
|
|
55
|
+
if (cleanupTokenRef.current && registryContainer2.registry) {
|
|
56
|
+
registryContainer2.registry.unregister(cleanupTokenRef.current);
|
|
57
|
+
cleanupTokenRef.current = null;
|
|
58
|
+
}
|
|
59
|
+
return () => {
|
|
60
|
+
subscription.current?.();
|
|
61
|
+
subscription.current = null;
|
|
62
|
+
};
|
|
63
|
+
}, [instance, eventName]);
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const registryContainer = {
|
|
67
|
+
registry: null
|
|
68
|
+
};
|
|
69
|
+
const useInstanceEventHandler = createUseInstanceEventHandler(registryContainer);
|
|
70
|
+
export {
|
|
71
|
+
createUseInstanceEventHandler,
|
|
72
|
+
useInstanceEventHandler
|
|
73
|
+
};
|
|
74
|
+
//# sourceMappingURL=useInstanceEventHandler.js.map
|