@headless-tree/core 0.0.10 → 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 +12 -0
- package/lib/cjs/core/build-proxified-instance.d.ts +2 -0
- package/lib/cjs/core/build-proxified-instance.js +58 -0
- package/lib/cjs/core/build-static-instance.d.ts +2 -0
- package/lib/cjs/core/build-static-instance.js +26 -0
- package/lib/cjs/core/create-tree.js +62 -40
- package/lib/cjs/features/async-data-loader/feature.d.ts +1 -4
- package/lib/cjs/features/async-data-loader/feature.js +35 -23
- package/lib/cjs/features/async-data-loader/types.d.ts +4 -6
- package/lib/cjs/features/drag-and-drop/feature.d.ts +2 -3
- package/lib/cjs/features/drag-and-drop/feature.js +79 -44
- package/lib/cjs/features/drag-and-drop/types.d.ts +15 -6
- package/lib/cjs/features/drag-and-drop/utils.d.ts +2 -3
- package/lib/cjs/features/drag-and-drop/utils.js +140 -37
- package/lib/cjs/features/expand-all/feature.d.ts +1 -5
- package/lib/cjs/features/expand-all/feature.js +12 -6
- package/lib/cjs/features/hotkeys-core/feature.d.ts +1 -3
- package/lib/cjs/features/main/types.d.ts +8 -2
- 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 +36 -22
- package/lib/cjs/features/renaming/types.d.ts +2 -2
- package/lib/cjs/features/search/feature.d.ts +1 -4
- package/lib/cjs/features/search/feature.js +38 -24
- package/lib/cjs/features/search/types.d.ts +0 -1
- package/lib/cjs/features/selection/feature.d.ts +1 -4
- package/lib/cjs/features/selection/feature.js +54 -35
- 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/sync-data-loader/feature.js +7 -2
- package/lib/cjs/features/tree/feature.d.ts +1 -5
- package/lib/cjs/features/tree/feature.js +97 -92
- package/lib/cjs/features/tree/types.d.ts +5 -8
- package/lib/cjs/index.d.ts +5 -1
- package/lib/cjs/index.js +4 -1
- package/lib/cjs/mddocs-entry.d.ts +10 -0
- package/lib/cjs/test-utils/test-tree-do.d.ts +23 -0
- package/lib/cjs/test-utils/test-tree-do.js +99 -0
- package/lib/cjs/test-utils/test-tree-expect.d.ts +15 -0
- package/lib/cjs/test-utils/test-tree-expect.js +62 -0
- package/lib/cjs/test-utils/test-tree.d.ts +47 -0
- package/lib/cjs/test-utils/test-tree.js +203 -0
- package/lib/cjs/types/core.d.ts +39 -24
- package/lib/cjs/utilities/errors.d.ts +1 -0
- package/lib/cjs/utilities/errors.js +5 -0
- package/lib/cjs/utilities/insert-items-at-target.js +10 -3
- package/lib/cjs/utilities/remove-items-from-parents.js +14 -8
- package/lib/cjs/utils.d.ts +3 -3
- package/lib/cjs/utils.js +6 -6
- package/lib/esm/core/build-proxified-instance.d.ts +2 -0
- package/lib/esm/core/build-proxified-instance.js +54 -0
- package/lib/esm/core/build-static-instance.d.ts +2 -0
- package/lib/esm/core/build-static-instance.js +22 -0
- package/lib/esm/core/create-tree.js +62 -40
- package/lib/esm/features/async-data-loader/feature.d.ts +1 -4
- package/lib/esm/features/async-data-loader/feature.js +35 -23
- package/lib/esm/features/async-data-loader/types.d.ts +4 -6
- package/lib/esm/features/drag-and-drop/feature.d.ts +2 -3
- package/lib/esm/features/drag-and-drop/feature.js +79 -44
- package/lib/esm/features/drag-and-drop/types.d.ts +15 -6
- package/lib/esm/features/drag-and-drop/utils.d.ts +2 -3
- package/lib/esm/features/drag-and-drop/utils.js +138 -34
- package/lib/esm/features/expand-all/feature.d.ts +1 -5
- package/lib/esm/features/expand-all/feature.js +12 -6
- package/lib/esm/features/hotkeys-core/feature.d.ts +1 -3
- package/lib/esm/features/main/types.d.ts +8 -2
- 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 +36 -22
- package/lib/esm/features/renaming/types.d.ts +2 -2
- package/lib/esm/features/search/feature.d.ts +1 -4
- package/lib/esm/features/search/feature.js +38 -24
- package/lib/esm/features/search/types.d.ts +0 -1
- package/lib/esm/features/selection/feature.d.ts +1 -4
- package/lib/esm/features/selection/feature.js +54 -35
- 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/sync-data-loader/feature.js +7 -2
- package/lib/esm/features/tree/feature.d.ts +1 -5
- package/lib/esm/features/tree/feature.js +98 -93
- package/lib/esm/features/tree/types.d.ts +5 -8
- package/lib/esm/index.d.ts +5 -1
- package/lib/esm/index.js +4 -1
- package/lib/esm/mddocs-entry.d.ts +10 -0
- package/lib/esm/test-utils/test-tree-do.d.ts +23 -0
- package/lib/esm/test-utils/test-tree-do.js +95 -0
- package/lib/esm/test-utils/test-tree-expect.d.ts +15 -0
- package/lib/esm/test-utils/test-tree-expect.js +58 -0
- package/lib/esm/test-utils/test-tree.d.ts +47 -0
- package/lib/esm/test-utils/test-tree.js +199 -0
- package/lib/esm/types/core.d.ts +39 -24
- package/lib/esm/utilities/errors.d.ts +1 -0
- package/lib/esm/utilities/errors.js +1 -0
- package/lib/esm/utilities/insert-items-at-target.js +10 -3
- package/lib/esm/utilities/remove-items-from-parents.js +14 -8
- package/lib/esm/utils.d.ts +3 -3
- package/lib/esm/utils.js +3 -3
- package/package.json +7 -3
- package/src/core/build-proxified-instance.ts +117 -0
- package/src/core/build-static-instance.ts +27 -0
- package/src/core/core.spec.ts +210 -0
- package/src/core/create-tree.ts +73 -78
- package/src/features/async-data-loader/async-data-loader.spec.ts +124 -0
- package/src/features/async-data-loader/feature.ts +34 -44
- package/src/features/async-data-loader/types.ts +4 -6
- package/src/features/drag-and-drop/drag-and-drop.spec.ts +717 -0
- package/src/features/drag-and-drop/feature.ts +88 -63
- package/src/features/drag-and-drop/types.ts +24 -10
- package/src/features/drag-and-drop/utils.ts +197 -56
- package/src/features/expand-all/expand-all.spec.ts +56 -0
- package/src/features/expand-all/feature.ts +9 -24
- package/src/features/hotkeys-core/feature.ts +5 -14
- package/src/features/main/types.ts +14 -1
- 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 +37 -45
- package/src/features/renaming/renaming.spec.ts +127 -0
- package/src/features/renaming/types.ts +2 -2
- package/src/features/search/feature.ts +36 -46
- package/src/features/search/search.spec.ts +117 -0
- package/src/features/search/types.ts +0 -1
- package/src/features/selection/feature.ts +50 -53
- package/src/features/selection/selection.spec.ts +219 -0
- package/src/features/selection/types.ts +0 -2
- package/src/features/sync-data-loader/feature.ts +9 -18
- package/src/features/tree/feature.ts +101 -144
- package/src/features/tree/tree.spec.ts +475 -0
- package/src/features/tree/types.ts +5 -9
- package/src/index.ts +6 -1
- package/src/mddocs-entry.ts +13 -0
- package/src/test-utils/test-tree-do.ts +136 -0
- package/src/test-utils/test-tree-expect.ts +86 -0
- package/src/test-utils/test-tree.ts +227 -0
- package/src/types/core.ts +76 -108
- package/src/utilities/errors.ts +2 -0
- package/src/utilities/insert-items-at-target.ts +10 -3
- package/src/utilities/remove-items-from-parents.ts +15 -10
- package/src/utils.spec.ts +89 -0
- package/src/utils.ts +6 -6
- package/tsconfig.json +1 -0
- package/vitest.config.ts +6 -0
package/CHANGELOG.md
CHANGED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildProxiedInstance = void 0;
|
|
4
|
+
const errors_1 = require("../utilities/errors");
|
|
5
|
+
const noop = () => { };
|
|
6
|
+
const findPrevInstanceMethod = (features, instanceType, methodKey, featureSearchIndex) => {
|
|
7
|
+
var _a;
|
|
8
|
+
for (let i = featureSearchIndex; i >= 0; i--) {
|
|
9
|
+
const feature = features[i];
|
|
10
|
+
const itemInstanceMethod = (_a = feature[instanceType]) === null || _a === void 0 ? void 0 : _a[methodKey];
|
|
11
|
+
if (itemInstanceMethod) {
|
|
12
|
+
return i;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return null;
|
|
16
|
+
};
|
|
17
|
+
const invokeInstanceMethod = (features, instanceType, opts, methodKey, featureIndex, args) => {
|
|
18
|
+
var _a;
|
|
19
|
+
const prevIndex = findPrevInstanceMethod(features, instanceType, methodKey, featureIndex - 1);
|
|
20
|
+
const itemInstanceMethod = (_a = features[featureIndex][instanceType]) === null || _a === void 0 ? void 0 : _a[methodKey];
|
|
21
|
+
return itemInstanceMethod(Object.assign(Object.assign({}, opts), { prev: prevIndex !== null
|
|
22
|
+
? (...newArgs) => invokeInstanceMethod(features, instanceType, opts, methodKey, prevIndex, newArgs)
|
|
23
|
+
: null }), ...args);
|
|
24
|
+
};
|
|
25
|
+
const buildProxiedInstance = (features, instanceType, buildOpts) => {
|
|
26
|
+
// demo with prototypes: https://jsfiddle.net/bgenc58r/
|
|
27
|
+
const opts = {};
|
|
28
|
+
const item = new Proxy({}, {
|
|
29
|
+
has(target, key) {
|
|
30
|
+
if (typeof key === "symbol") {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
if (key === "toJSON") {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
const hasInstanceMethod = findPrevInstanceMethod(features, instanceType, key, features.length - 1);
|
|
37
|
+
return Boolean(hasInstanceMethod);
|
|
38
|
+
},
|
|
39
|
+
get(target, key) {
|
|
40
|
+
if (typeof key === "symbol") {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
if (key === "toJSON") {
|
|
44
|
+
return {};
|
|
45
|
+
}
|
|
46
|
+
return (...args) => {
|
|
47
|
+
const featureIndex = findPrevInstanceMethod(features, instanceType, key, features.length - 1);
|
|
48
|
+
if (featureIndex === null) {
|
|
49
|
+
throw (0, errors_1.throwError)(`feature missing for method ${key}`);
|
|
50
|
+
}
|
|
51
|
+
return invokeInstanceMethod(features, instanceType, opts, key, featureIndex, args);
|
|
52
|
+
};
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
Object.assign(opts, buildOpts(item));
|
|
56
|
+
return [item, noop];
|
|
57
|
+
};
|
|
58
|
+
exports.buildProxiedInstance = buildProxiedInstance;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint-disable no-continue,no-labels,no-extra-label */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.buildStaticInstance = void 0;
|
|
5
|
+
const buildStaticInstance = (features, instanceType, buildOpts) => {
|
|
6
|
+
const instance = {};
|
|
7
|
+
const finalize = () => {
|
|
8
|
+
const opts = buildOpts(instance);
|
|
9
|
+
featureLoop: for (let i = 0; i < features.length; i++) {
|
|
10
|
+
// Loop goes in forward order, each features overwrite previous ones and wraps those in a prev() fn
|
|
11
|
+
const definition = features[i][instanceType];
|
|
12
|
+
if (!definition)
|
|
13
|
+
continue featureLoop;
|
|
14
|
+
methodLoop: for (const [key, method] of Object.entries(definition)) {
|
|
15
|
+
if (!method)
|
|
16
|
+
continue methodLoop;
|
|
17
|
+
const prev = instance[key];
|
|
18
|
+
instance[key] = (...args) => {
|
|
19
|
+
return method(Object.assign(Object.assign({}, opts), { prev }), ...args);
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
return [instance, finalize];
|
|
25
|
+
};
|
|
26
|
+
exports.buildStaticInstance = buildStaticInstance;
|
|
@@ -2,44 +2,40 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createTree = void 0;
|
|
4
4
|
const feature_1 = require("../features/tree/feature");
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
const itemInstance = {};
|
|
8
|
-
for (const feature of features) {
|
|
9
|
-
Object.assign(
|
|
10
|
-
// TODO dont run createItemInstance, but assign prototype objects instead?
|
|
11
|
-
// https://jsfiddle.net/bgenc58r/
|
|
12
|
-
itemInstance, (_b = (_a = feature.createItemInstance) === null || _a === void 0 ? void 0 : _a.call(feature, Object.assign({}, itemInstance), itemInstance, tree, itemId)) !== null && _b !== void 0 ? _b : {});
|
|
13
|
-
}
|
|
14
|
-
return itemInstance;
|
|
15
|
-
};
|
|
5
|
+
const build_static_instance_1 = require("./build-static-instance");
|
|
6
|
+
const errors_1 = require("../utilities/errors");
|
|
16
7
|
const verifyFeatures = (features) => {
|
|
17
8
|
var _a;
|
|
18
9
|
const loadedFeatures = features === null || features === void 0 ? void 0 : features.map((feature) => feature.key);
|
|
19
10
|
for (const feature of features !== null && features !== void 0 ? features : []) {
|
|
20
11
|
const missingDependency = (_a = feature.deps) === null || _a === void 0 ? void 0 : _a.find((dep) => !(loadedFeatures === null || loadedFeatures === void 0 ? void 0 : loadedFeatures.includes(dep)));
|
|
21
12
|
if (missingDependency) {
|
|
22
|
-
throw
|
|
13
|
+
throw (0, errors_1.throwError)(`${feature.key} needs ${missingDependency}`);
|
|
23
14
|
}
|
|
24
15
|
}
|
|
25
16
|
};
|
|
26
|
-
const compareFeatures = (feature1, feature2) => {
|
|
27
|
-
var _a;
|
|
17
|
+
const compareFeatures = (originalOrder) => (feature1, feature2) => {
|
|
18
|
+
var _a, _b;
|
|
28
19
|
if (feature2.key && ((_a = feature1.overwrites) === null || _a === void 0 ? void 0 : _a.includes(feature2.key))) {
|
|
29
20
|
return 1;
|
|
30
21
|
}
|
|
31
|
-
|
|
22
|
+
if (feature1.key && ((_b = feature2.overwrites) === null || _b === void 0 ? void 0 : _b.includes(feature1.key))) {
|
|
23
|
+
return -1;
|
|
24
|
+
}
|
|
25
|
+
return originalOrder.indexOf(feature1) - originalOrder.indexOf(feature2);
|
|
32
26
|
};
|
|
33
|
-
const sortFeatures = (features = []) => features.sort(compareFeatures);
|
|
27
|
+
const sortFeatures = (features = []) => features.sort(compareFeatures(features));
|
|
34
28
|
const createTree = (initialConfig) => {
|
|
35
|
-
var _a, _b, _c, _d
|
|
36
|
-
const
|
|
29
|
+
var _a, _b, _c, _d;
|
|
30
|
+
const buildInstance = (_a = initialConfig.instanceBuilder) !== null && _a !== void 0 ? _a : build_static_instance_1.buildStaticInstance;
|
|
37
31
|
const additionalFeatures = [
|
|
38
32
|
feature_1.treeFeature,
|
|
39
33
|
...sortFeatures(initialConfig.features),
|
|
40
34
|
];
|
|
41
35
|
verifyFeatures(additionalFeatures);
|
|
42
|
-
|
|
36
|
+
const features = [...additionalFeatures];
|
|
37
|
+
const [treeInstance, finalizeTree] = buildInstance(features, "treeInstance", (tree) => ({ tree }));
|
|
38
|
+
let state = additionalFeatures.reduce((acc, feature) => { var _a, _b; return (_b = (_a = feature.getInitialState) === null || _a === void 0 ? void 0 : _a.call(feature, acc, treeInstance)) !== null && _b !== void 0 ? _b : acc; }, (_c = (_b = initialConfig.initialState) !== null && _b !== void 0 ? _b : initialConfig.state) !== null && _c !== void 0 ? _c : {});
|
|
43
39
|
let config = additionalFeatures.reduce((acc, feature) => { var _a, _b; return (_b = (_a = feature.getDefaultConfig) === null || _a === void 0 ? void 0 : _a.call(feature, acc, treeInstance)) !== null && _b !== void 0 ? _b : acc; }, initialConfig);
|
|
44
40
|
const stateHandlerNames = additionalFeatures.reduce((acc, feature) => (Object.assign(Object.assign({}, acc), feature.stateHandlerNames)), {});
|
|
45
41
|
let treeElement;
|
|
@@ -50,11 +46,12 @@ const createTree = (initialConfig) => {
|
|
|
50
46
|
const itemDataRefs = {};
|
|
51
47
|
let itemMetaMap = {};
|
|
52
48
|
const hotkeyPresets = {};
|
|
53
|
-
const rebuildItemMeta = (
|
|
49
|
+
const rebuildItemMeta = () => {
|
|
54
50
|
// TODO can we find a way to only run this for the changed substructure?
|
|
55
51
|
itemInstances = [];
|
|
56
52
|
itemMetaMap = {};
|
|
57
|
-
const rootInstance =
|
|
53
|
+
const [rootInstance, finalizeRootInstance] = buildInstance(features, "itemInstance", (item) => ({ item, tree: treeInstance, itemId: config.rootItemId }));
|
|
54
|
+
finalizeRootInstance();
|
|
58
55
|
itemInstancesMap[config.rootItemId] = rootInstance;
|
|
59
56
|
itemMetaMap[config.rootItemId] = {
|
|
60
57
|
itemId: config.rootItemId,
|
|
@@ -67,7 +64,12 @@ const createTree = (initialConfig) => {
|
|
|
67
64
|
for (const item of treeInstance.getItemsMeta()) {
|
|
68
65
|
itemMetaMap[item.itemId] = item;
|
|
69
66
|
if (!itemInstancesMap[item.itemId]) {
|
|
70
|
-
const instance =
|
|
67
|
+
const [instance, finalizeInstance] = buildInstance(features, "itemInstance", (instance) => ({
|
|
68
|
+
item: instance,
|
|
69
|
+
tree: treeInstance,
|
|
70
|
+
itemId: item.itemId,
|
|
71
|
+
}));
|
|
72
|
+
finalizeInstance();
|
|
71
73
|
itemInstancesMap[item.itemId] = instance;
|
|
72
74
|
itemInstances.push(instance);
|
|
73
75
|
}
|
|
@@ -83,25 +85,36 @@ const createTree = (initialConfig) => {
|
|
|
83
85
|
};
|
|
84
86
|
const mainFeature = {
|
|
85
87
|
key: "main",
|
|
86
|
-
|
|
88
|
+
treeInstance: {
|
|
89
|
+
getState: () => state,
|
|
90
|
+
setState: ({}, updater) => {
|
|
87
91
|
var _a;
|
|
88
92
|
// Not necessary, since I think the subupdate below keeps the state fresh anyways?
|
|
89
93
|
// state = typeof updater === "function" ? updater(state) : updater;
|
|
90
|
-
(_a = config.setState) === null || _a === void 0 ? void 0 : _a.call(config, state);
|
|
91
|
-
},
|
|
94
|
+
(_a = config.setState) === null || _a === void 0 ? void 0 : _a.call(config, state); // TODO this cant be right... This doesnt allow external state updates
|
|
95
|
+
},
|
|
96
|
+
applySubStateUpdate: ({}, stateName, updater) => {
|
|
92
97
|
state[stateName] =
|
|
93
98
|
typeof updater === "function" ? updater(state[stateName]) : updater;
|
|
94
|
-
config[stateHandlerNames[stateName]]
|
|
95
|
-
|
|
99
|
+
const externalStateSetter = config[stateHandlerNames[stateName]];
|
|
100
|
+
externalStateSetter === null || externalStateSetter === void 0 ? void 0 : externalStateSetter(state[stateName]);
|
|
101
|
+
},
|
|
102
|
+
// TODO rebuildSubTree: (itemId: string) => void;
|
|
103
|
+
rebuildTree: () => {
|
|
96
104
|
var _a;
|
|
97
|
-
rebuildItemMeta(
|
|
105
|
+
rebuildItemMeta();
|
|
98
106
|
(_a = config.setState) === null || _a === void 0 ? void 0 : _a.call(config, state);
|
|
99
|
-
},
|
|
107
|
+
},
|
|
108
|
+
getConfig: () => config,
|
|
109
|
+
setConfig: (_, updater) => {
|
|
100
110
|
config = typeof updater === "function" ? updater(config) : updater;
|
|
101
111
|
if (config.state) {
|
|
102
112
|
state = Object.assign(Object.assign({}, state), config.state);
|
|
103
113
|
}
|
|
104
|
-
},
|
|
114
|
+
},
|
|
115
|
+
getItemInstance: ({}, itemId) => itemInstancesMap[itemId],
|
|
116
|
+
getItems: () => itemInstances,
|
|
117
|
+
registerElement: ({}, element) => {
|
|
105
118
|
if (treeElement === element) {
|
|
106
119
|
return;
|
|
107
120
|
}
|
|
@@ -112,29 +125,38 @@ const createTree = (initialConfig) => {
|
|
|
112
125
|
eachFeature((feature) => { var _a; return (_a = feature.onTreeMount) === null || _a === void 0 ? void 0 : _a.call(feature, treeInstance, element); });
|
|
113
126
|
}
|
|
114
127
|
treeElement = element;
|
|
115
|
-
},
|
|
116
|
-
|
|
128
|
+
},
|
|
129
|
+
getElement: () => treeElement,
|
|
130
|
+
getDataRef: () => treeDataRef,
|
|
131
|
+
getHotkeyPresets: () => hotkeyPresets,
|
|
132
|
+
},
|
|
133
|
+
itemInstance: {
|
|
134
|
+
// TODO just change to a getRef method that memoizes, maybe as part of getProps
|
|
135
|
+
registerElement: ({ itemId, item }, element) => {
|
|
117
136
|
if (itemElementsMap[itemId] === element) {
|
|
118
137
|
return;
|
|
119
138
|
}
|
|
120
139
|
const oldElement = itemElementsMap[itemId];
|
|
121
140
|
if (oldElement && !element) {
|
|
122
|
-
eachFeature((feature) => { var _a; return (_a = feature.onItemUnmount) === null || _a === void 0 ? void 0 : _a.call(feature,
|
|
141
|
+
eachFeature((feature) => { var _a; return (_a = feature.onItemUnmount) === null || _a === void 0 ? void 0 : _a.call(feature, item, oldElement, treeInstance); });
|
|
123
142
|
}
|
|
124
143
|
else if (!oldElement && element) {
|
|
125
|
-
eachFeature((feature) => { var _a; return (_a = feature.onItemMount) === null || _a === void 0 ? void 0 : _a.call(feature,
|
|
144
|
+
eachFeature((feature) => { var _a; return (_a = feature.onItemMount) === null || _a === void 0 ? void 0 : _a.call(feature, item, element, treeInstance); });
|
|
126
145
|
}
|
|
127
146
|
itemElementsMap[itemId] = element;
|
|
128
|
-
},
|
|
147
|
+
},
|
|
148
|
+
getElement: ({ itemId }) => itemElementsMap[itemId],
|
|
129
149
|
// eslint-disable-next-line no-return-assign
|
|
130
|
-
getDataRef: () => { var _a; return ((_a = itemDataRefs[itemId]) !== null && _a !== void 0 ? _a : (itemDataRefs[itemId] = { current: {} })); },
|
|
150
|
+
getDataRef: ({ itemId }) => { var _a; return ((_a = itemDataRefs[itemId]) !== null && _a !== void 0 ? _a : (itemDataRefs[itemId] = { current: {} })); },
|
|
151
|
+
getItemMeta: ({ itemId }) => itemMetaMap[itemId],
|
|
152
|
+
},
|
|
131
153
|
};
|
|
132
|
-
|
|
154
|
+
features.unshift(mainFeature);
|
|
133
155
|
for (const feature of features) {
|
|
134
|
-
Object.assign(
|
|
135
|
-
Object.assign(hotkeyPresets, (_e = feature.hotkeys) !== null && _e !== void 0 ? _e : {});
|
|
156
|
+
Object.assign(hotkeyPresets, (_d = feature.hotkeys) !== null && _d !== void 0 ? _d : {});
|
|
136
157
|
}
|
|
137
|
-
|
|
158
|
+
finalizeTree();
|
|
159
|
+
rebuildItemMeta();
|
|
138
160
|
return treeInstance;
|
|
139
161
|
};
|
|
140
162
|
exports.createTree = createTree;
|
|
@@ -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;
|
|
@@ -9,18 +9,19 @@ exports.asyncDataLoaderFeature = {
|
|
|
9
9
|
stateHandlerNames: {
|
|
10
10
|
loadingItems: "setLoadingItems",
|
|
11
11
|
},
|
|
12
|
-
|
|
12
|
+
treeInstance: {
|
|
13
|
+
retrieveItemData: ({ tree }, itemId) => {
|
|
13
14
|
var _a, _b, _c, _d, _e;
|
|
14
15
|
var _f, _g;
|
|
15
|
-
const config =
|
|
16
|
-
const dataRef =
|
|
16
|
+
const config = tree.getConfig();
|
|
17
|
+
const dataRef = tree.getDataRef();
|
|
17
18
|
(_a = (_f = dataRef.current).itemData) !== null && _a !== void 0 ? _a : (_f.itemData = {});
|
|
18
19
|
(_b = (_g = dataRef.current).childrenIds) !== null && _b !== void 0 ? _b : (_g.childrenIds = {});
|
|
19
20
|
if (dataRef.current.itemData[itemId]) {
|
|
20
21
|
return dataRef.current.itemData[itemId];
|
|
21
22
|
}
|
|
22
|
-
if (!
|
|
23
|
-
|
|
23
|
+
if (!tree.getState().loadingItems.includes(itemId)) {
|
|
24
|
+
tree.applySubStateUpdate("loadingItems", (loadingItems) => [
|
|
24
25
|
...loadingItems,
|
|
25
26
|
itemId,
|
|
26
27
|
]);
|
|
@@ -28,24 +29,25 @@ exports.asyncDataLoaderFeature = {
|
|
|
28
29
|
var _a;
|
|
29
30
|
dataRef.current.itemData[itemId] = item;
|
|
30
31
|
(_a = config.onLoadedItem) === null || _a === void 0 ? void 0 : _a.call(config, itemId, item);
|
|
31
|
-
|
|
32
|
+
tree.applySubStateUpdate("loadingItems", (loadingItems) => loadingItems.filter((id) => id !== itemId));
|
|
32
33
|
});
|
|
33
34
|
}
|
|
34
35
|
return (_e = (_d = config.createLoadingItemData) === null || _d === void 0 ? void 0 : _d.call(config)) !== null && _e !== void 0 ? _e : null;
|
|
35
|
-
},
|
|
36
|
+
},
|
|
37
|
+
retrieveChildrenIds: ({ tree }, itemId) => {
|
|
36
38
|
var _a, _b, _c, _d, _e;
|
|
37
39
|
var _f, _g;
|
|
38
|
-
const config =
|
|
39
|
-
const dataRef =
|
|
40
|
+
const config = tree.getConfig();
|
|
41
|
+
const dataRef = tree.getDataRef();
|
|
40
42
|
(_a = (_f = dataRef.current).itemData) !== null && _a !== void 0 ? _a : (_f.itemData = {});
|
|
41
43
|
(_b = (_g = dataRef.current).childrenIds) !== null && _b !== void 0 ? _b : (_g.childrenIds = {});
|
|
42
44
|
if (dataRef.current.childrenIds[itemId]) {
|
|
43
45
|
return dataRef.current.childrenIds[itemId];
|
|
44
46
|
}
|
|
45
|
-
if (
|
|
47
|
+
if (tree.getState().loadingItems.includes(itemId)) {
|
|
46
48
|
return [];
|
|
47
49
|
}
|
|
48
|
-
|
|
50
|
+
tree.applySubStateUpdate("loadingItems", (loadingItems) => [
|
|
49
51
|
...loadingItems,
|
|
50
52
|
itemId,
|
|
51
53
|
]);
|
|
@@ -59,8 +61,8 @@ exports.asyncDataLoaderFeature = {
|
|
|
59
61
|
const childrenIds = children.map(({ id }) => id);
|
|
60
62
|
dataRef.current.childrenIds[itemId] = childrenIds;
|
|
61
63
|
(_b = config.onLoadedChildren) === null || _b === void 0 ? void 0 : _b.call(config, itemId, childrenIds);
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
tree.applySubStateUpdate("loadingItems", (loadingItems) => loadingItems.filter((id) => id !== itemId));
|
|
65
|
+
tree.rebuildTree();
|
|
64
66
|
});
|
|
65
67
|
}
|
|
66
68
|
else {
|
|
@@ -68,21 +70,31 @@ exports.asyncDataLoaderFeature = {
|
|
|
68
70
|
var _a;
|
|
69
71
|
dataRef.current.childrenIds[itemId] = childrenIds;
|
|
70
72
|
(_a = config.onLoadedChildren) === null || _a === void 0 ? void 0 : _a.call(config, itemId, childrenIds);
|
|
71
|
-
|
|
72
|
-
|
|
73
|
+
tree.applySubStateUpdate("loadingItems", (loadingItems) => loadingItems.filter((id) => id !== itemId));
|
|
74
|
+
tree.rebuildTree();
|
|
73
75
|
});
|
|
74
76
|
}
|
|
75
77
|
return [];
|
|
76
|
-
},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
itemInstance: {
|
|
81
|
+
isLoading: ({ tree, item }) => tree.getState().loadingItems.includes(item.getItemMeta().itemId),
|
|
82
|
+
invalidateItemData: ({ tree, itemId }) => {
|
|
77
83
|
var _a;
|
|
78
|
-
const dataRef =
|
|
84
|
+
const dataRef = tree.getDataRef();
|
|
79
85
|
(_a = dataRef.current.itemData) === null || _a === void 0 ? true : delete _a[itemId];
|
|
80
|
-
|
|
81
|
-
},
|
|
86
|
+
tree.retrieveItemData(itemId);
|
|
87
|
+
},
|
|
88
|
+
invalidateChildrenIds: ({ tree, itemId }) => {
|
|
82
89
|
var _a;
|
|
83
|
-
const dataRef =
|
|
90
|
+
const dataRef = tree.getDataRef();
|
|
84
91
|
(_a = dataRef.current.childrenIds) === null || _a === void 0 ? true : delete _a[itemId];
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
|
|
92
|
+
tree.retrieveChildrenIds(itemId);
|
|
93
|
+
},
|
|
94
|
+
updateCachedChildrenIds: ({ tree, itemId }, childrenIds) => {
|
|
95
|
+
const dataRef = tree.getDataRef();
|
|
96
|
+
dataRef.current.childrenIds[itemId] = childrenIds;
|
|
97
|
+
tree.rebuildTree();
|
|
98
|
+
},
|
|
99
|
+
},
|
|
88
100
|
};
|
|
@@ -27,15 +27,13 @@ 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;
|
|
36
|
+
isLoading: () => boolean;
|
|
39
37
|
};
|
|
40
38
|
hotkeys: SyncDataLoaderFeatureDef<T>["hotkeys"];
|
|
41
39
|
};
|
|
@@ -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;
|
|
@@ -4,47 +4,69 @@ exports.dragAndDropFeature = void 0;
|
|
|
4
4
|
const utils_1 = require("./utils");
|
|
5
5
|
const utils_2 = require("../../utils");
|
|
6
6
|
exports.dragAndDropFeature = {
|
|
7
|
-
key: "
|
|
7
|
+
key: "drag-and-drop",
|
|
8
8
|
deps: ["selection"],
|
|
9
|
-
getDefaultConfig: (defaultConfig, tree) => (Object.assign({ canDrop: (_, target) => target.item.isFolder(), canDropForeignDragObject: () => false, setDndState: (0, utils_2.makeStateUpdater)("dnd", tree) }, defaultConfig)),
|
|
9
|
+
getDefaultConfig: (defaultConfig, tree) => (Object.assign({ canDrop: (_, target) => target.item.isFolder(), canDropForeignDragObject: () => false, setDndState: (0, utils_2.makeStateUpdater)("dnd", tree), canReorder: true }, defaultConfig)),
|
|
10
10
|
stateHandlerNames: {
|
|
11
11
|
dnd: "setDndState",
|
|
12
12
|
},
|
|
13
|
-
|
|
13
|
+
treeInstance: {
|
|
14
|
+
getDropTarget: ({ tree }) => {
|
|
14
15
|
var _a, _b;
|
|
15
16
|
return (_b = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.dragTarget) !== null && _b !== void 0 ? _b : null;
|
|
16
|
-
},
|
|
17
|
-
|
|
17
|
+
},
|
|
18
|
+
getDragLineData: ({ tree }) => {
|
|
19
|
+
var _a, _b, _c, _d, _e, _f;
|
|
18
20
|
const target = tree.getDropTarget();
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
+
const indent = ((_a = target === null || target === void 0 ? void 0 : target.item.getItemMeta().level) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
22
|
+
const treeBb = (_b = tree.getElement()) === null || _b === void 0 ? void 0 : _b.getBoundingClientRect();
|
|
23
|
+
if (!target || !treeBb || target.childIndex === null)
|
|
21
24
|
return null;
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
const leftOffset = target.dragLineLevel * ((_c = tree.getConfig().indent) !== null && _c !== void 0 ? _c : 1);
|
|
26
|
+
const targetItem = tree.getItems()[target.dragLineIndex];
|
|
27
|
+
if (!targetItem) {
|
|
28
|
+
const bb = (_e = (_d = tree
|
|
29
|
+
.getItems()[target.dragLineIndex - 1]) === null || _d === void 0 ? void 0 : _d.getElement()) === null || _e === void 0 ? void 0 : _e.getBoundingClientRect();
|
|
25
30
|
if (bb) {
|
|
26
31
|
return {
|
|
27
|
-
|
|
28
|
-
top: bb.bottom,
|
|
29
|
-
left: bb.left,
|
|
30
|
-
|
|
32
|
+
indent,
|
|
33
|
+
top: bb.bottom - treeBb.bottom,
|
|
34
|
+
left: bb.left + leftOffset - treeBb.left,
|
|
35
|
+
width: bb.width - leftOffset,
|
|
31
36
|
};
|
|
32
37
|
}
|
|
33
38
|
}
|
|
34
|
-
const bb = (
|
|
39
|
+
const bb = (_f = targetItem.getElement()) === null || _f === void 0 ? void 0 : _f.getBoundingClientRect();
|
|
35
40
|
if (bb) {
|
|
36
41
|
return {
|
|
37
|
-
|
|
38
|
-
top: bb.top,
|
|
39
|
-
left: bb.left,
|
|
40
|
-
|
|
42
|
+
indent,
|
|
43
|
+
top: bb.top - treeBb.top,
|
|
44
|
+
left: bb.left + leftOffset - treeBb.left,
|
|
45
|
+
width: bb.width - leftOffset,
|
|
41
46
|
};
|
|
42
47
|
}
|
|
43
48
|
return null;
|
|
44
|
-
}
|
|
45
|
-
|
|
49
|
+
},
|
|
50
|
+
getDragLineStyle: ({ tree }, topOffset = -1, leftOffset = -8) => {
|
|
51
|
+
const dragLine = tree.getDragLineData();
|
|
52
|
+
return dragLine
|
|
53
|
+
? {
|
|
54
|
+
top: `${dragLine.top + topOffset}px`,
|
|
55
|
+
left: `${dragLine.left + leftOffset}px`,
|
|
56
|
+
width: `${dragLine.width - leftOffset}px`,
|
|
57
|
+
pointerEvents: "none", // important to prevent capturing drag events
|
|
58
|
+
}
|
|
59
|
+
: { display: "none" };
|
|
60
|
+
},
|
|
61
|
+
getContainerProps: ({ prev }) => {
|
|
62
|
+
const prevProps = prev === null || prev === void 0 ? void 0 : prev();
|
|
63
|
+
return Object.assign(Object.assign({}, prevProps), { style: Object.assign(Object.assign({}, prevProps === null || prevProps === void 0 ? void 0 : prevProps.style), { position: "relative" }) });
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
itemInstance: {
|
|
67
|
+
getProps: ({ tree, item, prev }) => {
|
|
46
68
|
var _a, _b, _c;
|
|
47
|
-
return (Object.assign(Object.assign({}, prev
|
|
69
|
+
return (Object.assign(Object.assign({}, prev === null || prev === void 0 ? void 0 : prev()), { draggable: (_c = (_b = (_a = tree.getConfig()).isItemDraggable) === null || _b === void 0 ? void 0 : _b.call(_a, item)) !== null && _c !== void 0 ? _c : true, onDragStart: (e) => {
|
|
48
70
|
var _a, _b, _c;
|
|
49
71
|
const selectedItems = tree.getSelectedItems();
|
|
50
72
|
const items = selectedItems.includes(item) ? selectedItems : [item];
|
|
@@ -64,37 +86,45 @@ exports.dragAndDropFeature = {
|
|
|
64
86
|
draggedItems: items,
|
|
65
87
|
draggingOverItem: tree.getFocusedItem(),
|
|
66
88
|
});
|
|
67
|
-
}
|
|
89
|
+
}, onDragOver: (e) => {
|
|
68
90
|
var _a, _b, _c;
|
|
69
|
-
const target = (0, utils_1.getDropTarget)(e, item, tree);
|
|
70
91
|
const dataRef = tree.getDataRef();
|
|
71
|
-
|
|
72
|
-
|
|
92
|
+
const nextDragCode = (0, utils_1.getDragCode)(e, item, tree);
|
|
93
|
+
if (nextDragCode === dataRef.current.lastDragCode) {
|
|
94
|
+
if (dataRef.current.lastAllowDrop) {
|
|
95
|
+
e.preventDefault();
|
|
96
|
+
}
|
|
73
97
|
return;
|
|
74
98
|
}
|
|
75
|
-
|
|
99
|
+
dataRef.current.lastDragCode = nextDragCode;
|
|
100
|
+
const target = (0, utils_1.getDropTarget)(e, item, tree);
|
|
101
|
+
if (!((_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems) &&
|
|
102
|
+
(!e.dataTransfer ||
|
|
103
|
+
!((_c = (_b = tree
|
|
104
|
+
.getConfig()).canDropForeignDragObject) === null || _c === void 0 ? void 0 : _c.call(_b, e.dataTransfer, target)))) {
|
|
105
|
+
dataRef.current.lastAllowDrop = false;
|
|
76
106
|
return;
|
|
77
107
|
}
|
|
78
|
-
e.
|
|
79
|
-
|
|
80
|
-
if (nextDragCode === dataRef.current.lastDragCode) {
|
|
108
|
+
if (!(0, utils_1.canDrop)(e.dataTransfer, target, tree)) {
|
|
109
|
+
dataRef.current.lastAllowDrop = false;
|
|
81
110
|
return;
|
|
82
111
|
}
|
|
83
|
-
dataRef.current.lastDragCode = nextDragCode;
|
|
84
112
|
tree.applySubStateUpdate("dnd", (state) => (Object.assign(Object.assign({}, state), { dragTarget: target, draggingOverItem: item })));
|
|
85
|
-
|
|
113
|
+
dataRef.current.lastAllowDrop = true;
|
|
114
|
+
e.preventDefault();
|
|
115
|
+
}, onDragLeave: () => {
|
|
86
116
|
const dataRef = tree.getDataRef();
|
|
87
117
|
dataRef.current.lastDragCode = "no-drag";
|
|
88
118
|
tree.applySubStateUpdate("dnd", (state) => (Object.assign(Object.assign({}, state), { draggingOverItem: undefined, dragTarget: undefined })));
|
|
89
|
-
}
|
|
90
|
-
var _a, _b, _c;
|
|
119
|
+
}, onDragEnd: (e) => {
|
|
120
|
+
var _a, _b, _c, _d;
|
|
91
121
|
const draggedItems = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems;
|
|
92
122
|
tree.applySubStateUpdate("dnd", null);
|
|
93
|
-
if (e.dataTransfer.dropEffect === "none" || !draggedItems) {
|
|
123
|
+
if (((_b = e.dataTransfer) === null || _b === void 0 ? void 0 : _b.dropEffect) === "none" || !draggedItems) {
|
|
94
124
|
return;
|
|
95
125
|
}
|
|
96
|
-
(
|
|
97
|
-
}
|
|
126
|
+
(_d = (_c = tree.getConfig()).onCompleteForeignDrop) === null || _d === void 0 ? void 0 : _d.call(_c, draggedItems);
|
|
127
|
+
}, onDrop: (e) => {
|
|
98
128
|
var _a, _b, _c;
|
|
99
129
|
const dataRef = tree.getDataRef();
|
|
100
130
|
const target = (0, utils_1.getDropTarget)(e, item, tree);
|
|
@@ -109,30 +139,35 @@ exports.dragAndDropFeature = {
|
|
|
109
139
|
if (draggedItems) {
|
|
110
140
|
(_b = config.onDrop) === null || _b === void 0 ? void 0 : _b.call(config, draggedItems, target);
|
|
111
141
|
}
|
|
112
|
-
else {
|
|
142
|
+
else if (e.dataTransfer) {
|
|
113
143
|
(_c = config.onDropForeignDragObject) === null || _c === void 0 ? void 0 : _c.call(config, e.dataTransfer, target);
|
|
114
144
|
}
|
|
115
145
|
// TODO rebuild tree?
|
|
116
|
-
}
|
|
117
|
-
},
|
|
146
|
+
} }));
|
|
147
|
+
},
|
|
148
|
+
isDropTarget: ({ tree, item }) => {
|
|
118
149
|
const target = tree.getDropTarget();
|
|
119
150
|
return target ? target.item.getId() === item.getId() : false;
|
|
120
|
-
},
|
|
151
|
+
},
|
|
152
|
+
isDropTargetAbove: ({ tree, item }) => {
|
|
121
153
|
const target = tree.getDropTarget();
|
|
122
154
|
if (!target ||
|
|
123
155
|
target.childIndex === null ||
|
|
124
156
|
target.item !== item.getParent())
|
|
125
157
|
return false;
|
|
126
158
|
return target.childIndex === item.getItemMeta().posInSet;
|
|
127
|
-
},
|
|
159
|
+
},
|
|
160
|
+
isDropTargetBelow: ({ tree, item }) => {
|
|
128
161
|
const target = tree.getDropTarget();
|
|
129
162
|
if (!target ||
|
|
130
163
|
target.childIndex === null ||
|
|
131
164
|
target.item !== item.getParent())
|
|
132
165
|
return false;
|
|
133
166
|
return target.childIndex - 1 === item.getItemMeta().posInSet;
|
|
134
|
-
},
|
|
167
|
+
},
|
|
168
|
+
isDraggingOver: ({ tree, item }) => {
|
|
135
169
|
var _a, _b;
|
|
136
170
|
return ((_b = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggingOverItem) === null || _b === void 0 ? void 0 : _b.getId()) === item.getId();
|
|
137
|
-
}
|
|
171
|
+
},
|
|
172
|
+
},
|
|
138
173
|
};
|