@headless-tree/core 0.0.11 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/lib/cjs/core/build-static-instance.js +1 -2
- package/lib/cjs/core/create-tree.js +7 -4
- package/lib/cjs/features/async-data-loader/feature.d.ts +1 -4
- package/lib/cjs/features/async-data-loader/feature.js +5 -7
- package/lib/cjs/features/async-data-loader/types.d.ts +2 -5
- package/lib/cjs/features/drag-and-drop/feature.d.ts +2 -3
- package/lib/cjs/features/drag-and-drop/feature.js +27 -24
- package/lib/cjs/features/drag-and-drop/types.d.ts +3 -3
- package/lib/cjs/features/drag-and-drop/utils.d.ts +1 -1
- package/lib/cjs/features/drag-and-drop/utils.js +4 -4
- package/lib/cjs/features/expand-all/feature.d.ts +1 -5
- package/lib/cjs/features/hotkeys-core/feature.d.ts +1 -3
- package/lib/cjs/features/prop-memoization/feature.d.ts +2 -0
- package/lib/cjs/features/prop-memoization/feature.js +48 -0
- package/lib/cjs/features/prop-memoization/types.d.ts +10 -0
- package/lib/cjs/features/prop-memoization/types.js +2 -0
- package/lib/cjs/features/renaming/feature.d.ts +1 -4
- package/lib/cjs/features/renaming/feature.js +8 -9
- package/lib/cjs/features/renaming/types.d.ts +1 -1
- package/lib/cjs/features/search/feature.d.ts +1 -4
- package/lib/cjs/features/selection/feature.d.ts +1 -4
- package/lib/cjs/features/selection/feature.js +35 -25
- package/lib/cjs/features/selection/types.d.ts +1 -1
- package/lib/cjs/features/sync-data-loader/feature.d.ts +1 -3
- package/lib/cjs/features/tree/feature.d.ts +1 -6
- package/lib/cjs/features/tree/feature.js +40 -57
- package/lib/cjs/features/tree/types.d.ts +0 -5
- package/lib/cjs/index.d.ts +2 -0
- package/lib/cjs/index.js +2 -0
- package/lib/cjs/mddocs-entry.d.ts +10 -0
- package/lib/cjs/test-utils/test-tree-do.d.ts +1 -1
- package/lib/cjs/test-utils/test-tree-expect.d.ts +1 -1
- package/lib/cjs/test-utils/test-tree-expect.js +1 -1
- package/lib/cjs/test-utils/test-tree.d.ts +1 -1
- package/lib/cjs/test-utils/test-tree.js +9 -1
- package/lib/cjs/types/core.d.ts +29 -30
- package/lib/esm/core/build-static-instance.js +1 -2
- package/lib/esm/core/create-tree.js +7 -4
- package/lib/esm/features/async-data-loader/feature.d.ts +1 -4
- package/lib/esm/features/async-data-loader/feature.js +5 -7
- package/lib/esm/features/async-data-loader/types.d.ts +2 -5
- package/lib/esm/features/drag-and-drop/feature.d.ts +2 -3
- package/lib/esm/features/drag-and-drop/feature.js +27 -24
- package/lib/esm/features/drag-and-drop/types.d.ts +3 -3
- package/lib/esm/features/drag-and-drop/utils.d.ts +1 -1
- package/lib/esm/features/drag-and-drop/utils.js +4 -4
- package/lib/esm/features/expand-all/feature.d.ts +1 -5
- package/lib/esm/features/hotkeys-core/feature.d.ts +1 -3
- package/lib/esm/features/prop-memoization/feature.d.ts +2 -0
- package/lib/esm/features/prop-memoization/feature.js +45 -0
- package/lib/esm/features/prop-memoization/types.d.ts +10 -0
- package/lib/esm/features/prop-memoization/types.js +1 -0
- package/lib/esm/features/renaming/feature.d.ts +1 -4
- package/lib/esm/features/renaming/feature.js +8 -9
- package/lib/esm/features/renaming/types.d.ts +1 -1
- package/lib/esm/features/search/feature.d.ts +1 -4
- package/lib/esm/features/selection/feature.d.ts +1 -4
- package/lib/esm/features/selection/feature.js +35 -25
- package/lib/esm/features/selection/types.d.ts +1 -1
- package/lib/esm/features/sync-data-loader/feature.d.ts +1 -3
- package/lib/esm/features/tree/feature.d.ts +1 -6
- package/lib/esm/features/tree/feature.js +40 -57
- package/lib/esm/features/tree/types.d.ts +0 -5
- package/lib/esm/index.d.ts +2 -0
- package/lib/esm/index.js +2 -0
- package/lib/esm/mddocs-entry.d.ts +10 -0
- package/lib/esm/test-utils/test-tree-do.d.ts +1 -1
- package/lib/esm/test-utils/test-tree-expect.d.ts +1 -1
- package/lib/esm/test-utils/test-tree-expect.js +1 -1
- package/lib/esm/test-utils/test-tree.d.ts +1 -1
- package/lib/esm/test-utils/test-tree.js +9 -1
- package/lib/esm/types/core.d.ts +29 -30
- package/package.json +1 -1
- package/src/core/build-proxified-instance.ts +5 -3
- package/src/core/build-static-instance.ts +1 -2
- package/src/core/core.spec.ts +210 -0
- package/src/core/create-tree.ts +13 -16
- package/src/features/async-data-loader/async-data-loader.spec.ts +12 -31
- package/src/features/async-data-loader/feature.ts +8 -20
- package/src/features/async-data-loader/types.ts +2 -6
- package/src/features/drag-and-drop/drag-and-drop.spec.ts +4 -3
- package/src/features/drag-and-drop/feature.ts +87 -86
- package/src/features/drag-and-drop/types.ts +4 -4
- package/src/features/drag-and-drop/utils.ts +4 -4
- package/src/features/expand-all/expand-all.spec.ts +5 -1
- package/src/features/expand-all/feature.ts +1 -12
- package/src/features/hotkeys-core/feature.ts +4 -13
- package/src/features/prop-memoization/feature.ts +51 -0
- package/src/features/prop-memoization/prop-memoization.spec.ts +68 -0
- package/src/features/prop-memoization/types.ts +11 -0
- package/src/features/renaming/feature.ts +11 -20
- package/src/features/renaming/renaming.spec.ts +11 -9
- package/src/features/renaming/types.ts +1 -1
- package/src/features/search/feature.ts +2 -8
- package/src/features/search/search.spec.ts +3 -1
- package/src/features/selection/feature.ts +45 -47
- package/src/features/selection/selection.spec.ts +13 -14
- package/src/features/selection/types.ts +0 -2
- package/src/features/sync-data-loader/feature.ts +1 -7
- package/src/features/tree/feature.ts +47 -85
- package/src/features/tree/tree.spec.ts +24 -64
- package/src/features/tree/types.ts +0 -6
- package/src/index.ts +2 -0
- package/src/mddocs-entry.ts +13 -0
- package/src/test-utils/test-tree-expect.ts +1 -1
- package/src/test-utils/test-tree.ts +11 -1
- package/src/types/core.ts +56 -147
|
@@ -20,7 +20,6 @@ exports.treeFeature = {
|
|
|
20
20
|
focusedItem: "setFocusedItem",
|
|
21
21
|
},
|
|
22
22
|
treeInstance: {
|
|
23
|
-
isItemExpanded: ({ tree }, itemId) => tree.getState().expandedItems.includes(itemId),
|
|
24
23
|
getItemsMeta: ({ tree }) => {
|
|
25
24
|
const { rootItemId } = tree.getConfig();
|
|
26
25
|
const { expandedItems } = tree.getState();
|
|
@@ -52,44 +51,22 @@ exports.treeFeature = {
|
|
|
52
51
|
}
|
|
53
52
|
return flatItems;
|
|
54
53
|
},
|
|
55
|
-
expandItem: ({ tree }, itemId) => {
|
|
56
|
-
var _a;
|
|
57
|
-
if (!tree.getItemInstance(itemId).isFolder()) {
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
if ((_a = tree.getState().loadingItems) === null || _a === void 0 ? void 0 : _a.includes(itemId)) {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
tree.applySubStateUpdate("expandedItems", (expandedItems) => [
|
|
64
|
-
...expandedItems,
|
|
65
|
-
itemId,
|
|
66
|
-
]);
|
|
67
|
-
tree.rebuildTree();
|
|
68
|
-
},
|
|
69
|
-
collapseItem: ({ tree }, itemId) => {
|
|
70
|
-
if (!tree.getItemInstance(itemId).isFolder()) {
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
tree.applySubStateUpdate("expandedItems", (expandedItems) => expandedItems.filter((id) => id !== itemId));
|
|
74
|
-
tree.rebuildTree();
|
|
75
|
-
},
|
|
76
54
|
// TODO memo
|
|
77
55
|
getFocusedItem: ({ tree }) => {
|
|
78
56
|
var _a, _b;
|
|
79
57
|
return ((_b = tree.getItemInstance((_a = tree.getState().focusedItem) !== null && _a !== void 0 ? _a : "")) !== null && _b !== void 0 ? _b : tree.getItems()[0]);
|
|
80
58
|
},
|
|
81
|
-
focusItem: ({ tree }, itemId) => {
|
|
82
|
-
tree.applySubStateUpdate("focusedItem", itemId);
|
|
83
|
-
},
|
|
84
59
|
focusNextItem: ({ tree }) => {
|
|
60
|
+
var _a;
|
|
85
61
|
const { index } = tree.getFocusedItem().getItemMeta();
|
|
86
62
|
const nextIndex = Math.min(index + 1, tree.getItems().length - 1);
|
|
87
|
-
|
|
63
|
+
(_a = tree.getItems()[nextIndex]) === null || _a === void 0 ? void 0 : _a.setFocused();
|
|
88
64
|
},
|
|
89
65
|
focusPreviousItem: ({ tree }) => {
|
|
66
|
+
var _a;
|
|
90
67
|
const { index } = tree.getFocusedItem().getItemMeta();
|
|
91
68
|
const nextIndex = Math.max(index - 1, 0);
|
|
92
|
-
|
|
69
|
+
(_a = tree.getItems()[nextIndex]) === null || _a === void 0 ? void 0 : _a.setFocused();
|
|
93
70
|
},
|
|
94
71
|
updateDomFocus: ({ tree }) => {
|
|
95
72
|
// Required because if the state is managed outside in react, the state only updated during next render
|
|
@@ -104,7 +81,8 @@ exports.treeFeature = {
|
|
|
104
81
|
focusedElement.focus();
|
|
105
82
|
}));
|
|
106
83
|
},
|
|
107
|
-
|
|
84
|
+
// TODO add label parameter
|
|
85
|
+
getContainerProps: ({ prev, tree }) => (Object.assign(Object.assign({}, prev === null || prev === void 0 ? void 0 : prev()), { role: "tree", "aria-label": "", ref: tree.registerElement })),
|
|
108
86
|
// relevant for hotkeys of this feature
|
|
109
87
|
isSearchOpen: () => false,
|
|
110
88
|
},
|
|
@@ -115,10 +93,10 @@ exports.treeFeature = {
|
|
|
115
93
|
yield (0, utils_1.poll)(() => item.getElement() !== null, 20);
|
|
116
94
|
(_d = item.getElement()) === null || _d === void 0 ? void 0 : _d.scrollIntoView(scrollIntoViewArg);
|
|
117
95
|
}),
|
|
118
|
-
getId: ({
|
|
96
|
+
getId: ({ itemId }) => itemId,
|
|
119
97
|
getProps: ({ item, prev }) => {
|
|
120
98
|
const itemMeta = item.getItemMeta();
|
|
121
|
-
return Object.assign(Object.assign({}, prev === null || prev === void 0 ? void 0 : prev()), { role: "treeitem", "aria-setsize": itemMeta.setSize, "aria-posinset": itemMeta.posInSet, "aria-selected": "false", "aria-label": item.getItemName(), "aria-level": itemMeta.level, tabIndex: item.isFocused() ? 0 : -1, onClick:
|
|
99
|
+
return Object.assign(Object.assign({}, prev === null || prev === void 0 ? void 0 : prev()), { ref: item.registerElement, role: "treeitem", "aria-setsize": itemMeta.setSize, "aria-posinset": itemMeta.posInSet, "aria-selected": "false", "aria-label": item.getItemName(), "aria-level": itemMeta.level, tabIndex: item.isFocused() ? 0 : -1, onClick: (e) => {
|
|
122
100
|
item.setFocused();
|
|
123
101
|
item.primaryAction();
|
|
124
102
|
if (e.ctrlKey || e.shiftKey || e.metaKey) {
|
|
@@ -133,18 +111,37 @@ exports.treeFeature = {
|
|
|
133
111
|
else {
|
|
134
112
|
item.expand();
|
|
135
113
|
}
|
|
136
|
-
}
|
|
114
|
+
} });
|
|
115
|
+
},
|
|
116
|
+
expand: ({ tree, item, itemId }) => {
|
|
117
|
+
var _a;
|
|
118
|
+
if (!item.isFolder()) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if ((_a = tree.getState().loadingItems) === null || _a === void 0 ? void 0 : _a.includes(itemId)) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
tree.applySubStateUpdate("expandedItems", (expandedItems) => [
|
|
125
|
+
...expandedItems,
|
|
126
|
+
itemId,
|
|
127
|
+
]);
|
|
128
|
+
tree.rebuildTree();
|
|
137
129
|
},
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
130
|
+
collapse: ({ tree, item, itemId }) => {
|
|
131
|
+
if (!item.isFolder()) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
tree.applySubStateUpdate("expandedItems", (expandedItems) => expandedItems.filter((id) => id !== itemId));
|
|
135
|
+
tree.rebuildTree();
|
|
136
|
+
},
|
|
137
|
+
getItemData: ({ tree, itemId }) => tree.retrieveItemData(itemId),
|
|
141
138
|
equals: ({ item }, other) => item.getId() === (other === null || other === void 0 ? void 0 : other.getId()),
|
|
142
|
-
isExpanded: ({ tree,
|
|
139
|
+
isExpanded: ({ tree, itemId }) => tree.getState().expandedItems.includes(itemId),
|
|
143
140
|
isDescendentOf: ({ item }, parentId) => {
|
|
144
141
|
const parent = item.getParent();
|
|
145
142
|
return Boolean((parent === null || parent === void 0 ? void 0 : parent.getId()) === parentId || (parent === null || parent === void 0 ? void 0 : parent.isDescendentOf(parentId)));
|
|
146
143
|
},
|
|
147
|
-
isFocused: ({ tree, item }) => tree.getState().focusedItem ===
|
|
144
|
+
isFocused: ({ tree, item, itemId }) => tree.getState().focusedItem === itemId ||
|
|
148
145
|
(tree.getState().focusedItem === null && item.getItemMeta().index === 0),
|
|
149
146
|
isFolder: ({ tree, item }) => item.getItemMeta().level === -1 ||
|
|
150
147
|
tree.getConfig().isItemFolder(item),
|
|
@@ -152,12 +149,13 @@ exports.treeFeature = {
|
|
|
152
149
|
const config = tree.getConfig();
|
|
153
150
|
return config.getItemName(item);
|
|
154
151
|
},
|
|
155
|
-
setFocused: ({ tree,
|
|
152
|
+
setFocused: ({ tree, itemId }) => {
|
|
153
|
+
tree.applySubStateUpdate("focusedItem", itemId);
|
|
154
|
+
},
|
|
156
155
|
primaryAction: ({ tree, item }) => { var _a, _b; return (_b = (_a = tree.getConfig()).onPrimaryAction) === null || _b === void 0 ? void 0 : _b.call(_a, item); },
|
|
157
156
|
getParent: ({ tree, item }) => item.getItemMeta().parentId
|
|
158
157
|
? tree.getItemInstance(item.getItemMeta().parentId)
|
|
159
158
|
: undefined,
|
|
160
|
-
// TODO remove
|
|
161
159
|
getIndexInParent: ({ item }) => item.getItemMeta().posInSet,
|
|
162
160
|
getChildren: ({ tree, item }) => tree
|
|
163
161
|
.retrieveChildrenIds(item.getItemMeta().itemId)
|
|
@@ -165,23 +163,6 @@ exports.treeFeature = {
|
|
|
165
163
|
getTree: ({ tree }) => tree,
|
|
166
164
|
getItemAbove: ({ tree, item }) => tree.getItems()[item.getItemMeta().index - 1],
|
|
167
165
|
getItemBelow: ({ tree, item }) => tree.getItems()[item.getItemMeta().index + 1],
|
|
168
|
-
getMemoizedProp: ({ item }, name, create, deps) => {
|
|
169
|
-
var _a, _b, _c, _d, _e;
|
|
170
|
-
var _f, _g;
|
|
171
|
-
const data = item.getDataRef();
|
|
172
|
-
const memoizedValue = (_a = data.current.memoizedValues) === null || _a === void 0 ? void 0 : _a[name];
|
|
173
|
-
if (memoizedValue &&
|
|
174
|
-
(!deps ||
|
|
175
|
-
((_c = (_b = data.current.memoizedDeps) === null || _b === void 0 ? void 0 : _b[name]) === null || _c === void 0 ? void 0 : _c.every((d, i) => d === deps[i])))) {
|
|
176
|
-
return memoizedValue;
|
|
177
|
-
}
|
|
178
|
-
(_d = (_f = data.current).memoizedDeps) !== null && _d !== void 0 ? _d : (_f.memoizedDeps = {});
|
|
179
|
-
(_e = (_g = data.current).memoizedValues) !== null && _e !== void 0 ? _e : (_g.memoizedValues = {});
|
|
180
|
-
const value = create();
|
|
181
|
-
data.current.memoizedDeps[name] = deps;
|
|
182
|
-
data.current.memoizedValues[name] = value;
|
|
183
|
-
return value;
|
|
184
|
-
},
|
|
185
166
|
},
|
|
186
167
|
hotkeys: {
|
|
187
168
|
focusNextItem: {
|
|
@@ -237,14 +218,16 @@ exports.treeFeature = {
|
|
|
237
218
|
focusFirstItem: {
|
|
238
219
|
hotkey: "Home",
|
|
239
220
|
handler: (e, tree) => {
|
|
240
|
-
|
|
221
|
+
var _a;
|
|
222
|
+
(_a = tree.getItems()[0]) === null || _a === void 0 ? void 0 : _a.setFocused();
|
|
241
223
|
tree.updateDomFocus();
|
|
242
224
|
},
|
|
243
225
|
},
|
|
244
226
|
focusLastItem: {
|
|
245
227
|
hotkey: "End",
|
|
246
228
|
handler: (e, tree) => {
|
|
247
|
-
|
|
229
|
+
var _a;
|
|
230
|
+
(_a = tree.getItems()[tree.getItems().length - 1]) === null || _a === void 0 ? void 0 : _a.setFocused();
|
|
248
231
|
tree.updateDomFocus();
|
|
249
232
|
},
|
|
250
233
|
},
|
|
@@ -27,10 +27,6 @@ export type TreeFeatureDef<T> = {
|
|
|
27
27
|
treeInstance: {
|
|
28
28
|
/** @internal */
|
|
29
29
|
getItemsMeta: () => ItemMeta[];
|
|
30
|
-
expandItem: (itemId: string) => void;
|
|
31
|
-
collapseItem: (itemId: string) => void;
|
|
32
|
-
isItemExpanded: (itemId: string) => boolean;
|
|
33
|
-
focusItem: (itemId: string) => void;
|
|
34
30
|
getFocusedItem: () => ItemInstance<any>;
|
|
35
31
|
focusNextItem: () => void;
|
|
36
32
|
focusPreviousItem: () => void;
|
|
@@ -57,7 +53,6 @@ export type TreeFeatureDef<T> = {
|
|
|
57
53
|
getTree: () => TreeInstance<T>;
|
|
58
54
|
getItemAbove: () => ItemInstance<T> | undefined;
|
|
59
55
|
getItemBelow: () => ItemInstance<T> | undefined;
|
|
60
|
-
getMemoizedProp: <X>(name: string, create: () => X, deps?: any[]) => X;
|
|
61
56
|
scrollTo: (scrollIntoViewArg?: boolean | ScrollIntoViewOptions) => Promise<void>;
|
|
62
57
|
};
|
|
63
58
|
hotkeys: "focusNextItem" | "focusPreviousItem" | "expandOrDown" | "collapseOrUp" | "focusFirstItem" | "focusLastItem";
|
package/lib/cjs/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export * from "./features/hotkeys-core/types";
|
|
|
10
10
|
export * from "./features/search/types";
|
|
11
11
|
export * from "./features/renaming/types";
|
|
12
12
|
export * from "./features/expand-all/types";
|
|
13
|
+
export * from "./features/prop-memoization/types";
|
|
13
14
|
export * from "./features/selection/feature";
|
|
14
15
|
export * from "./features/hotkeys-core/feature";
|
|
15
16
|
export * from "./features/async-data-loader/feature";
|
|
@@ -18,6 +19,7 @@ export * from "./features/drag-and-drop/feature";
|
|
|
18
19
|
export * from "./features/search/feature";
|
|
19
20
|
export * from "./features/renaming/feature";
|
|
20
21
|
export * from "./features/expand-all/feature";
|
|
22
|
+
export * from "./features/prop-memoization/feature";
|
|
21
23
|
export * from "./utilities/create-on-drop-handler";
|
|
22
24
|
export * from "./utilities/insert-items-at-target";
|
|
23
25
|
export * from "./utilities/remove-items-from-parents";
|
package/lib/cjs/index.js
CHANGED
|
@@ -25,6 +25,7 @@ __exportStar(require("./features/hotkeys-core/types"), exports);
|
|
|
25
25
|
__exportStar(require("./features/search/types"), exports);
|
|
26
26
|
__exportStar(require("./features/renaming/types"), exports);
|
|
27
27
|
__exportStar(require("./features/expand-all/types"), exports);
|
|
28
|
+
__exportStar(require("./features/prop-memoization/types"), exports);
|
|
28
29
|
__exportStar(require("./features/selection/feature"), exports);
|
|
29
30
|
__exportStar(require("./features/hotkeys-core/feature"), exports);
|
|
30
31
|
__exportStar(require("./features/async-data-loader/feature"), exports);
|
|
@@ -33,6 +34,7 @@ __exportStar(require("./features/drag-and-drop/feature"), exports);
|
|
|
33
34
|
__exportStar(require("./features/search/feature"), exports);
|
|
34
35
|
__exportStar(require("./features/renaming/feature"), exports);
|
|
35
36
|
__exportStar(require("./features/expand-all/feature"), exports);
|
|
37
|
+
__exportStar(require("./features/prop-memoization/feature"), exports);
|
|
36
38
|
__exportStar(require("./utilities/create-on-drop-handler"), exports);
|
|
37
39
|
__exportStar(require("./utilities/insert-items-at-target"), exports);
|
|
38
40
|
__exportStar(require("./utilities/remove-items-from-parents"), exports);
|
|
@@ -8,6 +8,7 @@ import { SearchFeatureDef } from "./features/search/types";
|
|
|
8
8
|
import { SelectionFeatureDef } from "./features/selection/types";
|
|
9
9
|
import { SyncDataLoaderFeatureDef } from "./features/sync-data-loader/types";
|
|
10
10
|
import { TreeFeatureDef } from "./features/tree/types";
|
|
11
|
+
import { PropMemoizationFeatureDef } from "./features/prop-memoization/types";
|
|
11
12
|
export * from ".";
|
|
12
13
|
/** @interface */
|
|
13
14
|
export type AsyncDataLoaderFeatureConfig<T> = AsyncDataLoaderFeatureDef<T>["config"];
|
|
@@ -55,6 +56,15 @@ export type MainFeatureTreeInstance = MainFeatureDef["treeInstance"];
|
|
|
55
56
|
export type MainFeatureItemInstance = MainFeatureDef["itemInstance"];
|
|
56
57
|
export type MainFeatureHotkeys = MainFeatureDef["hotkeys"];
|
|
57
58
|
/** @interface */
|
|
59
|
+
export type PropMemoizationConfig = PropMemoizationFeatureDef["config"];
|
|
60
|
+
/** @interface */
|
|
61
|
+
export type PropMemoizationState = PropMemoizationFeatureDef["state"];
|
|
62
|
+
/** @interface */
|
|
63
|
+
export type PropMemoizationTreeInstance = PropMemoizationFeatureDef["treeInstance"];
|
|
64
|
+
/** @interface */
|
|
65
|
+
export type PropMemoizationItemInstance = PropMemoizationFeatureDef["itemInstance"];
|
|
66
|
+
export type PropMemoizationHotkeys = PropMemoizationFeatureDef["hotkeys"];
|
|
67
|
+
/** @interface */
|
|
58
68
|
export type RenamingFeatureConfig<T> = RenamingFeatureDef<T>["config"];
|
|
59
69
|
/** @interface */
|
|
60
70
|
export type RenamingFeatureState<T> = RenamingFeatureDef<T>["state"];
|
|
@@ -3,7 +3,7 @@ import { TestTree } from "./test-tree";
|
|
|
3
3
|
import { HotkeyName } from "../types/core";
|
|
4
4
|
export declare class TestTreeDo<T> {
|
|
5
5
|
protected tree: TestTree<T>;
|
|
6
|
-
protected itemInstance(itemId: string): import("../types/core").ItemInstance<
|
|
6
|
+
protected itemInstance(itemId: string): import("../types/core").ItemInstance<T>;
|
|
7
7
|
protected itemProps(itemId: string): Record<string, any>;
|
|
8
8
|
constructor(tree: TestTree<T>);
|
|
9
9
|
selectItem(id: string): void;
|
|
@@ -3,7 +3,7 @@ import { TestTree } from "./test-tree";
|
|
|
3
3
|
import { DropTarget } from "../features/drag-and-drop/types";
|
|
4
4
|
export declare class TestTreeExpect<T> {
|
|
5
5
|
private tree;
|
|
6
|
-
protected itemInstance(itemId: string): import("..").ItemInstance<
|
|
6
|
+
protected itemInstance(itemId: string): import("..").ItemInstance<T>;
|
|
7
7
|
protected itemProps(itemId: string): Record<string, any>;
|
|
8
8
|
constructor(tree: TestTree<T>);
|
|
9
9
|
foldersExpanded(...itemIds: string[]): void;
|
|
@@ -48,7 +48,7 @@ class TestTreeExpect {
|
|
|
48
48
|
(0, vitest_1.expect)(this.tree.instance.getDragLineData()).toEqual({
|
|
49
49
|
indent,
|
|
50
50
|
left: indent * 20,
|
|
51
|
-
|
|
51
|
+
width: 100 - indent * 20,
|
|
52
52
|
top: 0,
|
|
53
53
|
});
|
|
54
54
|
(0, vitest_1.expect)(this.tree.instance.getDragLineStyle(0, 0)).toEqual({
|
|
@@ -37,7 +37,7 @@ export declare class TestTree<T = string> {
|
|
|
37
37
|
createTestCaseTree(): Promise<this>;
|
|
38
38
|
withFeatures(...features: any): TestTree<T>;
|
|
39
39
|
mockedHandler(handlerName: keyof TreeConfig<T>): import("vitest").Mock<(...args: any[]) => any>;
|
|
40
|
-
item(itemId: string): import("../types/core").ItemInstance<
|
|
40
|
+
item(itemId: string): import("../types/core").ItemInstance<T>;
|
|
41
41
|
reset(): void;
|
|
42
42
|
debug(): void;
|
|
43
43
|
setElementBoundingBox(itemId: string, bb?: Partial<DOMRect>): void;
|
|
@@ -163,10 +163,18 @@ class TestTree {
|
|
|
163
163
|
}
|
|
164
164
|
setElementBoundingBox(itemId, bb = {
|
|
165
165
|
left: 0,
|
|
166
|
-
|
|
166
|
+
width: 100,
|
|
167
167
|
top: 0,
|
|
168
168
|
height: 20,
|
|
169
169
|
}) {
|
|
170
|
+
this.instance.registerElement({
|
|
171
|
+
getBoundingClientRect: () => ({
|
|
172
|
+
left: 0,
|
|
173
|
+
width: 100,
|
|
174
|
+
top: 0,
|
|
175
|
+
height: 10000,
|
|
176
|
+
}),
|
|
177
|
+
});
|
|
170
178
|
this.instance.getItemInstance(itemId).registerElement({
|
|
171
179
|
getBoundingClientRect: () => bb,
|
|
172
180
|
});
|
package/lib/cjs/types/core.d.ts
CHANGED
|
@@ -8,14 +8,14 @@ import { AsyncDataLoaderFeatureDef } from "../features/async-data-loader/types";
|
|
|
8
8
|
import { SearchFeatureDef } from "../features/search/types";
|
|
9
9
|
import { RenamingFeatureDef } from "../features/renaming/types";
|
|
10
10
|
import { ExpandAllFeatureDef } from "../features/expand-all/types";
|
|
11
|
+
import { PropMemoizationFeatureDef } from "../features/prop-memoization/types";
|
|
11
12
|
export type Updater<T> = T | ((old: T) => T);
|
|
12
13
|
export type SetStateFn<T> = (updaterOrValue: Updater<T>) => void;
|
|
13
|
-
type FunctionMap = Record<string, (...args: any[]) => any>;
|
|
14
14
|
export type FeatureDef = {
|
|
15
15
|
state: any;
|
|
16
16
|
config: any;
|
|
17
|
-
treeInstance:
|
|
18
|
-
itemInstance:
|
|
17
|
+
treeInstance: any;
|
|
18
|
+
itemInstance: any;
|
|
19
19
|
hotkeys: string;
|
|
20
20
|
};
|
|
21
21
|
export type EmptyFeatureDef = {
|
|
@@ -26,8 +26,6 @@ export type EmptyFeatureDef = {
|
|
|
26
26
|
hotkeys: never;
|
|
27
27
|
};
|
|
28
28
|
type UnionToIntersection<T> = (T extends any ? (x: T) => any : never) extends (x: infer R) => any ? R : never;
|
|
29
|
-
export type DefaultFeatures<T> = MainFeatureDef | TreeFeatureDef<T>;
|
|
30
|
-
export type FeatureDefs<T> = MainFeatureDef | TreeFeatureDef<T> | SelectionFeatureDef<T> | DragAndDropFeatureDef<T> | HotkeysCoreFeatureDef<T> | SyncDataLoaderFeatureDef<T> | AsyncDataLoaderFeatureDef<T> | SearchFeatureDef<T> | RenamingFeatureDef<T> | ExpandAllFeatureDef;
|
|
31
29
|
type MergedFeatures<F extends FeatureDef> = {
|
|
32
30
|
state: UnionToIntersection<F["state"]>;
|
|
33
31
|
config: UnionToIntersection<F["config"]>;
|
|
@@ -35,49 +33,50 @@ type MergedFeatures<F extends FeatureDef> = {
|
|
|
35
33
|
itemInstance: UnionToIntersection<F["itemInstance"]>;
|
|
36
34
|
hotkeys: F["hotkeys"];
|
|
37
35
|
};
|
|
38
|
-
type
|
|
36
|
+
export type RegisteredFeatures<T> = MainFeatureDef<T> | TreeFeatureDef<T> | SelectionFeatureDef<T> | DragAndDropFeatureDef<T> | HotkeysCoreFeatureDef<T> | SyncDataLoaderFeatureDef<T> | AsyncDataLoaderFeatureDef<T> | SearchFeatureDef<T> | RenamingFeatureDef<T> | ExpandAllFeatureDef | PropMemoizationFeatureDef;
|
|
37
|
+
type TreeStateType<T> = MergedFeatures<RegisteredFeatures<T>>["state"];
|
|
39
38
|
export interface TreeState<T> extends TreeStateType<T> {
|
|
40
39
|
}
|
|
41
|
-
type TreeConfigType<T> =
|
|
40
|
+
type TreeConfigType<T> = MergedFeatures<RegisteredFeatures<T>>["config"];
|
|
42
41
|
export interface TreeConfig<T> extends TreeConfigType<T> {
|
|
43
42
|
}
|
|
44
|
-
type TreeInstanceType<T> =
|
|
43
|
+
type TreeInstanceType<T> = MergedFeatures<RegisteredFeatures<T>>["treeInstance"];
|
|
45
44
|
export interface TreeInstance<T> extends TreeInstanceType<T> {
|
|
46
45
|
}
|
|
47
|
-
type ItemInstanceType<T> =
|
|
46
|
+
type ItemInstanceType<T> = MergedFeatures<RegisteredFeatures<T>>["itemInstance"];
|
|
48
47
|
export interface ItemInstance<T> extends ItemInstanceType<T> {
|
|
49
48
|
}
|
|
50
|
-
export type HotkeyName
|
|
51
|
-
export type HotkeysConfig<T
|
|
52
|
-
export type CustomHotkeysConfig<T
|
|
49
|
+
export type HotkeyName = MergedFeatures<RegisteredFeatures<any>>["hotkeys"];
|
|
50
|
+
export type HotkeysConfig<T> = Record<HotkeyName, HotkeyConfig<T>>;
|
|
51
|
+
export type CustomHotkeysConfig<T> = Partial<Record<HotkeyName | `custom${string}`, Partial<HotkeyConfig<T>>>>;
|
|
53
52
|
type MayReturnNull<T extends (...x: any[]) => any> = (...args: Parameters<T>) => ReturnType<T> | null;
|
|
54
|
-
export type ItemInstanceOpts<
|
|
55
|
-
item: ItemInstance
|
|
56
|
-
tree: TreeInstance
|
|
53
|
+
export type ItemInstanceOpts<Key extends keyof ItemInstance<any>> = {
|
|
54
|
+
item: ItemInstance<any>;
|
|
55
|
+
tree: TreeInstance<any>;
|
|
57
56
|
itemId: string;
|
|
58
|
-
prev?: MayReturnNull<ItemInstance[Key]>;
|
|
57
|
+
prev?: MayReturnNull<ItemInstance<any>[Key]>;
|
|
59
58
|
};
|
|
60
|
-
export type TreeInstanceOpts<
|
|
61
|
-
tree: TreeInstance
|
|
62
|
-
prev?: MayReturnNull<TreeInstance[Key]>;
|
|
59
|
+
export type TreeInstanceOpts<Key extends keyof TreeInstance<any>> = {
|
|
60
|
+
tree: TreeInstance<any>;
|
|
61
|
+
prev?: MayReturnNull<TreeInstance<any>[Key]>;
|
|
63
62
|
};
|
|
64
|
-
export type FeatureImplementation<T = any
|
|
63
|
+
export type FeatureImplementation<T = any> = {
|
|
65
64
|
key?: string;
|
|
66
65
|
deps?: string[];
|
|
67
66
|
overwrites?: string[];
|
|
68
|
-
stateHandlerNames?: Partial<Record<keyof
|
|
69
|
-
getInitialState?: (initialState: Partial<
|
|
70
|
-
getDefaultConfig?: (defaultConfig: Partial<
|
|
67
|
+
stateHandlerNames?: Partial<Record<keyof TreeState<T>, keyof TreeConfig<T>>>;
|
|
68
|
+
getInitialState?: (initialState: Partial<TreeState<T>>, tree: TreeInstance<T>) => Partial<TreeState<T>>;
|
|
69
|
+
getDefaultConfig?: (defaultConfig: Partial<TreeConfig<T>>, tree: TreeInstance<T>) => Partial<TreeConfig<T>>;
|
|
71
70
|
treeInstance?: {
|
|
72
|
-
[key in keyof
|
|
71
|
+
[key in keyof TreeInstance<T>]?: (opts: TreeInstanceOpts<key>, ...args: Parameters<TreeInstance<T>[key]>) => void;
|
|
73
72
|
};
|
|
74
73
|
itemInstance?: {
|
|
75
|
-
[key in keyof
|
|
74
|
+
[key in keyof ItemInstance<T>]?: (opts: ItemInstanceOpts<key>, ...args: Parameters<ItemInstance<T>[key]>) => void;
|
|
76
75
|
};
|
|
77
|
-
onTreeMount?: (instance:
|
|
78
|
-
onTreeUnmount?: (instance:
|
|
79
|
-
onItemMount?: (instance:
|
|
80
|
-
onItemUnmount?: (instance:
|
|
81
|
-
hotkeys?: HotkeysConfig<T
|
|
76
|
+
onTreeMount?: (instance: TreeInstance<T>, treeElement: HTMLElement) => void;
|
|
77
|
+
onTreeUnmount?: (instance: TreeInstance<T>, treeElement: HTMLElement) => void;
|
|
78
|
+
onItemMount?: (instance: ItemInstance<T>, itemElement: HTMLElement, tree: TreeInstance<T>) => void;
|
|
79
|
+
onItemUnmount?: (instance: ItemInstance<T>, itemElement: HTMLElement, tree: TreeInstance<T>) => void;
|
|
80
|
+
hotkeys?: Partial<HotkeysConfig<T>>;
|
|
82
81
|
};
|
|
83
82
|
export {};
|
|
@@ -4,8 +4,7 @@ export const buildStaticInstance = (features, instanceType, buildOpts) => {
|
|
|
4
4
|
const finalize = () => {
|
|
5
5
|
const opts = buildOpts(instance);
|
|
6
6
|
featureLoop: for (let i = 0; i < features.length; i++) {
|
|
7
|
-
// Loop goes in forward order,
|
|
8
|
-
// TODO loop order correct? I think so...
|
|
7
|
+
// Loop goes in forward order, each features overwrite previous ones and wraps those in a prev() fn
|
|
9
8
|
const definition = features[i][instanceType];
|
|
10
9
|
if (!definition)
|
|
11
10
|
continue featureLoop;
|
|
@@ -11,14 +11,17 @@ const verifyFeatures = (features) => {
|
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
};
|
|
14
|
-
const compareFeatures = (feature1, feature2) => {
|
|
15
|
-
var _a;
|
|
14
|
+
const compareFeatures = (originalOrder) => (feature1, feature2) => {
|
|
15
|
+
var _a, _b;
|
|
16
16
|
if (feature2.key && ((_a = feature1.overwrites) === null || _a === void 0 ? void 0 : _a.includes(feature2.key))) {
|
|
17
17
|
return 1;
|
|
18
18
|
}
|
|
19
|
-
|
|
19
|
+
if (feature1.key && ((_b = feature2.overwrites) === null || _b === void 0 ? void 0 : _b.includes(feature1.key))) {
|
|
20
|
+
return -1;
|
|
21
|
+
}
|
|
22
|
+
return originalOrder.indexOf(feature1) - originalOrder.indexOf(feature2);
|
|
20
23
|
};
|
|
21
|
-
const sortFeatures = (features = []) => features.sort(compareFeatures);
|
|
24
|
+
const sortFeatures = (features = []) => features.sort(compareFeatures(features));
|
|
22
25
|
export const createTree = (initialConfig) => {
|
|
23
26
|
var _a, _b, _c, _d;
|
|
24
27
|
const buildInstance = (_a = initialConfig.instanceBuilder) !== null && _a !== void 0 ? _a : buildStaticInstance;
|
|
@@ -1,5 +1,2 @@
|
|
|
1
1
|
import { FeatureImplementation } from "../../types/core";
|
|
2
|
-
|
|
3
|
-
import { MainFeatureDef } from "../main/types";
|
|
4
|
-
import { TreeFeatureDef } from "../tree/types";
|
|
5
|
-
export declare const asyncDataLoaderFeature: FeatureImplementation<any, AsyncDataLoaderFeatureDef<any>, MainFeatureDef | TreeFeatureDef<any> | AsyncDataLoaderFeatureDef<any>>;
|
|
2
|
+
export declare const asyncDataLoaderFeature: FeatureImplementation;
|
|
@@ -73,23 +73,21 @@ export const asyncDataLoaderFeature = {
|
|
|
73
73
|
}
|
|
74
74
|
return [];
|
|
75
75
|
},
|
|
76
|
-
|
|
76
|
+
},
|
|
77
|
+
itemInstance: {
|
|
78
|
+
isLoading: ({ tree, item }) => tree.getState().loadingItems.includes(item.getItemMeta().itemId),
|
|
79
|
+
invalidateItemData: ({ tree, itemId }) => {
|
|
77
80
|
var _a;
|
|
78
81
|
const dataRef = tree.getDataRef();
|
|
79
82
|
(_a = dataRef.current.itemData) === null || _a === void 0 ? true : delete _a[itemId];
|
|
80
83
|
tree.retrieveItemData(itemId);
|
|
81
84
|
},
|
|
82
|
-
invalidateChildrenIds: ({ tree
|
|
85
|
+
invalidateChildrenIds: ({ tree, itemId }) => {
|
|
83
86
|
var _a;
|
|
84
87
|
const dataRef = tree.getDataRef();
|
|
85
88
|
(_a = dataRef.current.childrenIds) === null || _a === void 0 ? true : delete _a[itemId];
|
|
86
89
|
tree.retrieveChildrenIds(itemId);
|
|
87
90
|
},
|
|
88
|
-
},
|
|
89
|
-
itemInstance: {
|
|
90
|
-
isLoading: ({ tree, item }) => tree.getState().loadingItems.includes(item.getItemMeta().itemId),
|
|
91
|
-
invalidateItemData: ({ tree, item }) => tree.invalidateItemData(item.getItemMeta().itemId),
|
|
92
|
-
invalidateChildrenIds: ({ tree, item }) => tree.invalidateChildrenIds(item.getItemMeta().itemId),
|
|
93
91
|
updateCachedChildrenIds: ({ tree, itemId }, childrenIds) => {
|
|
94
92
|
const dataRef = tree.getDataRef();
|
|
95
93
|
dataRef.current.childrenIds[itemId] = childrenIds;
|
|
@@ -27,12 +27,9 @@ export type AsyncDataLoaderFeatureDef<T> = {
|
|
|
27
27
|
onLoadedChildren?: (itemId: string, childrenIds: string[]) => void;
|
|
28
28
|
asyncDataLoader?: AsyncTreeDataLoader<T>;
|
|
29
29
|
};
|
|
30
|
-
treeInstance: SyncDataLoaderFeatureDef<T>["treeInstance"]
|
|
31
|
-
/** Invalidate fetched data for item, and triggers a refetch and subsequent rerender if the item is visible */
|
|
32
|
-
invalidateItemData: (itemId: string) => void;
|
|
33
|
-
invalidateChildrenIds: (itemId: string) => void;
|
|
34
|
-
};
|
|
30
|
+
treeInstance: SyncDataLoaderFeatureDef<T>["treeInstance"];
|
|
35
31
|
itemInstance: SyncDataLoaderFeatureDef<T>["itemInstance"] & {
|
|
32
|
+
/** Invalidate fetched data for item, and triggers a refetch and subsequent rerender if the item is visible */
|
|
36
33
|
invalidateItemData: () => void;
|
|
37
34
|
invalidateChildrenIds: () => void;
|
|
38
35
|
updateCachedChildrenIds: (childrenIds: string[]) => void;
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
export declare const dragAndDropFeature: FeatureImplementation<any, DragAndDropFeatureDef<any>, FeatureDefs<any>>;
|
|
1
|
+
import { FeatureImplementation } from "../../types/core";
|
|
2
|
+
export declare const dragAndDropFeature: FeatureImplementation;
|