@headless-tree/core 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/index.d.mts +577 -0
  3. package/dist/index.d.ts +577 -0
  4. package/dist/index.js +2321 -0
  5. package/dist/index.mjs +2276 -0
  6. package/package.json +18 -10
  7. package/src/core/create-tree.ts +26 -2
  8. package/src/features/async-data-loader/feature.ts +9 -4
  9. package/src/features/async-data-loader/types.ts +2 -0
  10. package/src/features/checkboxes/checkboxes.spec.ts +149 -0
  11. package/src/features/checkboxes/feature.ts +134 -0
  12. package/src/features/checkboxes/types.ts +29 -0
  13. package/src/features/drag-and-drop/drag-and-drop.spec.ts +11 -2
  14. package/src/features/drag-and-drop/feature.ts +88 -17
  15. package/src/features/drag-and-drop/types.ts +22 -0
  16. package/src/features/keyboard-drag-and-drop/feature.ts +8 -1
  17. package/src/features/keyboard-drag-and-drop/keyboard-drag-and-drop.spec.ts +34 -3
  18. package/src/features/sync-data-loader/feature.ts +5 -1
  19. package/src/features/tree/feature.ts +9 -3
  20. package/src/features/tree/tree.spec.ts +14 -4
  21. package/src/features/tree/types.ts +3 -2
  22. package/src/index.ts +2 -0
  23. package/src/test-utils/test-tree-do.ts +2 -0
  24. package/src/test-utils/test-tree.ts +1 -0
  25. package/src/types/core.ts +2 -0
  26. package/tsconfig.json +1 -4
  27. package/vitest.config.ts +3 -1
  28. package/lib/cjs/core/build-proxified-instance.d.ts +0 -2
  29. package/lib/cjs/core/build-proxified-instance.js +0 -58
  30. package/lib/cjs/core/build-static-instance.d.ts +0 -2
  31. package/lib/cjs/core/build-static-instance.js +0 -26
  32. package/lib/cjs/core/create-tree.d.ts +0 -2
  33. package/lib/cjs/core/create-tree.js +0 -182
  34. package/lib/cjs/features/async-data-loader/feature.d.ts +0 -2
  35. package/lib/cjs/features/async-data-loader/feature.js +0 -135
  36. package/lib/cjs/features/async-data-loader/types.d.ts +0 -47
  37. package/lib/cjs/features/async-data-loader/types.js +0 -2
  38. package/lib/cjs/features/drag-and-drop/feature.d.ts +0 -2
  39. package/lib/cjs/features/drag-and-drop/feature.js +0 -179
  40. package/lib/cjs/features/drag-and-drop/types.d.ts +0 -66
  41. package/lib/cjs/features/drag-and-drop/types.js +0 -9
  42. package/lib/cjs/features/drag-and-drop/utils.d.ts +0 -27
  43. package/lib/cjs/features/drag-and-drop/utils.js +0 -182
  44. package/lib/cjs/features/expand-all/feature.d.ts +0 -2
  45. package/lib/cjs/features/expand-all/feature.js +0 -70
  46. package/lib/cjs/features/expand-all/types.d.ts +0 -19
  47. package/lib/cjs/features/expand-all/types.js +0 -2
  48. package/lib/cjs/features/hotkeys-core/feature.d.ts +0 -2
  49. package/lib/cjs/features/hotkeys-core/feature.js +0 -107
  50. package/lib/cjs/features/hotkeys-core/types.d.ts +0 -27
  51. package/lib/cjs/features/hotkeys-core/types.js +0 -2
  52. package/lib/cjs/features/keyboard-drag-and-drop/feature.d.ts +0 -2
  53. package/lib/cjs/features/keyboard-drag-and-drop/feature.js +0 -206
  54. package/lib/cjs/features/keyboard-drag-and-drop/types.d.ts +0 -27
  55. package/lib/cjs/features/keyboard-drag-and-drop/types.js +0 -11
  56. package/lib/cjs/features/main/types.d.ts +0 -45
  57. package/lib/cjs/features/main/types.js +0 -2
  58. package/lib/cjs/features/prop-memoization/feature.d.ts +0 -2
  59. package/lib/cjs/features/prop-memoization/feature.js +0 -70
  60. package/lib/cjs/features/prop-memoization/types.d.ts +0 -15
  61. package/lib/cjs/features/prop-memoization/types.js +0 -2
  62. package/lib/cjs/features/renaming/feature.d.ts +0 -2
  63. package/lib/cjs/features/renaming/feature.js +0 -86
  64. package/lib/cjs/features/renaming/types.d.ts +0 -27
  65. package/lib/cjs/features/renaming/types.js +0 -2
  66. package/lib/cjs/features/search/feature.d.ts +0 -2
  67. package/lib/cjs/features/search/feature.js +0 -119
  68. package/lib/cjs/features/search/types.d.ts +0 -32
  69. package/lib/cjs/features/search/types.js +0 -2
  70. package/lib/cjs/features/selection/feature.d.ts +0 -2
  71. package/lib/cjs/features/selection/feature.js +0 -132
  72. package/lib/cjs/features/selection/types.d.ts +0 -21
  73. package/lib/cjs/features/selection/types.js +0 -2
  74. package/lib/cjs/features/sync-data-loader/feature.d.ts +0 -2
  75. package/lib/cjs/features/sync-data-loader/feature.js +0 -49
  76. package/lib/cjs/features/sync-data-loader/types.d.ts +0 -28
  77. package/lib/cjs/features/sync-data-loader/types.js +0 -2
  78. package/lib/cjs/features/tree/feature.d.ts +0 -2
  79. package/lib/cjs/features/tree/feature.js +0 -240
  80. package/lib/cjs/features/tree/types.d.ts +0 -62
  81. package/lib/cjs/features/tree/types.js +0 -2
  82. package/lib/cjs/index.d.ts +0 -31
  83. package/lib/cjs/index.js +0 -49
  84. package/lib/cjs/mddocs-entry.d.ts +0 -121
  85. package/lib/cjs/mddocs-entry.js +0 -17
  86. package/lib/cjs/test-utils/test-tree-do.d.ts +0 -23
  87. package/lib/cjs/test-utils/test-tree-do.js +0 -112
  88. package/lib/cjs/test-utils/test-tree-expect.d.ts +0 -17
  89. package/lib/cjs/test-utils/test-tree-expect.js +0 -66
  90. package/lib/cjs/test-utils/test-tree.d.ts +0 -48
  91. package/lib/cjs/test-utils/test-tree.js +0 -207
  92. package/lib/cjs/types/core.d.ts +0 -83
  93. package/lib/cjs/types/core.js +0 -2
  94. package/lib/cjs/types/deep-merge.d.ts +0 -13
  95. package/lib/cjs/types/deep-merge.js +0 -2
  96. package/lib/cjs/utilities/create-on-drop-handler.d.ts +0 -3
  97. package/lib/cjs/utilities/create-on-drop-handler.js +0 -20
  98. package/lib/cjs/utilities/errors.d.ts +0 -2
  99. package/lib/cjs/utilities/errors.js +0 -9
  100. package/lib/cjs/utilities/insert-items-at-target.d.ts +0 -3
  101. package/lib/cjs/utilities/insert-items-at-target.js +0 -40
  102. package/lib/cjs/utilities/remove-items-from-parents.d.ts +0 -2
  103. package/lib/cjs/utilities/remove-items-from-parents.js +0 -32
  104. package/lib/cjs/utils.d.ts +0 -6
  105. package/lib/cjs/utils.js +0 -53
  106. package/lib/esm/core/build-proxified-instance.d.ts +0 -2
  107. package/lib/esm/core/build-proxified-instance.js +0 -54
  108. package/lib/esm/core/build-static-instance.d.ts +0 -2
  109. package/lib/esm/core/build-static-instance.js +0 -22
  110. package/lib/esm/core/create-tree.d.ts +0 -2
  111. package/lib/esm/core/create-tree.js +0 -178
  112. package/lib/esm/features/async-data-loader/feature.d.ts +0 -2
  113. package/lib/esm/features/async-data-loader/feature.js +0 -132
  114. package/lib/esm/features/async-data-loader/types.d.ts +0 -47
  115. package/lib/esm/features/async-data-loader/types.js +0 -1
  116. package/lib/esm/features/drag-and-drop/feature.d.ts +0 -2
  117. package/lib/esm/features/drag-and-drop/feature.js +0 -176
  118. package/lib/esm/features/drag-and-drop/types.d.ts +0 -66
  119. package/lib/esm/features/drag-and-drop/types.js +0 -6
  120. package/lib/esm/features/drag-and-drop/utils.d.ts +0 -27
  121. package/lib/esm/features/drag-and-drop/utils.js +0 -172
  122. package/lib/esm/features/expand-all/feature.d.ts +0 -2
  123. package/lib/esm/features/expand-all/feature.js +0 -67
  124. package/lib/esm/features/expand-all/types.d.ts +0 -19
  125. package/lib/esm/features/expand-all/types.js +0 -1
  126. package/lib/esm/features/hotkeys-core/feature.d.ts +0 -2
  127. package/lib/esm/features/hotkeys-core/feature.js +0 -104
  128. package/lib/esm/features/hotkeys-core/types.d.ts +0 -27
  129. package/lib/esm/features/hotkeys-core/types.js +0 -1
  130. package/lib/esm/features/keyboard-drag-and-drop/feature.d.ts +0 -2
  131. package/lib/esm/features/keyboard-drag-and-drop/feature.js +0 -203
  132. package/lib/esm/features/keyboard-drag-and-drop/types.d.ts +0 -27
  133. package/lib/esm/features/keyboard-drag-and-drop/types.js +0 -8
  134. package/lib/esm/features/main/types.d.ts +0 -45
  135. package/lib/esm/features/main/types.js +0 -1
  136. package/lib/esm/features/prop-memoization/feature.d.ts +0 -2
  137. package/lib/esm/features/prop-memoization/feature.js +0 -67
  138. package/lib/esm/features/prop-memoization/types.d.ts +0 -15
  139. package/lib/esm/features/prop-memoization/types.js +0 -1
  140. package/lib/esm/features/renaming/feature.d.ts +0 -2
  141. package/lib/esm/features/renaming/feature.js +0 -83
  142. package/lib/esm/features/renaming/types.d.ts +0 -27
  143. package/lib/esm/features/renaming/types.js +0 -1
  144. package/lib/esm/features/search/feature.d.ts +0 -2
  145. package/lib/esm/features/search/feature.js +0 -116
  146. package/lib/esm/features/search/types.d.ts +0 -32
  147. package/lib/esm/features/search/types.js +0 -1
  148. package/lib/esm/features/selection/feature.d.ts +0 -2
  149. package/lib/esm/features/selection/feature.js +0 -129
  150. package/lib/esm/features/selection/types.d.ts +0 -21
  151. package/lib/esm/features/selection/types.js +0 -1
  152. package/lib/esm/features/sync-data-loader/feature.d.ts +0 -2
  153. package/lib/esm/features/sync-data-loader/feature.js +0 -46
  154. package/lib/esm/features/sync-data-loader/types.d.ts +0 -28
  155. package/lib/esm/features/sync-data-loader/types.js +0 -1
  156. package/lib/esm/features/tree/feature.d.ts +0 -2
  157. package/lib/esm/features/tree/feature.js +0 -237
  158. package/lib/esm/features/tree/types.d.ts +0 -62
  159. package/lib/esm/features/tree/types.js +0 -1
  160. package/lib/esm/index.d.ts +0 -31
  161. package/lib/esm/index.js +0 -30
  162. package/lib/esm/mddocs-entry.d.ts +0 -121
  163. package/lib/esm/mddocs-entry.js +0 -1
  164. package/lib/esm/test-utils/test-tree-do.d.ts +0 -23
  165. package/lib/esm/test-utils/test-tree-do.js +0 -108
  166. package/lib/esm/test-utils/test-tree-expect.d.ts +0 -17
  167. package/lib/esm/test-utils/test-tree-expect.js +0 -62
  168. package/lib/esm/test-utils/test-tree.d.ts +0 -48
  169. package/lib/esm/test-utils/test-tree.js +0 -203
  170. package/lib/esm/types/core.d.ts +0 -83
  171. package/lib/esm/types/core.js +0 -1
  172. package/lib/esm/types/deep-merge.d.ts +0 -13
  173. package/lib/esm/types/deep-merge.js +0 -1
  174. package/lib/esm/utilities/create-on-drop-handler.d.ts +0 -3
  175. package/lib/esm/utilities/create-on-drop-handler.js +0 -16
  176. package/lib/esm/utilities/errors.d.ts +0 -2
  177. package/lib/esm/utilities/errors.js +0 -4
  178. package/lib/esm/utilities/insert-items-at-target.d.ts +0 -3
  179. package/lib/esm/utilities/insert-items-at-target.js +0 -36
  180. package/lib/esm/utilities/remove-items-from-parents.d.ts +0 -2
  181. package/lib/esm/utilities/remove-items-from-parents.js +0 -28
  182. package/lib/esm/utils.d.ts +0 -6
  183. package/lib/esm/utils.js +0 -46
package/dist/index.mjs ADDED
@@ -0,0 +1,2276 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ var __async = (__this, __arguments, generator) => {
21
+ return new Promise((resolve, reject) => {
22
+ var fulfilled = (value) => {
23
+ try {
24
+ step(generator.next(value));
25
+ } catch (e) {
26
+ reject(e);
27
+ }
28
+ };
29
+ var rejected = (value) => {
30
+ try {
31
+ step(generator.throw(value));
32
+ } catch (e) {
33
+ reject(e);
34
+ }
35
+ };
36
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
37
+ step((generator = generator.apply(__this, __arguments)).next());
38
+ });
39
+ };
40
+
41
+ // src/utils.ts
42
+ var memo = (deps, fn) => {
43
+ let value;
44
+ let oldDeps = null;
45
+ return (...a) => {
46
+ const newDeps = deps(...a);
47
+ if (!value) {
48
+ value = fn(...newDeps);
49
+ oldDeps = newDeps;
50
+ return value;
51
+ }
52
+ const match = oldDeps && oldDeps.length === newDeps.length && !oldDeps.some((dep, i) => dep !== newDeps[i]);
53
+ if (match) {
54
+ return value;
55
+ }
56
+ value = fn(...newDeps);
57
+ oldDeps = newDeps;
58
+ return value;
59
+ };
60
+ };
61
+ function functionalUpdate(updater, input) {
62
+ return typeof updater === "function" ? updater(input) : updater;
63
+ }
64
+ function makeStateUpdater(key, instance) {
65
+ return (updater) => {
66
+ instance.setState((old) => {
67
+ return __spreadProps(__spreadValues({}, old), {
68
+ [key]: functionalUpdate(updater, old[key])
69
+ });
70
+ });
71
+ };
72
+ }
73
+ var poll = (fn, interval = 100, timeout = 1e3) => new Promise((resolve) => {
74
+ let clear;
75
+ const i = setInterval(() => {
76
+ if (fn()) {
77
+ resolve();
78
+ clearInterval(i);
79
+ clearTimeout(clear);
80
+ }
81
+ }, interval);
82
+ clear = setTimeout(() => {
83
+ clearInterval(i);
84
+ }, timeout);
85
+ });
86
+
87
+ // src/utilities/errors.ts
88
+ var prefix = "Headless Tree: ";
89
+ var throwError = (message) => Error(prefix + message);
90
+ var logWarning = (message) => console.warn(prefix + message);
91
+
92
+ // src/features/tree/feature.ts
93
+ var treeFeature = {
94
+ key: "tree",
95
+ getInitialState: (initialState) => __spreadValues({
96
+ expandedItems: [],
97
+ focusedItem: null
98
+ }, initialState),
99
+ getDefaultConfig: (defaultConfig, tree) => __spreadValues({
100
+ setExpandedItems: makeStateUpdater("expandedItems", tree),
101
+ setFocusedItem: makeStateUpdater("focusedItem", tree)
102
+ }, defaultConfig),
103
+ stateHandlerNames: {
104
+ expandedItems: "setExpandedItems",
105
+ focusedItem: "setFocusedItem"
106
+ },
107
+ treeInstance: {
108
+ getItemsMeta: ({ tree }) => {
109
+ const { rootItemId } = tree.getConfig();
110
+ const { expandedItems } = tree.getState();
111
+ const flatItems = [];
112
+ const expandedItemsSet = new Set(expandedItems);
113
+ const recursiveAdd = (itemId, path, level, setSize, posInSet) => {
114
+ var _a;
115
+ if (path.includes(itemId)) {
116
+ logWarning(`Circular reference for ${path.join(".")}`);
117
+ return;
118
+ }
119
+ flatItems.push({
120
+ itemId,
121
+ level,
122
+ index: flatItems.length,
123
+ parentId: path.at(-1),
124
+ setSize,
125
+ posInSet
126
+ });
127
+ if (expandedItemsSet.has(itemId)) {
128
+ const children2 = (_a = tree.retrieveChildrenIds(itemId)) != null ? _a : [];
129
+ let i2 = 0;
130
+ for (const childId of children2) {
131
+ recursiveAdd(
132
+ childId,
133
+ path.concat(itemId),
134
+ level + 1,
135
+ children2.length,
136
+ i2++
137
+ );
138
+ }
139
+ }
140
+ };
141
+ const children = tree.retrieveChildrenIds(rootItemId);
142
+ let i = 0;
143
+ for (const itemId of children) {
144
+ recursiveAdd(itemId, [rootItemId], 0, children.length, i++);
145
+ }
146
+ return flatItems;
147
+ },
148
+ getFocusedItem: ({ tree }) => {
149
+ var _a;
150
+ const focusedItemId = tree.getState().focusedItem;
151
+ return (_a = focusedItemId !== null ? tree.getItemInstance(focusedItemId) : null) != null ? _a : tree.getItems()[0];
152
+ },
153
+ getRootItem: ({ tree }) => {
154
+ const { rootItemId } = tree.getConfig();
155
+ return tree.getItemInstance(rootItemId);
156
+ },
157
+ focusNextItem: ({ tree }) => {
158
+ var _a;
159
+ const focused = tree.getFocusedItem().getItemMeta();
160
+ if (!focused) return;
161
+ const nextIndex = Math.min(focused.index + 1, tree.getItems().length - 1);
162
+ (_a = tree.getItems()[nextIndex]) == null ? void 0 : _a.setFocused();
163
+ },
164
+ focusPreviousItem: ({ tree }) => {
165
+ var _a;
166
+ const focused = tree.getFocusedItem().getItemMeta();
167
+ if (!focused) return;
168
+ const nextIndex = Math.max(focused.index - 1, 0);
169
+ (_a = tree.getItems()[nextIndex]) == null ? void 0 : _a.setFocused();
170
+ },
171
+ updateDomFocus: ({ tree }) => {
172
+ setTimeout(() => __async(null, null, function* () {
173
+ var _a, _b;
174
+ const focusedItem = tree.getFocusedItem();
175
+ (_b = (_a = tree.getConfig()).scrollToItem) == null ? void 0 : _b.call(_a, focusedItem);
176
+ yield poll(() => focusedItem.getElement() !== null, 20);
177
+ const focusedElement = focusedItem.getElement();
178
+ if (!focusedElement) return;
179
+ focusedElement.focus();
180
+ }));
181
+ },
182
+ getContainerProps: ({ prev, tree }, treeLabel) => __spreadProps(__spreadValues({}, prev == null ? void 0 : prev()), {
183
+ role: "tree",
184
+ "aria-label": treeLabel != null ? treeLabel : "",
185
+ ref: tree.registerElement
186
+ }),
187
+ // relevant for hotkeys of this feature
188
+ isSearchOpen: () => false
189
+ },
190
+ itemInstance: {
191
+ scrollTo: (_0, _1) => __async(null, [_0, _1], function* ({ tree, item }, scrollIntoViewArg) {
192
+ var _a, _b, _c;
193
+ (_b = (_a = tree.getConfig()).scrollToItem) == null ? void 0 : _b.call(_a, item);
194
+ yield poll(() => item.getElement() !== null, 20);
195
+ (_c = item.getElement()) == null ? void 0 : _c.scrollIntoView(scrollIntoViewArg);
196
+ }),
197
+ getId: ({ itemId }) => itemId,
198
+ getKey: ({ itemId }) => itemId,
199
+ // TODO apply to all stories to use
200
+ getProps: ({ item, prev }) => {
201
+ const itemMeta = item.getItemMeta();
202
+ return __spreadProps(__spreadValues({}, prev == null ? void 0 : prev()), {
203
+ ref: item.registerElement,
204
+ role: "treeitem",
205
+ "aria-setsize": itemMeta.setSize,
206
+ "aria-posinset": itemMeta.posInSet + 1,
207
+ "aria-selected": "false",
208
+ "aria-label": item.getItemName(),
209
+ "aria-level": itemMeta.level + 1,
210
+ tabIndex: item.isFocused() ? 0 : -1,
211
+ onClick: (e) => {
212
+ item.setFocused();
213
+ item.primaryAction();
214
+ if (e.ctrlKey || e.shiftKey || e.metaKey) {
215
+ return;
216
+ }
217
+ if (!item.isFolder()) {
218
+ return;
219
+ }
220
+ if (item.isExpanded()) {
221
+ item.collapse();
222
+ } else {
223
+ item.expand();
224
+ }
225
+ }
226
+ });
227
+ },
228
+ expand: ({ tree, item, itemId }) => {
229
+ var _a;
230
+ if (!item.isFolder()) {
231
+ return;
232
+ }
233
+ if ((_a = tree.getState().loadingItemChildrens) == null ? void 0 : _a.includes(itemId)) {
234
+ return;
235
+ }
236
+ tree.applySubStateUpdate("expandedItems", (expandedItems) => [
237
+ ...expandedItems,
238
+ itemId
239
+ ]);
240
+ tree.rebuildTree();
241
+ },
242
+ collapse: ({ tree, item, itemId }) => {
243
+ if (!item.isFolder()) {
244
+ return;
245
+ }
246
+ tree.applySubStateUpdate(
247
+ "expandedItems",
248
+ (expandedItems) => expandedItems.filter((id) => id !== itemId)
249
+ );
250
+ tree.rebuildTree();
251
+ },
252
+ getItemData: ({ tree, itemId }) => tree.retrieveItemData(itemId),
253
+ equals: ({ item }, other) => item.getId() === (other == null ? void 0 : other.getId()),
254
+ isExpanded: ({ tree, itemId }) => tree.getState().expandedItems.includes(itemId),
255
+ isDescendentOf: ({ item }, parentId) => {
256
+ const parent = item.getParent();
257
+ return Boolean(
258
+ (parent == null ? void 0 : parent.getId()) === parentId || (parent == null ? void 0 : parent.isDescendentOf(parentId))
259
+ );
260
+ },
261
+ isFocused: ({ tree, item, itemId }) => tree.getState().focusedItem === itemId || tree.getState().focusedItem === null && item.getItemMeta().index === 0,
262
+ isFolder: ({ tree, item }) => item.getItemMeta().level === -1 || tree.getConfig().isItemFolder(item),
263
+ getItemName: ({ tree, item }) => {
264
+ const config = tree.getConfig();
265
+ return config.getItemName(item);
266
+ },
267
+ setFocused: ({ tree, itemId }) => {
268
+ tree.applySubStateUpdate("focusedItem", itemId);
269
+ },
270
+ primaryAction: ({ tree, item }) => {
271
+ var _a, _b;
272
+ return (_b = (_a = tree.getConfig()).onPrimaryAction) == null ? void 0 : _b.call(_a, item);
273
+ },
274
+ getParent: ({ tree, item }) => item.getItemMeta().parentId ? tree.getItemInstance(item.getItemMeta().parentId) : void 0,
275
+ getIndexInParent: ({ item }) => item.getItemMeta().posInSet,
276
+ getChildren: ({ tree, itemId }) => tree.retrieveChildrenIds(itemId).map((id) => tree.getItemInstance(id)),
277
+ getTree: ({ tree }) => tree,
278
+ getItemAbove: ({ tree, item }) => tree.getItems()[item.getItemMeta().index - 1],
279
+ getItemBelow: ({ tree, item }) => tree.getItems()[item.getItemMeta().index + 1]
280
+ },
281
+ hotkeys: {
282
+ focusNextItem: {
283
+ hotkey: "ArrowDown",
284
+ canRepeat: true,
285
+ preventDefault: true,
286
+ isEnabled: (tree) => {
287
+ var _a, _b;
288
+ return !((_b = (_a = tree.isSearchOpen) == null ? void 0 : _a.call(tree)) != null ? _b : false) && !tree.getState().dnd;
289
+ },
290
+ // TODO what happens when the feature doesnt exist? proxy method still claims to exist
291
+ handler: (e, tree) => {
292
+ tree.focusNextItem();
293
+ tree.updateDomFocus();
294
+ }
295
+ },
296
+ focusPreviousItem: {
297
+ hotkey: "ArrowUp",
298
+ canRepeat: true,
299
+ preventDefault: true,
300
+ isEnabled: (tree) => {
301
+ var _a, _b;
302
+ return !((_b = (_a = tree.isSearchOpen) == null ? void 0 : _a.call(tree)) != null ? _b : false) && !tree.getState().dnd;
303
+ },
304
+ handler: (e, tree) => {
305
+ tree.focusPreviousItem();
306
+ tree.updateDomFocus();
307
+ }
308
+ },
309
+ expandOrDown: {
310
+ hotkey: "ArrowRight",
311
+ canRepeat: true,
312
+ handler: (e, tree) => {
313
+ const item = tree.getFocusedItem();
314
+ if (item.isExpanded() || !item.isFolder()) {
315
+ tree.focusNextItem();
316
+ tree.updateDomFocus();
317
+ } else {
318
+ item.expand();
319
+ }
320
+ }
321
+ },
322
+ collapseOrUp: {
323
+ hotkey: "ArrowLeft",
324
+ canRepeat: true,
325
+ handler: (e, tree) => {
326
+ var _a;
327
+ const item = tree.getFocusedItem();
328
+ if ((!item.isExpanded() || !item.isFolder()) && item.getItemMeta().level !== 0) {
329
+ (_a = item.getParent()) == null ? void 0 : _a.setFocused();
330
+ tree.updateDomFocus();
331
+ } else {
332
+ item.collapse();
333
+ }
334
+ }
335
+ },
336
+ focusFirstItem: {
337
+ hotkey: "Home",
338
+ handler: (e, tree) => {
339
+ var _a;
340
+ (_a = tree.getItems()[0]) == null ? void 0 : _a.setFocused();
341
+ tree.updateDomFocus();
342
+ }
343
+ },
344
+ focusLastItem: {
345
+ hotkey: "End",
346
+ handler: (e, tree) => {
347
+ var _a;
348
+ (_a = tree.getItems()[tree.getItems().length - 1]) == null ? void 0 : _a.setFocused();
349
+ tree.updateDomFocus();
350
+ }
351
+ }
352
+ }
353
+ };
354
+
355
+ // src/core/build-static-instance.ts
356
+ var buildStaticInstance = (features, instanceType, buildOpts) => {
357
+ const instance = {};
358
+ const finalize = () => {
359
+ const opts = buildOpts(instance);
360
+ featureLoop: for (let i = 0; i < features.length; i++) {
361
+ const definition = features[i][instanceType];
362
+ if (!definition) continue featureLoop;
363
+ methodLoop: for (const [key, method] of Object.entries(definition)) {
364
+ if (!method) continue methodLoop;
365
+ const prev = instance[key];
366
+ instance[key] = (...args) => {
367
+ return method(__spreadProps(__spreadValues({}, opts), { prev }), ...args);
368
+ };
369
+ }
370
+ }
371
+ };
372
+ return [instance, finalize];
373
+ };
374
+
375
+ // src/core/create-tree.ts
376
+ var verifyFeatures = (features) => {
377
+ var _a;
378
+ const loadedFeatures = features == null ? void 0 : features.map((feature) => feature.key);
379
+ for (const feature of features != null ? features : []) {
380
+ const missingDependency = (_a = feature.deps) == null ? void 0 : _a.find(
381
+ (dep) => !(loadedFeatures == null ? void 0 : loadedFeatures.includes(dep))
382
+ );
383
+ if (missingDependency) {
384
+ throw throwError(`${feature.key} needs ${missingDependency}`);
385
+ }
386
+ }
387
+ };
388
+ var exhaustiveSort = (arr, compareFn) => {
389
+ const n = arr.length;
390
+ for (let i = 0; i < n; i++) {
391
+ for (let j = i + 1; j < n; j++) {
392
+ if (compareFn(arr[j], arr[i]) < 0) {
393
+ [arr[i], arr[j]] = [arr[j], arr[i]];
394
+ }
395
+ }
396
+ }
397
+ return arr;
398
+ };
399
+ var compareFeatures = (originalOrder) => (feature1, feature2) => {
400
+ var _a, _b;
401
+ if (feature2.key && ((_a = feature1.overwrites) == null ? void 0 : _a.includes(feature2.key))) {
402
+ return 1;
403
+ }
404
+ if (feature1.key && ((_b = feature2.overwrites) == null ? void 0 : _b.includes(feature1.key))) {
405
+ return -1;
406
+ }
407
+ return originalOrder.indexOf(feature1) - originalOrder.indexOf(feature2);
408
+ };
409
+ var sortFeatures = (features = []) => exhaustiveSort(features, compareFeatures(features));
410
+ var createTree = (initialConfig) => {
411
+ var _a, _b, _c, _d;
412
+ const buildInstance = (_a = initialConfig.instanceBuilder) != null ? _a : buildStaticInstance;
413
+ const additionalFeatures = [
414
+ treeFeature,
415
+ ...sortFeatures(initialConfig.features)
416
+ ];
417
+ verifyFeatures(additionalFeatures);
418
+ const features = [...additionalFeatures];
419
+ const [treeInstance, finalizeTree] = buildInstance(
420
+ features,
421
+ "treeInstance",
422
+ (tree) => ({ tree })
423
+ );
424
+ let state = additionalFeatures.reduce(
425
+ (acc, feature) => {
426
+ var _a2, _b2;
427
+ return (_b2 = (_a2 = feature.getInitialState) == null ? void 0 : _a2.call(feature, acc, treeInstance)) != null ? _b2 : acc;
428
+ },
429
+ (_c = (_b = initialConfig.initialState) != null ? _b : initialConfig.state) != null ? _c : {}
430
+ );
431
+ let config = additionalFeatures.reduce(
432
+ (acc, feature) => {
433
+ var _a2, _b2;
434
+ return (_b2 = (_a2 = feature.getDefaultConfig) == null ? void 0 : _a2.call(feature, acc, treeInstance)) != null ? _b2 : acc;
435
+ },
436
+ initialConfig
437
+ );
438
+ const stateHandlerNames = additionalFeatures.reduce(
439
+ (acc, feature) => __spreadValues(__spreadValues({}, acc), feature.stateHandlerNames),
440
+ {}
441
+ );
442
+ let treeElement;
443
+ const treeDataRef = { current: {} };
444
+ const itemInstancesMap = {};
445
+ let itemInstances = [];
446
+ const itemElementsMap = {};
447
+ const itemDataRefs = {};
448
+ let itemMetaMap = {};
449
+ const hotkeyPresets = {};
450
+ const rebuildItemMeta = () => {
451
+ itemInstances = [];
452
+ itemMetaMap = {};
453
+ const [rootInstance, finalizeRootInstance] = buildInstance(
454
+ features,
455
+ "itemInstance",
456
+ (item) => ({ item, tree: treeInstance, itemId: config.rootItemId })
457
+ );
458
+ finalizeRootInstance();
459
+ itemInstancesMap[config.rootItemId] = rootInstance;
460
+ itemMetaMap[config.rootItemId] = {
461
+ itemId: config.rootItemId,
462
+ index: -1,
463
+ parentId: null,
464
+ level: -1,
465
+ posInSet: 0,
466
+ setSize: 1
467
+ };
468
+ for (const item of treeInstance.getItemsMeta()) {
469
+ itemMetaMap[item.itemId] = item;
470
+ if (!itemInstancesMap[item.itemId]) {
471
+ const [instance, finalizeInstance] = buildInstance(
472
+ features,
473
+ "itemInstance",
474
+ (instance2) => ({
475
+ item: instance2,
476
+ tree: treeInstance,
477
+ itemId: item.itemId
478
+ })
479
+ );
480
+ finalizeInstance();
481
+ itemInstancesMap[item.itemId] = instance;
482
+ itemInstances.push(instance);
483
+ } else {
484
+ itemInstances.push(itemInstancesMap[item.itemId]);
485
+ }
486
+ }
487
+ };
488
+ const eachFeature = (fn) => {
489
+ for (const feature of additionalFeatures) {
490
+ fn(feature);
491
+ }
492
+ };
493
+ const mainFeature = {
494
+ key: "main",
495
+ treeInstance: {
496
+ getState: () => state,
497
+ setState: ({}, updater) => {
498
+ var _a2;
499
+ (_a2 = config.setState) == null ? void 0 : _a2.call(config, state);
500
+ },
501
+ applySubStateUpdate: ({}, stateName, updater) => {
502
+ state[stateName] = typeof updater === "function" ? updater(state[stateName]) : updater;
503
+ const externalStateSetter = config[stateHandlerNames[stateName]];
504
+ externalStateSetter == null ? void 0 : externalStateSetter(state[stateName]);
505
+ },
506
+ // TODO rebuildSubTree: (itemId: string) => void;
507
+ rebuildTree: () => {
508
+ var _a2;
509
+ rebuildItemMeta();
510
+ (_a2 = config.setState) == null ? void 0 : _a2.call(config, state);
511
+ },
512
+ getConfig: () => config,
513
+ setConfig: (_, updater) => {
514
+ var _a2, _b2, _c2;
515
+ const newConfig = typeof updater === "function" ? updater(config) : updater;
516
+ const hasChangedExpandedItems = ((_a2 = newConfig.state) == null ? void 0 : _a2.expandedItems) && ((_b2 = newConfig.state) == null ? void 0 : _b2.expandedItems) !== state.expandedItems;
517
+ config = newConfig;
518
+ if (newConfig.state) {
519
+ state = __spreadValues(__spreadValues({}, state), newConfig.state);
520
+ }
521
+ if (hasChangedExpandedItems) {
522
+ rebuildItemMeta();
523
+ (_c2 = config.setState) == null ? void 0 : _c2.call(config, state);
524
+ }
525
+ },
526
+ getItemInstance: ({}, itemId) => {
527
+ const existingInstance = itemInstancesMap[itemId];
528
+ if (!existingInstance) {
529
+ const [instance, finalizeInstance] = buildInstance(
530
+ features,
531
+ "itemInstance",
532
+ (instance2) => ({
533
+ item: instance2,
534
+ tree: treeInstance,
535
+ itemId
536
+ })
537
+ );
538
+ finalizeInstance();
539
+ return instance;
540
+ }
541
+ return existingInstance;
542
+ },
543
+ getItems: () => itemInstances,
544
+ registerElement: ({}, element) => {
545
+ if (treeElement === element) {
546
+ return;
547
+ }
548
+ if (treeElement && !element) {
549
+ eachFeature(
550
+ (feature) => {
551
+ var _a2;
552
+ return (_a2 = feature.onTreeUnmount) == null ? void 0 : _a2.call(feature, treeInstance, treeElement);
553
+ }
554
+ );
555
+ } else if (!treeElement && element) {
556
+ eachFeature(
557
+ (feature) => {
558
+ var _a2;
559
+ return (_a2 = feature.onTreeMount) == null ? void 0 : _a2.call(feature, treeInstance, element);
560
+ }
561
+ );
562
+ }
563
+ treeElement = element;
564
+ },
565
+ getElement: () => treeElement,
566
+ getDataRef: () => treeDataRef,
567
+ getHotkeyPresets: () => hotkeyPresets
568
+ },
569
+ itemInstance: {
570
+ registerElement: ({ itemId, item }, element) => {
571
+ if (itemElementsMap[itemId] === element) {
572
+ return;
573
+ }
574
+ const oldElement = itemElementsMap[itemId];
575
+ if (oldElement && !element) {
576
+ eachFeature(
577
+ (feature) => {
578
+ var _a2;
579
+ return (_a2 = feature.onItemUnmount) == null ? void 0 : _a2.call(feature, item, oldElement, treeInstance);
580
+ }
581
+ );
582
+ } else if (!oldElement && element) {
583
+ eachFeature(
584
+ (feature) => {
585
+ var _a2;
586
+ return (_a2 = feature.onItemMount) == null ? void 0 : _a2.call(feature, item, element, treeInstance);
587
+ }
588
+ );
589
+ }
590
+ itemElementsMap[itemId] = element;
591
+ },
592
+ getElement: ({ itemId }) => itemElementsMap[itemId],
593
+ // eslint-disable-next-line no-return-assign
594
+ getDataRef: ({ itemId }) => {
595
+ var _a2;
596
+ return (_a2 = itemDataRefs[itemId]) != null ? _a2 : itemDataRefs[itemId] = { current: {} };
597
+ },
598
+ getItemMeta: ({ itemId }) => {
599
+ var _a2;
600
+ return (_a2 = itemMetaMap[itemId]) != null ? _a2 : {
601
+ itemId,
602
+ parentId: null,
603
+ level: -1,
604
+ index: -1,
605
+ posInSet: 0,
606
+ setSize: 1
607
+ };
608
+ }
609
+ }
610
+ };
611
+ features.unshift(mainFeature);
612
+ for (const feature of features) {
613
+ Object.assign(hotkeyPresets, (_d = feature.hotkeys) != null ? _d : {});
614
+ }
615
+ finalizeTree();
616
+ return treeInstance;
617
+ };
618
+
619
+ // src/features/drag-and-drop/types.ts
620
+ var DragTargetPosition = /* @__PURE__ */ ((DragTargetPosition2) => {
621
+ DragTargetPosition2["Top"] = "top";
622
+ DragTargetPosition2["Bottom"] = "bottom";
623
+ DragTargetPosition2["Item"] = "item";
624
+ return DragTargetPosition2;
625
+ })(DragTargetPosition || {});
626
+
627
+ // src/features/keyboard-drag-and-drop/types.ts
628
+ var AssistiveDndState = /* @__PURE__ */ ((AssistiveDndState2) => {
629
+ AssistiveDndState2[AssistiveDndState2["None"] = 0] = "None";
630
+ AssistiveDndState2[AssistiveDndState2["Started"] = 1] = "Started";
631
+ AssistiveDndState2[AssistiveDndState2["Dragging"] = 2] = "Dragging";
632
+ AssistiveDndState2[AssistiveDndState2["Completed"] = 3] = "Completed";
633
+ AssistiveDndState2[AssistiveDndState2["Aborted"] = 4] = "Aborted";
634
+ return AssistiveDndState2;
635
+ })(AssistiveDndState || {});
636
+
637
+ // src/features/checkboxes/types.ts
638
+ var CheckedState = /* @__PURE__ */ ((CheckedState2) => {
639
+ CheckedState2["Checked"] = "checked";
640
+ CheckedState2["Unchecked"] = "unchecked";
641
+ CheckedState2["Indeterminate"] = "indeterminate";
642
+ return CheckedState2;
643
+ })(CheckedState || {});
644
+
645
+ // src/features/selection/feature.ts
646
+ var selectionFeature = {
647
+ key: "selection",
648
+ getInitialState: (initialState) => __spreadValues({
649
+ selectedItems: []
650
+ }, initialState),
651
+ getDefaultConfig: (defaultConfig, tree) => __spreadValues({
652
+ setSelectedItems: makeStateUpdater("selectedItems", tree)
653
+ }, defaultConfig),
654
+ stateHandlerNames: {
655
+ selectedItems: "setSelectedItems"
656
+ },
657
+ treeInstance: {
658
+ setSelectedItems: ({ tree }, selectedItems) => {
659
+ tree.applySubStateUpdate("selectedItems", selectedItems);
660
+ },
661
+ getSelectedItems: ({ tree }) => {
662
+ return tree.getState().selectedItems.map(tree.getItemInstance);
663
+ }
664
+ },
665
+ itemInstance: {
666
+ select: ({ tree, itemId }) => {
667
+ const { selectedItems } = tree.getState();
668
+ tree.setSelectedItems(
669
+ selectedItems.includes(itemId) ? selectedItems : [...selectedItems, itemId]
670
+ );
671
+ },
672
+ deselect: ({ tree, itemId }) => {
673
+ const { selectedItems } = tree.getState();
674
+ tree.setSelectedItems(selectedItems.filter((id) => id !== itemId));
675
+ },
676
+ isSelected: ({ tree, itemId }) => {
677
+ const { selectedItems } = tree.getState();
678
+ return selectedItems.includes(itemId);
679
+ },
680
+ selectUpTo: ({ tree, item }, ctrl) => {
681
+ const indexA = item.getItemMeta().index;
682
+ const indexB = tree.getFocusedItem().getItemMeta().index;
683
+ const [a, b] = indexA < indexB ? [indexA, indexB] : [indexB, indexA];
684
+ const newSelectedItems = tree.getItems().slice(a, b + 1).map((treeItem) => treeItem.getItemMeta().itemId);
685
+ if (!ctrl) {
686
+ tree.setSelectedItems(newSelectedItems);
687
+ return;
688
+ }
689
+ const { selectedItems } = tree.getState();
690
+ const uniqueSelectedItems = [
691
+ .../* @__PURE__ */ new Set([...selectedItems, ...newSelectedItems])
692
+ ];
693
+ tree.setSelectedItems(uniqueSelectedItems);
694
+ },
695
+ toggleSelect: ({ item }) => {
696
+ if (item.isSelected()) {
697
+ item.deselect();
698
+ } else {
699
+ item.select();
700
+ }
701
+ },
702
+ getProps: ({ tree, item, prev }) => __spreadProps(__spreadValues({}, prev == null ? void 0 : prev()), {
703
+ "aria-selected": item.isSelected() ? "true" : "false",
704
+ onClick: (e) => {
705
+ var _a, _b;
706
+ if (e.shiftKey) {
707
+ item.selectUpTo(e.ctrlKey || e.metaKey);
708
+ } else if (e.ctrlKey || e.metaKey) {
709
+ item.toggleSelect();
710
+ } else {
711
+ tree.setSelectedItems([item.getItemMeta().itemId]);
712
+ }
713
+ (_b = (_a = prev == null ? void 0 : prev()) == null ? void 0 : _a.onClick) == null ? void 0 : _b.call(_a, e);
714
+ }
715
+ })
716
+ },
717
+ hotkeys: {
718
+ // setSelectedItem: {
719
+ // hotkey: "space",
720
+ // handler: (e, tree) => {
721
+ // tree.setSelectedItems([tree.getFocusedItem().getId()]);
722
+ // },
723
+ // },
724
+ toggleSelectedItem: {
725
+ hotkey: "Control+Space",
726
+ preventDefault: true,
727
+ handler: (_, tree) => {
728
+ tree.getFocusedItem().toggleSelect();
729
+ }
730
+ },
731
+ selectUpwards: {
732
+ hotkey: "Shift+ArrowUp",
733
+ handler: (e, tree) => {
734
+ const focused = tree.getFocusedItem();
735
+ const above = focused.getItemAbove();
736
+ if (!above) return;
737
+ if (focused.isSelected() && above.isSelected()) {
738
+ focused.deselect();
739
+ } else {
740
+ above.select();
741
+ }
742
+ above.setFocused();
743
+ tree.updateDomFocus();
744
+ }
745
+ },
746
+ selectDownwards: {
747
+ hotkey: "Shift+ArrowDown",
748
+ handler: (e, tree) => {
749
+ const focused = tree.getFocusedItem();
750
+ const below = focused.getItemBelow();
751
+ if (!below) return;
752
+ if (focused.isSelected() && below.isSelected()) {
753
+ focused.deselect();
754
+ } else {
755
+ below.select();
756
+ }
757
+ below.setFocused();
758
+ tree.updateDomFocus();
759
+ }
760
+ },
761
+ selectAll: {
762
+ hotkey: "Control+KeyA",
763
+ preventDefault: true,
764
+ handler: (e, tree) => {
765
+ tree.setSelectedItems(tree.getItems().map((item) => item.getId()));
766
+ }
767
+ }
768
+ }
769
+ };
770
+
771
+ // src/features/checkboxes/feature.ts
772
+ var getAllLoadedDescendants = (tree, itemId, includeFolders = false) => {
773
+ if (!tree.getConfig().isItemFolder(tree.getItemInstance(itemId))) {
774
+ return [itemId];
775
+ }
776
+ const descendants = tree.retrieveChildrenIds(itemId).map((child) => getAllLoadedDescendants(tree, child, includeFolders)).flat();
777
+ return includeFolders ? [itemId, ...descendants] : descendants;
778
+ };
779
+ var checkboxesFeature = {
780
+ key: "checkboxes",
781
+ overwrites: ["selection"],
782
+ getInitialState: (initialState) => __spreadValues({
783
+ checkedItems: []
784
+ }, initialState),
785
+ getDefaultConfig: (defaultConfig, tree) => {
786
+ var _a, _b, _c;
787
+ const hasAsyncLoader = (_a = defaultConfig.features) == null ? void 0 : _a.some(
788
+ (f) => f.key === "async-data-loader"
789
+ );
790
+ if (hasAsyncLoader && defaultConfig.propagateCheckedState) {
791
+ throwError(`propagateCheckedState not supported with async trees`);
792
+ }
793
+ const propagateCheckedState = (_b = defaultConfig.propagateCheckedState) != null ? _b : !hasAsyncLoader;
794
+ const canCheckFolders = (_c = defaultConfig.canCheckFolders) != null ? _c : !propagateCheckedState;
795
+ return __spreadValues({
796
+ setCheckedItems: makeStateUpdater("checkedItems", tree),
797
+ propagateCheckedState,
798
+ canCheckFolders
799
+ }, defaultConfig);
800
+ },
801
+ stateHandlerNames: {
802
+ checkedItems: "setCheckedItems"
803
+ },
804
+ treeInstance: {
805
+ setCheckedItems: ({ tree }, checkedItems) => {
806
+ tree.applySubStateUpdate("checkedItems", checkedItems);
807
+ }
808
+ },
809
+ itemInstance: {
810
+ getCheckboxProps: ({ item }) => {
811
+ const checkedState = item.getCheckedState();
812
+ return {
813
+ onChange: item.toggleCheckedState,
814
+ checked: checkedState === "checked" /* Checked */,
815
+ ref: (r) => {
816
+ if (r) {
817
+ r.indeterminate = checkedState === "indeterminate" /* Indeterminate */;
818
+ }
819
+ }
820
+ };
821
+ },
822
+ toggleCheckedState: ({ item }) => {
823
+ if (item.getCheckedState() === "checked" /* Checked */) {
824
+ item.setUnchecked();
825
+ } else {
826
+ item.setChecked();
827
+ }
828
+ },
829
+ getCheckedState: ({ item, tree }) => {
830
+ const { checkedItems } = tree.getState();
831
+ const { propagateCheckedState } = tree.getConfig();
832
+ const itemId = item.getId();
833
+ if (checkedItems.includes(itemId)) {
834
+ return "checked" /* Checked */;
835
+ }
836
+ if (item.isFolder() && propagateCheckedState) {
837
+ const descendants = getAllLoadedDescendants(tree, itemId);
838
+ if (descendants.every((d) => checkedItems.includes(d))) {
839
+ return "checked" /* Checked */;
840
+ }
841
+ if (descendants.some((d) => checkedItems.includes(d))) {
842
+ return "indeterminate" /* Indeterminate */;
843
+ }
844
+ }
845
+ return "unchecked" /* Unchecked */;
846
+ },
847
+ setChecked: ({ item, tree, itemId }) => {
848
+ const { propagateCheckedState, canCheckFolders } = tree.getConfig();
849
+ if (item.isFolder() && propagateCheckedState) {
850
+ tree.applySubStateUpdate("checkedItems", (items) => [
851
+ ...items,
852
+ ...getAllLoadedDescendants(tree, itemId, canCheckFolders)
853
+ ]);
854
+ } else if (!item.isFolder() || canCheckFolders) {
855
+ tree.applySubStateUpdate("checkedItems", (items) => [...items, itemId]);
856
+ }
857
+ },
858
+ setUnchecked: ({ item, tree, itemId }) => {
859
+ const { propagateCheckedState, canCheckFolders } = tree.getConfig();
860
+ if (item.isFolder() && propagateCheckedState) {
861
+ const descendants = getAllLoadedDescendants(
862
+ tree,
863
+ itemId,
864
+ canCheckFolders
865
+ );
866
+ tree.applySubStateUpdate(
867
+ "checkedItems",
868
+ (items) => items.filter((id) => !descendants.includes(id) && id !== itemId)
869
+ );
870
+ } else {
871
+ tree.applySubStateUpdate(
872
+ "checkedItems",
873
+ (items) => items.filter((id) => id !== itemId)
874
+ );
875
+ }
876
+ }
877
+ }
878
+ };
879
+
880
+ // src/features/hotkeys-core/feature.ts
881
+ var specialKeys = {
882
+ // TODO:breaking deprecate auto-lowercase
883
+ letter: /^Key[A-Z]$/,
884
+ letterornumber: /^(Key[A-Z]|Digit[0-9])$/,
885
+ plus: /^(NumpadAdd|Plus)$/,
886
+ minus: /^(NumpadSubtract|Minus)$/,
887
+ control: /^(ControlLeft|ControlRight)$/,
888
+ shift: /^(ShiftLeft|ShiftRight)$/
889
+ };
890
+ var testHotkeyMatch = (pressedKeys, tree, hotkey) => {
891
+ const supposedKeys = hotkey.hotkey.toLowerCase().split("+");
892
+ const doKeysMatch = supposedKeys.every((key) => {
893
+ if (key in specialKeys) {
894
+ return [...pressedKeys].some(
895
+ (pressedKey) => specialKeys[key].test(pressedKey)
896
+ );
897
+ }
898
+ const pressedKeysLowerCase = [...pressedKeys].map((k) => k.toLowerCase());
899
+ if (pressedKeysLowerCase.includes(key.toLowerCase())) {
900
+ return true;
901
+ }
902
+ if (pressedKeysLowerCase.includes(`key${key.toLowerCase()}`)) {
903
+ return true;
904
+ }
905
+ return false;
906
+ });
907
+ const isEnabled = !hotkey.isEnabled || hotkey.isEnabled(tree);
908
+ const equalCounts = pressedKeys.size === supposedKeys.length;
909
+ return doKeysMatch && isEnabled && equalCounts;
910
+ };
911
+ var findHotkeyMatch = (pressedKeys, tree, config1, config2) => {
912
+ var _a;
913
+ return (_a = Object.entries(__spreadValues(__spreadValues({}, config1), config2)).find(
914
+ ([, hotkey]) => testHotkeyMatch(pressedKeys, tree, hotkey)
915
+ )) == null ? void 0 : _a[0];
916
+ };
917
+ var hotkeysCoreFeature = {
918
+ key: "hotkeys-core",
919
+ onTreeMount: (tree, element) => {
920
+ const data = tree.getDataRef();
921
+ const keydown = (e) => {
922
+ var _a, _b;
923
+ const { ignoreHotkeysOnInputs, onTreeHotkey, hotkeys } = tree.getConfig();
924
+ if (e.target instanceof HTMLInputElement && ignoreHotkeysOnInputs) {
925
+ return;
926
+ }
927
+ (_b = (_a = data.current).pressedKeys) != null ? _b : _a.pressedKeys = /* @__PURE__ */ new Set();
928
+ const newMatch = !data.current.pressedKeys.has(e.code);
929
+ data.current.pressedKeys.add(e.code);
930
+ const hotkeyName = findHotkeyMatch(
931
+ data.current.pressedKeys,
932
+ tree,
933
+ tree.getHotkeyPresets(),
934
+ hotkeys
935
+ );
936
+ if (e.target instanceof HTMLInputElement) {
937
+ data.current.pressedKeys.delete(e.code);
938
+ }
939
+ if (!hotkeyName) return;
940
+ const hotkeyConfig = __spreadValues(__spreadValues({}, tree.getHotkeyPresets()[hotkeyName]), hotkeys == null ? void 0 : hotkeys[hotkeyName]);
941
+ if (!hotkeyConfig) return;
942
+ if (!hotkeyConfig.allowWhenInputFocused && e.target instanceof HTMLInputElement)
943
+ return;
944
+ if (!hotkeyConfig.canRepeat && !newMatch) return;
945
+ if (hotkeyConfig.preventDefault) e.preventDefault();
946
+ hotkeyConfig.handler(e, tree);
947
+ onTreeHotkey == null ? void 0 : onTreeHotkey(hotkeyName, e);
948
+ };
949
+ const keyup = (e) => {
950
+ var _a, _b;
951
+ (_b = (_a = data.current).pressedKeys) != null ? _b : _a.pressedKeys = /* @__PURE__ */ new Set();
952
+ data.current.pressedKeys.delete(e.code);
953
+ };
954
+ const reset = () => {
955
+ data.current.pressedKeys = /* @__PURE__ */ new Set();
956
+ };
957
+ element.addEventListener("keydown", keydown);
958
+ document.addEventListener("keyup", keyup);
959
+ window.addEventListener("focus", reset);
960
+ data.current.keydownHandler = keydown;
961
+ data.current.keyupHandler = keyup;
962
+ data.current.resetHandler = reset;
963
+ },
964
+ onTreeUnmount: (tree, element) => {
965
+ const data = tree.getDataRef();
966
+ if (data.current.keyupHandler) {
967
+ document.removeEventListener("keyup", data.current.keyupHandler);
968
+ delete data.current.keyupHandler;
969
+ }
970
+ if (data.current.keydownHandler) {
971
+ element.removeEventListener("keydown", data.current.keydownHandler);
972
+ delete data.current.keydownHandler;
973
+ }
974
+ if (data.current.resetHandler) {
975
+ window.removeEventListener("focus", data.current.resetHandler);
976
+ delete data.current.resetHandler;
977
+ }
978
+ }
979
+ };
980
+
981
+ // src/features/async-data-loader/feature.ts
982
+ var getDataRef = (tree) => {
983
+ var _a, _b, _c, _d;
984
+ const dataRef = tree.getDataRef();
985
+ (_b = (_a = dataRef.current).itemData) != null ? _b : _a.itemData = {};
986
+ (_d = (_c = dataRef.current).childrenIds) != null ? _d : _c.childrenIds = {};
987
+ return dataRef;
988
+ };
989
+ var loadItemData = (tree, itemId) => __async(null, null, function* () {
990
+ var _a;
991
+ const config = tree.getConfig();
992
+ const dataRef = getDataRef(tree);
993
+ const item = yield config.dataLoader.getItem(itemId);
994
+ dataRef.current.itemData[itemId] = item;
995
+ (_a = config.onLoadedItem) == null ? void 0 : _a.call(config, itemId, item);
996
+ tree.applySubStateUpdate(
997
+ "loadingItemData",
998
+ (loadingItemData) => loadingItemData.filter((id) => id !== itemId)
999
+ );
1000
+ return item;
1001
+ });
1002
+ var loadChildrenIds = (tree, itemId) => __async(null, null, function* () {
1003
+ var _a, _b;
1004
+ const config = tree.getConfig();
1005
+ const dataRef = getDataRef(tree);
1006
+ let childrenIds;
1007
+ if ("getChildrenWithData" in config.dataLoader) {
1008
+ const children = yield config.dataLoader.getChildrenWithData(itemId);
1009
+ childrenIds = children.map((c) => c.id);
1010
+ dataRef.current.childrenIds[itemId] = childrenIds;
1011
+ children.forEach(({ id, data }) => {
1012
+ var _a2;
1013
+ dataRef.current.itemData[id] = data;
1014
+ (_a2 = config.onLoadedItem) == null ? void 0 : _a2.call(config, id, data);
1015
+ });
1016
+ (_a = config.onLoadedChildren) == null ? void 0 : _a.call(config, itemId, childrenIds);
1017
+ tree.rebuildTree();
1018
+ tree.applySubStateUpdate(
1019
+ "loadingItemData",
1020
+ (loadingItemData) => loadingItemData.filter((id) => !childrenIds.includes(id))
1021
+ );
1022
+ } else {
1023
+ childrenIds = yield config.dataLoader.getChildren(itemId);
1024
+ dataRef.current.childrenIds[itemId] = childrenIds;
1025
+ (_b = config.onLoadedChildren) == null ? void 0 : _b.call(config, itemId, childrenIds);
1026
+ tree.rebuildTree();
1027
+ }
1028
+ tree.applySubStateUpdate(
1029
+ "loadingItemChildrens",
1030
+ (loadingItemChildrens) => loadingItemChildrens.filter((id) => id !== itemId)
1031
+ );
1032
+ return childrenIds;
1033
+ });
1034
+ var asyncDataLoaderFeature = {
1035
+ key: "async-data-loader",
1036
+ getInitialState: (initialState) => __spreadValues({
1037
+ loadingItemData: [],
1038
+ loadingItemChildrens: []
1039
+ }, initialState),
1040
+ getDefaultConfig: (defaultConfig, tree) => __spreadValues({
1041
+ setLoadingItemData: makeStateUpdater("loadingItemData", tree),
1042
+ setLoadingItemChildrens: makeStateUpdater("loadingItemChildrens", tree)
1043
+ }, defaultConfig),
1044
+ stateHandlerNames: {
1045
+ loadingItemData: "setLoadingItemData",
1046
+ loadingItemChildrens: "setLoadingItemChildrens"
1047
+ },
1048
+ treeInstance: {
1049
+ waitForItemDataLoaded: ({ tree }, itemId) => tree.loadItemData(itemId),
1050
+ waitForItemChildrenLoaded: ({ tree }, itemId) => tree.loadChildrenIds(itemId),
1051
+ loadItemData: (_0, _1) => __async(null, [_0, _1], function* ({ tree }, itemId) {
1052
+ var _a;
1053
+ return (_a = getDataRef(tree).current.itemData[itemId]) != null ? _a : yield loadItemData(tree, itemId);
1054
+ }),
1055
+ loadChildrenIds: (_0, _1) => __async(null, [_0, _1], function* ({ tree }, itemId) {
1056
+ var _a;
1057
+ return (_a = getDataRef(tree).current.childrenIds[itemId]) != null ? _a : yield loadChildrenIds(tree, itemId);
1058
+ }),
1059
+ retrieveItemData: ({ tree }, itemId, skipFetch = false) => {
1060
+ var _a, _b;
1061
+ const config = tree.getConfig();
1062
+ const dataRef = getDataRef(tree);
1063
+ if (dataRef.current.itemData[itemId]) {
1064
+ return dataRef.current.itemData[itemId];
1065
+ }
1066
+ if (!tree.getState().loadingItemData.includes(itemId) && !skipFetch) {
1067
+ tree.applySubStateUpdate("loadingItemData", (loadingItemData) => [
1068
+ ...loadingItemData,
1069
+ itemId
1070
+ ]);
1071
+ loadItemData(tree, itemId);
1072
+ }
1073
+ return (_b = (_a = config.createLoadingItemData) == null ? void 0 : _a.call(config)) != null ? _b : null;
1074
+ },
1075
+ retrieveChildrenIds: ({ tree }, itemId, skipFetch = false) => {
1076
+ const dataRef = getDataRef(tree);
1077
+ if (dataRef.current.childrenIds[itemId]) {
1078
+ return dataRef.current.childrenIds[itemId];
1079
+ }
1080
+ if (tree.getState().loadingItemChildrens.includes(itemId) || skipFetch) {
1081
+ return [];
1082
+ }
1083
+ tree.applySubStateUpdate(
1084
+ "loadingItemChildrens",
1085
+ (loadingItemChildrens) => [...loadingItemChildrens, itemId]
1086
+ );
1087
+ loadChildrenIds(tree, itemId);
1088
+ return [];
1089
+ }
1090
+ },
1091
+ itemInstance: {
1092
+ isLoading: ({ tree, item }) => tree.getState().loadingItemData.includes(item.getItemMeta().itemId) || tree.getState().loadingItemChildrens.includes(item.getItemMeta().itemId),
1093
+ invalidateItemData: (_0, _1) => __async(null, [_0, _1], function* ({ tree, itemId }, optimistic) {
1094
+ var _a;
1095
+ if (!optimistic) {
1096
+ (_a = getDataRef(tree).current.itemData) == null ? true : delete _a[itemId];
1097
+ tree.applySubStateUpdate("loadingItemData", (loadingItemData) => [
1098
+ ...loadingItemData,
1099
+ itemId
1100
+ ]);
1101
+ }
1102
+ yield loadItemData(tree, itemId);
1103
+ }),
1104
+ invalidateChildrenIds: (_0, _1) => __async(null, [_0, _1], function* ({ tree, itemId }, optimistic) {
1105
+ var _a;
1106
+ if (!optimistic) {
1107
+ (_a = getDataRef(tree).current.childrenIds) == null ? true : delete _a[itemId];
1108
+ tree.applySubStateUpdate(
1109
+ "loadingItemChildrens",
1110
+ (loadingItemChildrens) => [...loadingItemChildrens, itemId]
1111
+ );
1112
+ }
1113
+ yield loadChildrenIds(tree, itemId);
1114
+ }),
1115
+ updateCachedChildrenIds: ({ tree, itemId }, childrenIds) => {
1116
+ const dataRef = tree.getDataRef();
1117
+ dataRef.current.childrenIds[itemId] = childrenIds;
1118
+ tree.rebuildTree();
1119
+ },
1120
+ updateCachedData: ({ tree, itemId }, data) => {
1121
+ const dataRef = tree.getDataRef();
1122
+ dataRef.current.itemData[itemId] = data;
1123
+ tree.rebuildTree();
1124
+ }
1125
+ }
1126
+ };
1127
+
1128
+ // src/features/sync-data-loader/feature.ts
1129
+ var undefErrorMessage = "sync dataLoader returned undefined";
1130
+ var promiseErrorMessage = "sync dataLoader returned promise";
1131
+ var unpromise = (data) => {
1132
+ if (!data) {
1133
+ throw throwError(undefErrorMessage);
1134
+ }
1135
+ if (typeof data === "object" && "then" in data) {
1136
+ throw throwError(promiseErrorMessage);
1137
+ }
1138
+ return data;
1139
+ };
1140
+ var syncDataLoaderFeature = {
1141
+ key: "sync-data-loader",
1142
+ getInitialState: (initialState) => __spreadValues({
1143
+ loadingItemData: [],
1144
+ loadingItemChildrens: []
1145
+ }, initialState),
1146
+ getDefaultConfig: (defaultConfig, tree) => __spreadValues({
1147
+ setLoadingItemData: makeStateUpdater("loadingItemData", tree),
1148
+ setLoadingItemChildrens: makeStateUpdater("loadingItemChildrens", tree)
1149
+ }, defaultConfig),
1150
+ stateHandlerNames: {
1151
+ loadingItemData: "setLoadingItemData",
1152
+ loadingItemChildrens: "setLoadingItemChildrens"
1153
+ },
1154
+ treeInstance: {
1155
+ waitForItemDataLoaded: () => __async(null, null, function* () {
1156
+ }),
1157
+ waitForItemChildrenLoaded: () => __async(null, null, function* () {
1158
+ }),
1159
+ retrieveItemData: ({ tree }, itemId) => {
1160
+ return unpromise(tree.getConfig().dataLoader.getItem(itemId));
1161
+ },
1162
+ retrieveChildrenIds: ({ tree }, itemId) => {
1163
+ const { dataLoader } = tree.getConfig();
1164
+ if ("getChildren" in dataLoader) {
1165
+ return unpromise(dataLoader.getChildren(itemId));
1166
+ }
1167
+ return unpromise(dataLoader.getChildrenWithData(itemId)).map(
1168
+ (c) => c.data
1169
+ );
1170
+ },
1171
+ loadItemData: ({ tree }, itemId) => tree.retrieveItemData(itemId),
1172
+ loadChildrenIds: ({ tree }, itemId) => tree.retrieveChildrenIds(itemId)
1173
+ },
1174
+ itemInstance: {
1175
+ isLoading: () => false
1176
+ }
1177
+ };
1178
+
1179
+ // src/features/drag-and-drop/utils.ts
1180
+ var isOrderedDragTarget = (dragTarget) => "childIndex" in dragTarget;
1181
+ var canDrop = (dataTransfer, target, tree) => {
1182
+ var _a, _b, _c;
1183
+ const draggedItems = (_a = tree.getState().dnd) == null ? void 0 : _a.draggedItems;
1184
+ const config = tree.getConfig();
1185
+ if (draggedItems && !((_c = (_b = config.canDrop) == null ? void 0 : _b.call(config, draggedItems, target)) != null ? _c : true)) {
1186
+ return false;
1187
+ }
1188
+ if (draggedItems && draggedItems.some(
1189
+ (draggedItem) => target.item.getId() === draggedItem.getId() || target.item.isDescendentOf(draggedItem.getId())
1190
+ )) {
1191
+ return false;
1192
+ }
1193
+ if (!draggedItems && dataTransfer && config.canDropForeignDragObject && !config.canDropForeignDragObject(dataTransfer, target)) {
1194
+ return false;
1195
+ }
1196
+ return true;
1197
+ };
1198
+ var getItemDropCategory = (item) => {
1199
+ if (item.isExpanded()) {
1200
+ return 1 /* ExpandedFolder */;
1201
+ }
1202
+ const parent = item.getParent();
1203
+ if (parent && item.getIndexInParent() === item.getItemMeta().setSize - 1) {
1204
+ return 2 /* LastInGroup */;
1205
+ }
1206
+ return 0 /* Item */;
1207
+ };
1208
+ var getInsertionIndex = (children, childIndex, draggedItems) => {
1209
+ var _a;
1210
+ const numberOfDragItemsBeforeTarget = (_a = children.slice(0, childIndex).reduce(
1211
+ (counter, child) => child && (draggedItems == null ? void 0 : draggedItems.some((i) => i.getId() === child.getId())) ? ++counter : counter,
1212
+ 0
1213
+ )) != null ? _a : 0;
1214
+ return childIndex - numberOfDragItemsBeforeTarget;
1215
+ };
1216
+ var getTargetPlacement = (e, item, tree, canMakeChild) => {
1217
+ var _a, _b, _c, _d, _e;
1218
+ const config = tree.getConfig();
1219
+ if (!config.canReorder) {
1220
+ return canMakeChild ? { type: 2 /* MakeChild */ } : { type: 1 /* ReorderBelow */ };
1221
+ }
1222
+ const bb = (_a = item.getElement()) == null ? void 0 : _a.getBoundingClientRect();
1223
+ const topPercent = bb ? (e.clientY - bb.top) / bb.height : 0.5;
1224
+ const leftPixels = bb ? e.clientX - bb.left : 0;
1225
+ const targetDropCategory = getItemDropCategory(item);
1226
+ const reorderAreaPercentage = !canMakeChild ? 0.5 : (_b = config.reorderAreaPercentage) != null ? _b : 0.3;
1227
+ const indent = (_c = config.indent) != null ? _c : 20;
1228
+ const makeChildType = canMakeChild ? 2 /* MakeChild */ : 1 /* ReorderBelow */;
1229
+ if (targetDropCategory === 1 /* ExpandedFolder */) {
1230
+ if (topPercent < reorderAreaPercentage) {
1231
+ return { type: 0 /* ReorderAbove */ };
1232
+ }
1233
+ return { type: makeChildType };
1234
+ }
1235
+ if (targetDropCategory === 2 /* LastInGroup */) {
1236
+ if (leftPixels < item.getItemMeta().level * indent) {
1237
+ if (topPercent < 0.5) {
1238
+ return { type: 0 /* ReorderAbove */ };
1239
+ }
1240
+ const minLevel = (_e = (_d = item.getItemBelow()) == null ? void 0 : _d.getItemMeta().level) != null ? _e : 0;
1241
+ return {
1242
+ type: 3 /* Reparent */,
1243
+ reparentLevel: Math.max(minLevel, Math.floor(leftPixels / indent))
1244
+ };
1245
+ }
1246
+ }
1247
+ if (topPercent < reorderAreaPercentage) {
1248
+ return { type: 0 /* ReorderAbove */ };
1249
+ }
1250
+ if (topPercent > 1 - reorderAreaPercentage) {
1251
+ return { type: 1 /* ReorderBelow */ };
1252
+ }
1253
+ return { type: makeChildType };
1254
+ };
1255
+ var getDragCode = (e, item, tree) => {
1256
+ const placement = getTargetPlacement(e, item, tree, true);
1257
+ return [
1258
+ item.getId(),
1259
+ placement.type,
1260
+ placement.type === 3 /* Reparent */ ? placement.reparentLevel : 0
1261
+ ].join("__");
1262
+ };
1263
+ var getNthParent = (item, n) => {
1264
+ if (n === item.getItemMeta().level) {
1265
+ return item;
1266
+ }
1267
+ return getNthParent(item.getParent(), n);
1268
+ };
1269
+ var getReparentTarget = (item, reparentLevel, draggedItems) => {
1270
+ const itemMeta = item.getItemMeta();
1271
+ const reparentedTarget = getNthParent(item, reparentLevel - 1);
1272
+ const targetItemAbove = getNthParent(item, reparentLevel);
1273
+ const targetIndex = targetItemAbove.getIndexInParent() + 1;
1274
+ return {
1275
+ item: reparentedTarget,
1276
+ childIndex: targetIndex,
1277
+ insertionIndex: getInsertionIndex(
1278
+ reparentedTarget.getChildren(),
1279
+ targetIndex,
1280
+ draggedItems
1281
+ ),
1282
+ dragLineIndex: itemMeta.index + 1,
1283
+ dragLineLevel: reparentLevel
1284
+ };
1285
+ };
1286
+ var getDragTarget = (e, item, tree, canReorder = tree.getConfig().canReorder) => {
1287
+ var _a;
1288
+ const draggedItems = (_a = tree.getState().dnd) == null ? void 0 : _a.draggedItems;
1289
+ const itemMeta = item.getItemMeta();
1290
+ const parent = item.getParent();
1291
+ const itemTarget = { item };
1292
+ const parentTarget = parent ? { item: parent } : null;
1293
+ const canBecomeSibling = parentTarget && canDrop(e.dataTransfer, parentTarget, tree);
1294
+ const canMakeChild = canDrop(e.dataTransfer, itemTarget, tree);
1295
+ const placement = getTargetPlacement(e, item, tree, canMakeChild);
1296
+ if (!canReorder && parent && canBecomeSibling && placement.type !== 2 /* MakeChild */) {
1297
+ return parentTarget;
1298
+ }
1299
+ if (!canReorder && parent && !canBecomeSibling) {
1300
+ return getDragTarget(e, parent, tree, false);
1301
+ }
1302
+ if (!parent) {
1303
+ return itemTarget;
1304
+ }
1305
+ if (placement.type === 2 /* MakeChild */) {
1306
+ return itemTarget;
1307
+ }
1308
+ if (!canBecomeSibling) {
1309
+ return getDragTarget(e, parent, tree, false);
1310
+ }
1311
+ if (placement.type === 3 /* Reparent */) {
1312
+ return getReparentTarget(item, placement.reparentLevel, draggedItems);
1313
+ }
1314
+ const maybeAddOneForBelow = placement.type === 0 /* ReorderAbove */ ? 0 : 1;
1315
+ const childIndex = item.getIndexInParent() + maybeAddOneForBelow;
1316
+ return {
1317
+ item: parent,
1318
+ dragLineIndex: itemMeta.index + maybeAddOneForBelow,
1319
+ dragLineLevel: itemMeta.level,
1320
+ childIndex,
1321
+ // TODO performance could be improved by computing this only when dragcode changed
1322
+ insertionIndex: getInsertionIndex(
1323
+ parent.getChildren(),
1324
+ childIndex,
1325
+ draggedItems
1326
+ )
1327
+ };
1328
+ };
1329
+
1330
+ // src/features/drag-and-drop/feature.ts
1331
+ var defaultCanDropForeignDragObject = () => false;
1332
+ var dragAndDropFeature = {
1333
+ key: "drag-and-drop",
1334
+ deps: ["selection"],
1335
+ getDefaultConfig: (defaultConfig, tree) => __spreadValues({
1336
+ canDrop: (_, target) => target.item.isFolder(),
1337
+ canDropForeignDragObject: defaultCanDropForeignDragObject,
1338
+ canDragForeignDragObjectOver: defaultConfig.canDropForeignDragObject !== defaultCanDropForeignDragObject ? (dataTransfer) => dataTransfer.effectAllowed !== "none" : () => false,
1339
+ setDndState: makeStateUpdater("dnd", tree),
1340
+ canReorder: true
1341
+ }, defaultConfig),
1342
+ stateHandlerNames: {
1343
+ dnd: "setDndState"
1344
+ },
1345
+ onTreeMount: (tree) => {
1346
+ const listener = () => {
1347
+ tree.applySubStateUpdate("dnd", null);
1348
+ };
1349
+ tree.getDataRef().current.windowDragEndListener = listener;
1350
+ window.addEventListener("dragend", listener);
1351
+ },
1352
+ onTreeUnmount: (tree) => {
1353
+ const { windowDragEndListener } = tree.getDataRef().current;
1354
+ if (!windowDragEndListener) return;
1355
+ window.removeEventListener("dragend", windowDragEndListener);
1356
+ },
1357
+ treeInstance: {
1358
+ getDragTarget: ({ tree }) => {
1359
+ var _a, _b;
1360
+ return (_b = (_a = tree.getState().dnd) == null ? void 0 : _a.dragTarget) != null ? _b : null;
1361
+ },
1362
+ getDragLineData: ({ tree }) => {
1363
+ var _a, _b, _c, _d, _e, _f;
1364
+ const target = tree.getDragTarget();
1365
+ const indent = ((_a = target == null ? void 0 : target.item.getItemMeta().level) != null ? _a : 0) + 1;
1366
+ const treeBb = (_b = tree.getElement()) == null ? void 0 : _b.getBoundingClientRect();
1367
+ if (!target || !treeBb || !isOrderedDragTarget(target)) return null;
1368
+ const leftOffset = target.dragLineLevel * ((_c = tree.getConfig().indent) != null ? _c : 1);
1369
+ const targetItem = tree.getItems()[target.dragLineIndex];
1370
+ if (!targetItem) {
1371
+ const bb2 = (_e = (_d = tree.getItems()[target.dragLineIndex - 1]) == null ? void 0 : _d.getElement()) == null ? void 0 : _e.getBoundingClientRect();
1372
+ if (bb2) {
1373
+ return {
1374
+ indent,
1375
+ top: bb2.bottom - treeBb.top,
1376
+ left: bb2.left + leftOffset - treeBb.left,
1377
+ width: bb2.width - leftOffset
1378
+ };
1379
+ }
1380
+ }
1381
+ const bb = (_f = targetItem.getElement()) == null ? void 0 : _f.getBoundingClientRect();
1382
+ if (bb) {
1383
+ return {
1384
+ indent,
1385
+ top: bb.top - treeBb.top,
1386
+ left: bb.left + leftOffset - treeBb.left,
1387
+ width: bb.width - leftOffset
1388
+ };
1389
+ }
1390
+ return null;
1391
+ },
1392
+ getDragLineStyle: ({ tree }, topOffset = -1, leftOffset = -8) => {
1393
+ const dragLine = tree.getDragLineData();
1394
+ return dragLine ? {
1395
+ position: "absolute",
1396
+ top: `${dragLine.top + topOffset}px`,
1397
+ left: `${dragLine.left + leftOffset}px`,
1398
+ width: `${dragLine.width - leftOffset}px`,
1399
+ pointerEvents: "none"
1400
+ // important to prevent capturing drag events
1401
+ } : { display: "none" };
1402
+ },
1403
+ getContainerProps: ({ prev, tree }, treeLabel) => {
1404
+ const prevProps = prev == null ? void 0 : prev(treeLabel);
1405
+ return __spreadProps(__spreadValues({}, prevProps), {
1406
+ onDragOver: (e) => {
1407
+ e.preventDefault();
1408
+ },
1409
+ onDrop: (e) => __async(null, null, function* () {
1410
+ var _a, _b, _c;
1411
+ const dataRef = tree.getDataRef();
1412
+ const target = { item: tree.getRootItem() };
1413
+ if (!canDrop(e.dataTransfer, target, tree)) {
1414
+ return;
1415
+ }
1416
+ e.preventDefault();
1417
+ const config = tree.getConfig();
1418
+ const draggedItems = (_a = tree.getState().dnd) == null ? void 0 : _a.draggedItems;
1419
+ dataRef.current.lastDragCode = void 0;
1420
+ if (draggedItems) {
1421
+ yield (_b = config.onDrop) == null ? void 0 : _b.call(config, draggedItems, target);
1422
+ } else if (e.dataTransfer) {
1423
+ yield (_c = config.onDropForeignDragObject) == null ? void 0 : _c.call(config, e.dataTransfer, target);
1424
+ }
1425
+ }),
1426
+ style: __spreadProps(__spreadValues({}, prevProps == null ? void 0 : prevProps.style), {
1427
+ position: "relative"
1428
+ })
1429
+ });
1430
+ }
1431
+ },
1432
+ itemInstance: {
1433
+ getProps: ({ tree, item, prev }) => __spreadProps(__spreadValues({}, prev == null ? void 0 : prev()), {
1434
+ draggable: true,
1435
+ onDragEnter: (e) => e.preventDefault(),
1436
+ onDragStart: (e) => {
1437
+ var _a, _b, _c;
1438
+ const selectedItems = tree.getSelectedItems();
1439
+ const items = selectedItems.includes(item) ? selectedItems : [item];
1440
+ const config = tree.getConfig();
1441
+ if (!selectedItems.includes(item)) {
1442
+ tree.setSelectedItems([item.getItemMeta().itemId]);
1443
+ }
1444
+ if (!((_b = (_a = config.canDrag) == null ? void 0 : _a.call(config, items)) != null ? _b : true)) {
1445
+ e.preventDefault();
1446
+ return;
1447
+ }
1448
+ if (config.setDragImage) {
1449
+ const { imgElement, xOffset, yOffset } = config.setDragImage(items);
1450
+ (_c = e.dataTransfer) == null ? void 0 : _c.setDragImage(imgElement, xOffset != null ? xOffset : 0, yOffset != null ? yOffset : 0);
1451
+ }
1452
+ if (config.createForeignDragObject && e.dataTransfer) {
1453
+ const { format, data, dropEffect, effectAllowed } = config.createForeignDragObject(items);
1454
+ e.dataTransfer.setData(format, data);
1455
+ if (dropEffect) e.dataTransfer.dropEffect = dropEffect;
1456
+ if (effectAllowed) e.dataTransfer.effectAllowed = effectAllowed;
1457
+ }
1458
+ tree.applySubStateUpdate("dnd", {
1459
+ draggedItems: items,
1460
+ draggingOverItem: tree.getFocusedItem()
1461
+ });
1462
+ },
1463
+ onDragOver: (e) => {
1464
+ var _a, _b, _c;
1465
+ e.stopPropagation();
1466
+ const dataRef = tree.getDataRef();
1467
+ const nextDragCode = getDragCode(e, item, tree);
1468
+ if (nextDragCode === dataRef.current.lastDragCode) {
1469
+ if (dataRef.current.lastAllowDrop) {
1470
+ e.preventDefault();
1471
+ }
1472
+ return;
1473
+ }
1474
+ dataRef.current.lastDragCode = nextDragCode;
1475
+ dataRef.current.lastDragEnter = Date.now();
1476
+ const target = getDragTarget(e, item, tree);
1477
+ if (!((_a = tree.getState().dnd) == null ? void 0 : _a.draggedItems) && (!e.dataTransfer || !((_c = (_b = tree.getConfig()).canDragForeignDragObjectOver) == null ? void 0 : _c.call(_b, e.dataTransfer, target)))) {
1478
+ dataRef.current.lastAllowDrop = false;
1479
+ return;
1480
+ }
1481
+ if (!canDrop(e.dataTransfer, target, tree)) {
1482
+ dataRef.current.lastAllowDrop = false;
1483
+ return;
1484
+ }
1485
+ tree.applySubStateUpdate("dnd", (state) => __spreadProps(__spreadValues({}, state), {
1486
+ dragTarget: target,
1487
+ draggingOverItem: item
1488
+ }));
1489
+ dataRef.current.lastAllowDrop = true;
1490
+ e.preventDefault();
1491
+ },
1492
+ onDragLeave: () => {
1493
+ setTimeout(() => {
1494
+ var _a;
1495
+ const dataRef = tree.getDataRef();
1496
+ if (((_a = dataRef.current.lastDragEnter) != null ? _a : 0) + 100 >= Date.now()) return;
1497
+ dataRef.current.lastDragCode = "no-drag";
1498
+ tree.applySubStateUpdate("dnd", (state) => __spreadProps(__spreadValues({}, state), {
1499
+ draggingOverItem: void 0,
1500
+ dragTarget: void 0
1501
+ }));
1502
+ }, 100);
1503
+ },
1504
+ onDragEnd: (e) => {
1505
+ var _a, _b;
1506
+ const { onCompleteForeignDrop, canDragForeignDragObjectOver } = tree.getConfig();
1507
+ const draggedItems = (_a = tree.getState().dnd) == null ? void 0 : _a.draggedItems;
1508
+ if (((_b = e.dataTransfer) == null ? void 0 : _b.dropEffect) === "none" || !draggedItems) {
1509
+ return;
1510
+ }
1511
+ const target = getDragTarget(e, item, tree);
1512
+ if (canDragForeignDragObjectOver && e.dataTransfer && !canDragForeignDragObjectOver(e.dataTransfer, target)) {
1513
+ return;
1514
+ }
1515
+ onCompleteForeignDrop == null ? void 0 : onCompleteForeignDrop(draggedItems);
1516
+ },
1517
+ onDrop: (e) => __async(null, null, function* () {
1518
+ var _a, _b, _c;
1519
+ e.stopPropagation();
1520
+ const dataRef = tree.getDataRef();
1521
+ const target = getDragTarget(e, item, tree);
1522
+ if (!canDrop(e.dataTransfer, target, tree)) {
1523
+ return;
1524
+ }
1525
+ e.preventDefault();
1526
+ const config = tree.getConfig();
1527
+ const draggedItems = (_a = tree.getState().dnd) == null ? void 0 : _a.draggedItems;
1528
+ dataRef.current.lastDragCode = void 0;
1529
+ if (draggedItems) {
1530
+ yield (_b = config.onDrop) == null ? void 0 : _b.call(config, draggedItems, target);
1531
+ } else if (e.dataTransfer) {
1532
+ yield (_c = config.onDropForeignDragObject) == null ? void 0 : _c.call(config, e.dataTransfer, target);
1533
+ }
1534
+ })
1535
+ }),
1536
+ isDragTarget: ({ tree, item }) => {
1537
+ const target = tree.getDragTarget();
1538
+ return target ? target.item.getId() === item.getId() : false;
1539
+ },
1540
+ isDragTargetAbove: ({ tree, item }) => {
1541
+ const target = tree.getDragTarget();
1542
+ if (!target || !isOrderedDragTarget(target) || target.item !== item.getParent())
1543
+ return false;
1544
+ return target.childIndex === item.getItemMeta().posInSet;
1545
+ },
1546
+ isDragTargetBelow: ({ tree, item }) => {
1547
+ const target = tree.getDragTarget();
1548
+ if (!target || !isOrderedDragTarget(target) || target.item !== item.getParent())
1549
+ return false;
1550
+ return target.childIndex - 1 === item.getItemMeta().posInSet;
1551
+ },
1552
+ isDraggingOver: ({ tree, item }) => {
1553
+ var _a, _b;
1554
+ return ((_b = (_a = tree.getState().dnd) == null ? void 0 : _a.draggingOverItem) == null ? void 0 : _b.getId()) === item.getId();
1555
+ }
1556
+ }
1557
+ };
1558
+
1559
+ // src/features/keyboard-drag-and-drop/feature.ts
1560
+ var getNextDragTarget = (tree, isUp, dragTarget) => {
1561
+ var _a, _b, _c, _d;
1562
+ const direction = isUp ? 0 : 1;
1563
+ const draggedItems = (_a = tree.getState().dnd) == null ? void 0 : _a.draggedItems;
1564
+ if (isOrderedDragTarget(dragTarget)) {
1565
+ const parent = dragTarget.item.getParent();
1566
+ const targetedItem = tree.getItems()[dragTarget.dragLineIndex - 1];
1567
+ const targetCategory = targetedItem ? getItemDropCategory(targetedItem) : 0 /* Item */;
1568
+ const maxLevel = (_b = targetedItem == null ? void 0 : targetedItem.getItemMeta().level) != null ? _b : 0;
1569
+ const minLevel = (_d = (_c = targetedItem == null ? void 0 : targetedItem.getItemBelow()) == null ? void 0 : _c.getItemMeta().level) != null ? _d : 0;
1570
+ if (targetCategory === 2 /* LastInGroup */) {
1571
+ if (isUp && dragTarget.dragLineLevel < maxLevel) {
1572
+ return getReparentTarget(
1573
+ targetedItem,
1574
+ dragTarget.dragLineLevel + 1,
1575
+ draggedItems
1576
+ );
1577
+ }
1578
+ if (!isUp && dragTarget.dragLineLevel > minLevel && parent) {
1579
+ return getReparentTarget(
1580
+ targetedItem,
1581
+ dragTarget.dragLineLevel - 1,
1582
+ draggedItems
1583
+ );
1584
+ }
1585
+ }
1586
+ const newIndex = dragTarget.dragLineIndex - 1 + direction;
1587
+ const item = tree.getItems()[newIndex];
1588
+ return item ? { item } : void 0;
1589
+ }
1590
+ const targetingExpandedFolder = getItemDropCategory(dragTarget.item) === 1 /* ExpandedFolder */;
1591
+ if (targetingExpandedFolder && !isUp) {
1592
+ return {
1593
+ item: dragTarget.item,
1594
+ childIndex: 0,
1595
+ insertionIndex: getInsertionIndex(
1596
+ dragTarget.item.getChildren(),
1597
+ 0,
1598
+ draggedItems
1599
+ ),
1600
+ dragLineIndex: dragTarget.item.getItemMeta().index + direction,
1601
+ dragLineLevel: dragTarget.item.getItemMeta().level + 1
1602
+ };
1603
+ }
1604
+ const childIndex = dragTarget.item.getIndexInParent() + direction;
1605
+ return {
1606
+ item: dragTarget.item.getParent(),
1607
+ childIndex,
1608
+ insertionIndex: getInsertionIndex(
1609
+ dragTarget.item.getParent().getChildren(),
1610
+ childIndex,
1611
+ draggedItems
1612
+ ),
1613
+ dragLineIndex: dragTarget.item.getItemMeta().index + direction,
1614
+ dragLineLevel: dragTarget.item.getItemMeta().level
1615
+ };
1616
+ };
1617
+ var getNextValidDragTarget = (tree, isUp, previousTarget = ((_a) => (_a = tree.getState().dnd) == null ? void 0 : _a.dragTarget)()) => {
1618
+ var _a2;
1619
+ if (!previousTarget) return void 0;
1620
+ const nextTarget = getNextDragTarget(tree, isUp, previousTarget);
1621
+ const dataTransfer = (_a2 = tree.getDataRef().current.kDndDataTransfer) != null ? _a2 : null;
1622
+ if (!nextTarget) return void 0;
1623
+ if (canDrop(dataTransfer, nextTarget, tree)) {
1624
+ return nextTarget;
1625
+ }
1626
+ return getNextValidDragTarget(tree, isUp, nextTarget);
1627
+ };
1628
+ var updateScroll = (tree) => {
1629
+ const state = tree.getState().dnd;
1630
+ if (!(state == null ? void 0 : state.dragTarget) || isOrderedDragTarget(state.dragTarget)) return;
1631
+ state.dragTarget.item.scrollTo({ block: "nearest", inline: "nearest" });
1632
+ };
1633
+ var initiateDrag = (tree, draggedItems, dataTransfer) => {
1634
+ var _a, _b;
1635
+ const focusedItem = tree.getFocusedItem();
1636
+ const { canDrag } = tree.getConfig();
1637
+ if (draggedItems && canDrag && !canDrag(draggedItems)) {
1638
+ return;
1639
+ }
1640
+ if (draggedItems) {
1641
+ tree.applySubStateUpdate("dnd", { draggedItems });
1642
+ (_b = (_a = tree.getConfig()).onStartKeyboardDrag) == null ? void 0 : _b.call(_a, draggedItems);
1643
+ } else if (dataTransfer) {
1644
+ tree.getDataRef().current.kDndDataTransfer = dataTransfer;
1645
+ }
1646
+ const dragTarget = getNextValidDragTarget(tree, false, {
1647
+ item: focusedItem
1648
+ });
1649
+ if (!dragTarget) return;
1650
+ tree.applySubStateUpdate("dnd", {
1651
+ draggedItems,
1652
+ dragTarget
1653
+ });
1654
+ tree.applySubStateUpdate("assistiveDndState", 1 /* Started */);
1655
+ updateScroll(tree);
1656
+ };
1657
+ var moveDragPosition = (tree, isUp) => {
1658
+ var _a;
1659
+ const dragTarget = getNextValidDragTarget(tree, isUp);
1660
+ if (!dragTarget) return;
1661
+ tree.applySubStateUpdate("dnd", {
1662
+ draggedItems: (_a = tree.getState().dnd) == null ? void 0 : _a.draggedItems,
1663
+ dragTarget
1664
+ });
1665
+ tree.applySubStateUpdate("assistiveDndState", 2 /* Dragging */);
1666
+ if (!isOrderedDragTarget(dragTarget)) {
1667
+ dragTarget.item.setFocused();
1668
+ }
1669
+ updateScroll(tree);
1670
+ };
1671
+ var keyboardDragAndDropFeature = {
1672
+ key: "keyboard-drag-and-drop",
1673
+ deps: ["drag-and-drop"],
1674
+ getDefaultConfig: (defaultConfig, tree) => __spreadValues({
1675
+ setAssistiveDndState: makeStateUpdater("assistiveDndState", tree)
1676
+ }, defaultConfig),
1677
+ stateHandlerNames: {
1678
+ assistiveDndState: "setAssistiveDndState"
1679
+ },
1680
+ treeInstance: {
1681
+ startKeyboardDrag: ({ tree }, draggedItems) => {
1682
+ initiateDrag(tree, draggedItems, void 0);
1683
+ },
1684
+ startKeyboardDragOnForeignObject: ({ tree }, dataTransfer) => {
1685
+ initiateDrag(tree, void 0, dataTransfer);
1686
+ },
1687
+ stopKeyboardDrag: ({ tree }) => {
1688
+ tree.getDataRef().current.kDndDataTransfer = void 0;
1689
+ tree.applySubStateUpdate("dnd", null);
1690
+ tree.applySubStateUpdate("assistiveDndState", 0 /* None */);
1691
+ }
1692
+ },
1693
+ hotkeys: {
1694
+ startDrag: {
1695
+ hotkey: "Control+Shift+KeyD",
1696
+ preventDefault: true,
1697
+ isEnabled: (tree) => !tree.getState().dnd,
1698
+ handler: (_, tree) => {
1699
+ const selectedItems = tree.getSelectedItems();
1700
+ const focusedItem = tree.getFocusedItem();
1701
+ tree.startKeyboardDrag(
1702
+ selectedItems.includes(focusedItem) ? selectedItems : selectedItems.concat(focusedItem)
1703
+ );
1704
+ }
1705
+ },
1706
+ dragUp: {
1707
+ hotkey: "ArrowUp",
1708
+ preventDefault: true,
1709
+ isEnabled: (tree) => !!tree.getState().dnd,
1710
+ handler: (_, tree) => {
1711
+ moveDragPosition(tree, true);
1712
+ }
1713
+ },
1714
+ dragDown: {
1715
+ hotkey: "ArrowDown",
1716
+ preventDefault: true,
1717
+ isEnabled: (tree) => !!tree.getState().dnd,
1718
+ handler: (_, tree) => {
1719
+ moveDragPosition(tree, false);
1720
+ }
1721
+ },
1722
+ cancelDrag: {
1723
+ hotkey: "Escape",
1724
+ isEnabled: (tree) => !!tree.getState().dnd,
1725
+ handler: (_, tree) => {
1726
+ tree.stopKeyboardDrag();
1727
+ }
1728
+ },
1729
+ completeDrag: {
1730
+ hotkey: "Enter",
1731
+ preventDefault: true,
1732
+ isEnabled: (tree) => !!tree.getState().dnd,
1733
+ handler: (e, tree) => __async(null, null, function* () {
1734
+ var _a, _b, _c, _d;
1735
+ e.stopPropagation();
1736
+ const dataRef = tree.getDataRef();
1737
+ const target = tree.getDragTarget();
1738
+ const dataTransfer = (_a = dataRef.current.kDndDataTransfer) != null ? _a : null;
1739
+ if (!target || !canDrop(dataTransfer, target, tree)) {
1740
+ return;
1741
+ }
1742
+ const config = tree.getConfig();
1743
+ const draggedItems = (_b = tree.getState().dnd) == null ? void 0 : _b.draggedItems;
1744
+ dataRef.current.lastDragCode = void 0;
1745
+ tree.applySubStateUpdate("dnd", null);
1746
+ if (draggedItems) {
1747
+ yield (_c = config.onDrop) == null ? void 0 : _c.call(config, draggedItems, target);
1748
+ tree.getItemInstance(draggedItems[0].getId()).setFocused();
1749
+ } else if (dataTransfer) {
1750
+ yield (_d = config.onDropForeignDragObject) == null ? void 0 : _d.call(config, dataTransfer, target);
1751
+ }
1752
+ tree.applySubStateUpdate(
1753
+ "assistiveDndState",
1754
+ 3 /* Completed */
1755
+ );
1756
+ })
1757
+ }
1758
+ }
1759
+ };
1760
+
1761
+ // src/features/search/feature.ts
1762
+ var searchFeature = {
1763
+ key: "search",
1764
+ getInitialState: (initialState) => __spreadValues({
1765
+ search: null
1766
+ }, initialState),
1767
+ getDefaultConfig: (defaultConfig, tree) => __spreadValues({
1768
+ setSearch: makeStateUpdater("search", tree),
1769
+ isSearchMatchingItem: (search, item) => search.length > 0 && item.getItemName().toLowerCase().includes(search.toLowerCase())
1770
+ }, defaultConfig),
1771
+ stateHandlerNames: {
1772
+ search: "setSearch"
1773
+ },
1774
+ treeInstance: {
1775
+ setSearch: ({ tree }, search) => {
1776
+ var _a;
1777
+ tree.applySubStateUpdate("search", search);
1778
+ (_a = tree.getItems().find(
1779
+ (item) => {
1780
+ var _a2, _b;
1781
+ return (_b = (_a2 = tree.getConfig()).isSearchMatchingItem) == null ? void 0 : _b.call(_a2, tree.getSearchValue(), item);
1782
+ }
1783
+ )) == null ? void 0 : _a.setFocused();
1784
+ },
1785
+ openSearch: ({ tree }, initialValue = "") => {
1786
+ var _a, _b;
1787
+ tree.setSearch(initialValue);
1788
+ (_b = (_a = tree.getConfig()).onOpenSearch) == null ? void 0 : _b.call(_a);
1789
+ setTimeout(() => {
1790
+ var _a2;
1791
+ (_a2 = tree.getDataRef().current.searchInput) == null ? void 0 : _a2.focus();
1792
+ });
1793
+ },
1794
+ closeSearch: ({ tree }) => {
1795
+ var _a, _b;
1796
+ tree.setSearch(null);
1797
+ (_b = (_a = tree.getConfig()).onCloseSearch) == null ? void 0 : _b.call(_a);
1798
+ tree.updateDomFocus();
1799
+ },
1800
+ isSearchOpen: ({ tree }) => tree.getState().search !== null,
1801
+ getSearchValue: ({ tree }) => tree.getState().search || "",
1802
+ registerSearchInputElement: ({ tree }, element) => {
1803
+ const dataRef = tree.getDataRef();
1804
+ dataRef.current.searchInput = element;
1805
+ if (element && dataRef.current.keydownHandler) {
1806
+ element.addEventListener("keydown", dataRef.current.keydownHandler);
1807
+ }
1808
+ },
1809
+ getSearchInputElement: ({ tree }) => {
1810
+ var _a;
1811
+ return (_a = tree.getDataRef().current.searchInput) != null ? _a : null;
1812
+ },
1813
+ // TODO memoize with propMemoizationFeature
1814
+ getSearchInputElementProps: ({ tree }) => ({
1815
+ value: tree.getSearchValue(),
1816
+ onChange: (e) => tree.setSearch(e.target.value),
1817
+ onBlur: () => tree.closeSearch(),
1818
+ ref: tree.registerSearchInputElement
1819
+ }),
1820
+ getSearchMatchingItems: memo(
1821
+ ({ tree }) => [
1822
+ tree.getSearchValue(),
1823
+ tree.getItems(),
1824
+ tree.getConfig().isSearchMatchingItem
1825
+ ],
1826
+ (search, items, isSearchMatchingItem) => items.filter((item) => search && (isSearchMatchingItem == null ? void 0 : isSearchMatchingItem(search, item)))
1827
+ )
1828
+ },
1829
+ itemInstance: {
1830
+ isMatchingSearch: ({ tree, item }) => tree.getSearchMatchingItems().some((i) => i.getId() === item.getId())
1831
+ },
1832
+ hotkeys: {
1833
+ openSearch: {
1834
+ hotkey: "LetterOrNumber",
1835
+ preventDefault: true,
1836
+ // TODO make true default
1837
+ isEnabled: (tree) => !tree.isSearchOpen(),
1838
+ handler: (e, tree) => {
1839
+ e.stopPropagation();
1840
+ tree.openSearch(e.key);
1841
+ }
1842
+ },
1843
+ closeSearch: {
1844
+ // TODO allow multiple, i.e. Enter
1845
+ hotkey: "Escape",
1846
+ allowWhenInputFocused: true,
1847
+ isEnabled: (tree) => tree.isSearchOpen(),
1848
+ handler: (e, tree) => {
1849
+ tree.closeSearch();
1850
+ }
1851
+ },
1852
+ submitSearch: {
1853
+ hotkey: "Enter",
1854
+ allowWhenInputFocused: true,
1855
+ isEnabled: (tree) => tree.isSearchOpen(),
1856
+ handler: (e, tree) => {
1857
+ tree.closeSearch();
1858
+ tree.setSelectedItems([tree.getFocusedItem().getId()]);
1859
+ }
1860
+ },
1861
+ nextSearchItem: {
1862
+ hotkey: "ArrowDown",
1863
+ allowWhenInputFocused: true,
1864
+ canRepeat: true,
1865
+ isEnabled: (tree) => tree.isSearchOpen(),
1866
+ handler: (e, tree) => {
1867
+ const focusItem = tree.getSearchMatchingItems().find(
1868
+ (item) => item.getItemMeta().index > tree.getFocusedItem().getItemMeta().index
1869
+ );
1870
+ focusItem == null ? void 0 : focusItem.setFocused();
1871
+ focusItem == null ? void 0 : focusItem.scrollTo({ block: "nearest", inline: "nearest" });
1872
+ }
1873
+ },
1874
+ previousSearchItem: {
1875
+ hotkey: "ArrowUp",
1876
+ allowWhenInputFocused: true,
1877
+ canRepeat: true,
1878
+ isEnabled: (tree) => tree.isSearchOpen(),
1879
+ handler: (e, tree) => {
1880
+ const focusItem = [...tree.getSearchMatchingItems()].reverse().find(
1881
+ (item) => item.getItemMeta().index < tree.getFocusedItem().getItemMeta().index
1882
+ );
1883
+ focusItem == null ? void 0 : focusItem.setFocused();
1884
+ focusItem == null ? void 0 : focusItem.scrollTo({ block: "nearest", inline: "nearest" });
1885
+ }
1886
+ }
1887
+ }
1888
+ };
1889
+
1890
+ // src/features/renaming/feature.ts
1891
+ var renamingFeature = {
1892
+ key: "renaming",
1893
+ overwrites: ["drag-and-drop"],
1894
+ getDefaultConfig: (defaultConfig, tree) => __spreadValues({
1895
+ setRenamingItem: makeStateUpdater("renamingItem", tree),
1896
+ setRenamingValue: makeStateUpdater("renamingValue", tree),
1897
+ canRename: () => true
1898
+ }, defaultConfig),
1899
+ stateHandlerNames: {
1900
+ renamingItem: "setRenamingItem",
1901
+ renamingValue: "setRenamingValue"
1902
+ },
1903
+ treeInstance: {
1904
+ getRenamingItem: ({ tree }) => {
1905
+ const itemId = tree.getState().renamingItem;
1906
+ return itemId ? tree.getItemInstance(itemId) : null;
1907
+ },
1908
+ getRenamingValue: ({ tree }) => tree.getState().renamingValue || "",
1909
+ abortRenaming: ({ tree }) => {
1910
+ tree.applySubStateUpdate("renamingItem", null);
1911
+ tree.updateDomFocus();
1912
+ },
1913
+ completeRenaming: ({ tree }) => {
1914
+ var _a;
1915
+ const config = tree.getConfig();
1916
+ const item = tree.getRenamingItem();
1917
+ if (item) {
1918
+ (_a = config.onRename) == null ? void 0 : _a.call(config, item, tree.getState().renamingValue || "");
1919
+ }
1920
+ tree.applySubStateUpdate("renamingItem", null);
1921
+ tree.updateDomFocus();
1922
+ },
1923
+ isRenamingItem: ({ tree }) => !!tree.getState().renamingItem
1924
+ },
1925
+ itemInstance: {
1926
+ startRenaming: ({ tree, item, itemId }) => {
1927
+ if (!item.canRename()) {
1928
+ return;
1929
+ }
1930
+ tree.applySubStateUpdate("renamingItem", itemId);
1931
+ tree.applySubStateUpdate("renamingValue", item.getItemName());
1932
+ },
1933
+ getRenameInputProps: ({ tree }) => ({
1934
+ ref: (r) => r == null ? void 0 : r.focus(),
1935
+ onBlur: () => tree.abortRenaming(),
1936
+ value: tree.getRenamingValue(),
1937
+ onChange: (e) => {
1938
+ var _a;
1939
+ tree.applySubStateUpdate("renamingValue", (_a = e.target) == null ? void 0 : _a.value);
1940
+ }
1941
+ }),
1942
+ canRename: ({ tree, item }) => {
1943
+ var _a, _b, _c;
1944
+ return (_c = (_b = (_a = tree.getConfig()).canRename) == null ? void 0 : _b.call(_a, item)) != null ? _c : true;
1945
+ },
1946
+ isRenaming: ({ tree, item }) => item.getId() === tree.getState().renamingItem,
1947
+ getProps: ({ prev, item }) => {
1948
+ var _a;
1949
+ const isRenaming = item.isRenaming();
1950
+ const prevProps = (_a = prev == null ? void 0 : prev()) != null ? _a : {};
1951
+ return isRenaming ? __spreadProps(__spreadValues({}, prevProps), {
1952
+ draggable: false,
1953
+ onDragStart: () => {
1954
+ }
1955
+ }) : prevProps;
1956
+ }
1957
+ },
1958
+ hotkeys: {
1959
+ renameItem: {
1960
+ hotkey: "F2",
1961
+ handler: (e, tree) => {
1962
+ tree.getFocusedItem().startRenaming();
1963
+ }
1964
+ },
1965
+ abortRenaming: {
1966
+ hotkey: "Escape",
1967
+ allowWhenInputFocused: true,
1968
+ isEnabled: (tree) => tree.isRenamingItem(),
1969
+ handler: (e, tree) => {
1970
+ tree.abortRenaming();
1971
+ }
1972
+ },
1973
+ completeRenaming: {
1974
+ hotkey: "Enter",
1975
+ allowWhenInputFocused: true,
1976
+ isEnabled: (tree) => tree.isRenamingItem(),
1977
+ handler: (e, tree) => {
1978
+ tree.completeRenaming();
1979
+ }
1980
+ }
1981
+ }
1982
+ };
1983
+
1984
+ // src/features/expand-all/feature.ts
1985
+ var expandAllFeature = {
1986
+ key: "expand-all",
1987
+ treeInstance: {
1988
+ expandAll: (_0, _1) => __async(null, [_0, _1], function* ({ tree }, cancelToken) {
1989
+ yield Promise.all(
1990
+ tree.getItems().map((item) => item.expandAll(cancelToken))
1991
+ );
1992
+ }),
1993
+ collapseAll: ({ tree }) => {
1994
+ tree.applySubStateUpdate("expandedItems", []);
1995
+ tree.rebuildTree();
1996
+ }
1997
+ },
1998
+ itemInstance: {
1999
+ expandAll: (_0, _1) => __async(null, [_0, _1], function* ({ tree, item }, cancelToken) {
2000
+ if (cancelToken == null ? void 0 : cancelToken.current) {
2001
+ return;
2002
+ }
2003
+ if (!item.isFolder()) {
2004
+ return;
2005
+ }
2006
+ item.expand();
2007
+ yield tree.waitForItemChildrenLoaded(item.getId());
2008
+ yield Promise.all(
2009
+ item.getChildren().map((child) => __async(null, null, function* () {
2010
+ yield tree.waitForItemChildrenLoaded(item.getId());
2011
+ yield child == null ? void 0 : child.expandAll(cancelToken);
2012
+ }))
2013
+ );
2014
+ }),
2015
+ collapseAll: ({ item }) => {
2016
+ if (!item.isExpanded()) return;
2017
+ for (const child of item.getChildren()) {
2018
+ child == null ? void 0 : child.collapseAll();
2019
+ }
2020
+ item.collapse();
2021
+ }
2022
+ },
2023
+ hotkeys: {
2024
+ expandSelected: {
2025
+ hotkey: "Control+Shift+Plus",
2026
+ handler: (_, tree) => __async(null, null, function* () {
2027
+ const cancelToken = { current: false };
2028
+ const cancelHandler = (e) => {
2029
+ if (e.code === "Escape") {
2030
+ cancelToken.current = true;
2031
+ }
2032
+ };
2033
+ document.addEventListener("keydown", cancelHandler);
2034
+ yield Promise.all(
2035
+ tree.getSelectedItems().map((item) => item.expandAll(cancelToken))
2036
+ );
2037
+ document.removeEventListener("keydown", cancelHandler);
2038
+ })
2039
+ },
2040
+ collapseSelected: {
2041
+ hotkey: "Control+Shift+Minus",
2042
+ handler: (_, tree) => {
2043
+ tree.getSelectedItems().forEach((item) => item.collapseAll());
2044
+ }
2045
+ }
2046
+ }
2047
+ };
2048
+
2049
+ // src/features/prop-memoization/feature.ts
2050
+ var memoize = (props, memoizedProps) => {
2051
+ for (const key in props) {
2052
+ if (typeof props[key] === "function") {
2053
+ if (memoizedProps && key in memoizedProps) {
2054
+ props[key] = memoizedProps[key];
2055
+ } else {
2056
+ memoizedProps[key] = props[key];
2057
+ }
2058
+ }
2059
+ }
2060
+ return props;
2061
+ };
2062
+ var propMemoizationFeature = {
2063
+ key: "prop-memoization",
2064
+ overwrites: [
2065
+ "main",
2066
+ "async-data-loader",
2067
+ "sync-data-loader",
2068
+ "drag-and-drop",
2069
+ "expand-all",
2070
+ "hotkeys-core",
2071
+ "renaming",
2072
+ "search",
2073
+ "selection"
2074
+ ],
2075
+ treeInstance: {
2076
+ getContainerProps: ({ tree, prev }, treeLabel) => {
2077
+ var _a, _b, _c, _d, _e;
2078
+ const dataRef = tree.getDataRef();
2079
+ const props = (_a = prev == null ? void 0 : prev(treeLabel)) != null ? _a : {};
2080
+ (_c = (_b = dataRef.current).memo) != null ? _c : _b.memo = {};
2081
+ (_e = (_d = dataRef.current.memo).tree) != null ? _e : _d.tree = {};
2082
+ return memoize(props, dataRef.current.memo.tree);
2083
+ },
2084
+ getSearchInputElementProps: ({ tree, prev }) => {
2085
+ var _a, _b, _c, _d, _e;
2086
+ const dataRef = tree.getDataRef();
2087
+ const props = (_a = prev == null ? void 0 : prev()) != null ? _a : {};
2088
+ (_c = (_b = dataRef.current).memo) != null ? _c : _b.memo = {};
2089
+ (_e = (_d = dataRef.current.memo).search) != null ? _e : _d.search = {};
2090
+ return memoize(props, dataRef.current.memo.search);
2091
+ }
2092
+ },
2093
+ itemInstance: {
2094
+ getProps: ({ item, prev }) => {
2095
+ var _a, _b, _c, _d, _e;
2096
+ const dataRef = item.getDataRef();
2097
+ const props = (_a = prev == null ? void 0 : prev()) != null ? _a : {};
2098
+ (_c = (_b = dataRef.current).memo) != null ? _c : _b.memo = {};
2099
+ (_e = (_d = dataRef.current.memo).item) != null ? _e : _d.item = {};
2100
+ return memoize(props, dataRef.current.memo.item);
2101
+ },
2102
+ getRenameInputProps: ({ item, prev }) => {
2103
+ var _a, _b, _c, _d, _e;
2104
+ const dataRef = item.getDataRef();
2105
+ const props = (_a = prev == null ? void 0 : prev()) != null ? _a : {};
2106
+ (_c = (_b = dataRef.current).memo) != null ? _c : _b.memo = {};
2107
+ (_e = (_d = dataRef.current.memo).rename) != null ? _e : _d.rename = {};
2108
+ return memoize(props, dataRef.current.memo.rename);
2109
+ }
2110
+ }
2111
+ };
2112
+
2113
+ // src/utilities/remove-items-from-parents.ts
2114
+ var removeItemsFromParents = (movedItems, onChangeChildren) => __async(null, null, function* () {
2115
+ const movedItemsIds = movedItems.map((item) => item.getId());
2116
+ const uniqueParents = [
2117
+ ...new Set(movedItems.map((item) => item.getParent()))
2118
+ ];
2119
+ for (const parent of uniqueParents) {
2120
+ const siblings = parent == null ? void 0 : parent.getChildren();
2121
+ if (siblings && parent) {
2122
+ const newChildren = siblings.filter((sibling) => !movedItemsIds.includes(sibling.getId())).map((i) => i.getId());
2123
+ yield onChangeChildren(parent, newChildren);
2124
+ if (parent && "updateCachedChildrenIds" in parent) {
2125
+ parent == null ? void 0 : parent.updateCachedChildrenIds(newChildren);
2126
+ }
2127
+ }
2128
+ }
2129
+ movedItems[0].getTree().rebuildTree();
2130
+ });
2131
+
2132
+ // src/utilities/insert-items-at-target.ts
2133
+ var insertItemsAtTarget = (itemIds, target, onChangeChildren) => __async(null, null, function* () {
2134
+ yield target.item.getTree().waitForItemChildrenLoaded(target.item.getId());
2135
+ const oldChildrenIds = target.item.getTree().retrieveChildrenIds(target.item.getId());
2136
+ if (!("childIndex" in target)) {
2137
+ const newChildren2 = [...oldChildrenIds, ...itemIds];
2138
+ yield onChangeChildren(target.item, newChildren2);
2139
+ if (target.item && "updateCachedChildrenIds" in target.item) {
2140
+ target.item.updateCachedChildrenIds(newChildren2);
2141
+ }
2142
+ target.item.getTree().rebuildTree();
2143
+ return;
2144
+ }
2145
+ const newChildren = [
2146
+ ...oldChildrenIds.slice(0, target.insertionIndex),
2147
+ ...itemIds,
2148
+ ...oldChildrenIds.slice(target.insertionIndex)
2149
+ ];
2150
+ yield onChangeChildren(target.item, newChildren);
2151
+ if (target.item && "updateCachedChildrenIds" in target.item) {
2152
+ target.item.updateCachedChildrenIds(newChildren);
2153
+ }
2154
+ target.item.getTree().rebuildTree();
2155
+ });
2156
+
2157
+ // src/utilities/create-on-drop-handler.ts
2158
+ var createOnDropHandler = (onChangeChildren) => (items, target) => __async(null, null, function* () {
2159
+ const itemIds = items.map((item) => item.getId());
2160
+ yield removeItemsFromParents(items, onChangeChildren);
2161
+ yield insertItemsAtTarget(itemIds, target, onChangeChildren);
2162
+ });
2163
+
2164
+ // src/core/build-proxified-instance.ts
2165
+ var noop = () => {
2166
+ };
2167
+ var findPrevInstanceMethod = (features, instanceType, methodKey, featureSearchIndex) => {
2168
+ var _a;
2169
+ for (let i = featureSearchIndex; i >= 0; i--) {
2170
+ const feature = features[i];
2171
+ const itemInstanceMethod = (_a = feature[instanceType]) == null ? void 0 : _a[methodKey];
2172
+ if (itemInstanceMethod) {
2173
+ return i;
2174
+ }
2175
+ }
2176
+ return null;
2177
+ };
2178
+ var invokeInstanceMethod = (features, instanceType, opts, methodKey, featureIndex, args) => {
2179
+ var _a;
2180
+ const prevIndex = findPrevInstanceMethod(
2181
+ features,
2182
+ instanceType,
2183
+ methodKey,
2184
+ featureIndex - 1
2185
+ );
2186
+ const itemInstanceMethod = (_a = features[featureIndex][instanceType]) == null ? void 0 : _a[methodKey];
2187
+ return itemInstanceMethod(
2188
+ __spreadProps(__spreadValues({}, opts), {
2189
+ prev: prevIndex !== null ? (...newArgs) => invokeInstanceMethod(
2190
+ features,
2191
+ instanceType,
2192
+ opts,
2193
+ methodKey,
2194
+ prevIndex,
2195
+ newArgs
2196
+ ) : null
2197
+ }),
2198
+ ...args
2199
+ );
2200
+ };
2201
+ var buildProxiedInstance = (features, instanceType, buildOpts) => {
2202
+ const opts = {};
2203
+ const item = new Proxy(
2204
+ {},
2205
+ {
2206
+ has(target, key) {
2207
+ if (typeof key === "symbol") {
2208
+ return false;
2209
+ }
2210
+ if (key === "toJSON") {
2211
+ return false;
2212
+ }
2213
+ const hasInstanceMethod = findPrevInstanceMethod(
2214
+ features,
2215
+ instanceType,
2216
+ key,
2217
+ features.length - 1
2218
+ );
2219
+ return Boolean(hasInstanceMethod);
2220
+ },
2221
+ get(target, key) {
2222
+ if (typeof key === "symbol") {
2223
+ return void 0;
2224
+ }
2225
+ if (key === "toJSON") {
2226
+ return {};
2227
+ }
2228
+ return (...args) => {
2229
+ const featureIndex = findPrevInstanceMethod(
2230
+ features,
2231
+ instanceType,
2232
+ key,
2233
+ features.length - 1
2234
+ );
2235
+ if (featureIndex === null) {
2236
+ throw throwError(`feature missing for method ${key}`);
2237
+ }
2238
+ return invokeInstanceMethod(
2239
+ features,
2240
+ instanceType,
2241
+ opts,
2242
+ key,
2243
+ featureIndex,
2244
+ args
2245
+ );
2246
+ };
2247
+ }
2248
+ }
2249
+ );
2250
+ Object.assign(opts, buildOpts(item));
2251
+ return [item, noop];
2252
+ };
2253
+ export {
2254
+ AssistiveDndState,
2255
+ CheckedState,
2256
+ DragTargetPosition,
2257
+ asyncDataLoaderFeature,
2258
+ buildProxiedInstance,
2259
+ buildStaticInstance,
2260
+ checkboxesFeature,
2261
+ createOnDropHandler,
2262
+ createTree,
2263
+ dragAndDropFeature,
2264
+ expandAllFeature,
2265
+ hotkeysCoreFeature,
2266
+ insertItemsAtTarget,
2267
+ isOrderedDragTarget,
2268
+ keyboardDragAndDropFeature,
2269
+ makeStateUpdater,
2270
+ propMemoizationFeature,
2271
+ removeItemsFromParents,
2272
+ renamingFeature,
2273
+ searchFeature,
2274
+ selectionFeature,
2275
+ syncDataLoaderFeature
2276
+ };