@headless-tree/core 0.0.0-20250725212154 → 0.0.0-20250726131830

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