@headless-tree/core 0.0.0-20250224204705 → 0.0.0-20250322153940
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 +13 -1
- package/lib/cjs/core/create-tree.js +13 -4
- package/lib/cjs/features/async-data-loader/feature.js +73 -48
- package/lib/cjs/features/async-data-loader/types.d.ts +17 -14
- package/lib/cjs/features/drag-and-drop/feature.js +89 -84
- package/lib/cjs/features/drag-and-drop/types.d.ts +8 -20
- package/lib/cjs/features/drag-and-drop/utils.js +8 -21
- package/lib/cjs/features/expand-all/feature.js +26 -3
- package/lib/cjs/features/expand-all/types.d.ts +3 -1
- package/lib/cjs/features/hotkeys-core/feature.js +6 -3
- package/lib/cjs/features/hotkeys-core/types.d.ts +4 -5
- package/lib/cjs/features/prop-memoization/feature.js +2 -2
- package/lib/cjs/features/prop-memoization/types.d.ts +2 -2
- package/lib/cjs/features/renaming/feature.js +1 -1
- package/lib/cjs/features/search/feature.js +2 -0
- package/lib/cjs/features/search/types.d.ts +2 -2
- package/lib/cjs/features/selection/feature.js +4 -4
- package/lib/cjs/features/selection/types.d.ts +1 -1
- package/lib/cjs/features/sync-data-loader/feature.js +31 -5
- package/lib/cjs/features/sync-data-loader/types.d.ts +5 -5
- package/lib/cjs/features/tree/feature.js +4 -7
- package/lib/cjs/features/tree/types.d.ts +7 -5
- package/lib/cjs/test-utils/test-tree-do.d.ts +2 -2
- package/lib/cjs/test-utils/test-tree-do.js +19 -6
- package/lib/cjs/test-utils/test-tree.d.ts +2 -1
- package/lib/cjs/test-utils/test-tree.js +24 -21
- package/lib/cjs/utilities/create-on-drop-handler.d.ts +1 -1
- package/lib/cjs/utilities/create-on-drop-handler.js +13 -4
- package/lib/cjs/utilities/insert-items-at-target.d.ts +1 -1
- package/lib/cjs/utilities/insert-items-at-target.js +21 -12
- package/lib/cjs/utilities/remove-items-from-parents.d.ts +1 -1
- package/lib/cjs/utilities/remove-items-from-parents.js +12 -3
- package/lib/esm/core/create-tree.js +13 -4
- package/lib/esm/features/async-data-loader/feature.js +73 -48
- package/lib/esm/features/async-data-loader/types.d.ts +17 -14
- package/lib/esm/features/drag-and-drop/feature.js +89 -84
- package/lib/esm/features/drag-and-drop/types.d.ts +8 -20
- package/lib/esm/features/drag-and-drop/utils.js +8 -21
- package/lib/esm/features/expand-all/feature.js +26 -3
- package/lib/esm/features/expand-all/types.d.ts +3 -1
- package/lib/esm/features/hotkeys-core/feature.js +6 -3
- package/lib/esm/features/hotkeys-core/types.d.ts +4 -5
- package/lib/esm/features/prop-memoization/feature.js +2 -2
- package/lib/esm/features/prop-memoization/types.d.ts +2 -2
- package/lib/esm/features/renaming/feature.js +1 -1
- package/lib/esm/features/search/feature.js +2 -0
- package/lib/esm/features/search/types.d.ts +2 -2
- package/lib/esm/features/selection/feature.js +4 -4
- package/lib/esm/features/selection/types.d.ts +1 -1
- package/lib/esm/features/sync-data-loader/feature.js +31 -5
- package/lib/esm/features/sync-data-loader/types.d.ts +5 -5
- package/lib/esm/features/tree/feature.js +4 -7
- package/lib/esm/features/tree/types.d.ts +7 -5
- package/lib/esm/test-utils/test-tree-do.d.ts +2 -2
- package/lib/esm/test-utils/test-tree-do.js +19 -6
- package/lib/esm/test-utils/test-tree.d.ts +2 -1
- package/lib/esm/test-utils/test-tree.js +24 -21
- package/lib/esm/utilities/create-on-drop-handler.d.ts +1 -1
- package/lib/esm/utilities/create-on-drop-handler.js +13 -4
- package/lib/esm/utilities/insert-items-at-target.d.ts +1 -1
- package/lib/esm/utilities/insert-items-at-target.js +21 -12
- package/lib/esm/utilities/remove-items-from-parents.d.ts +1 -1
- package/lib/esm/utilities/remove-items-from-parents.js +12 -3
- package/package.json +2 -2
- package/src/core/core.spec.ts +31 -0
- package/src/core/create-tree.ts +15 -5
- package/src/features/async-data-loader/async-data-loader.spec.ts +10 -6
- package/src/features/async-data-loader/feature.ts +76 -48
- package/src/features/async-data-loader/types.ts +18 -11
- package/src/features/drag-and-drop/drag-and-drop.spec.ts +69 -83
- package/src/features/drag-and-drop/feature.ts +9 -10
- package/src/features/drag-and-drop/types.ts +15 -27
- package/src/features/drag-and-drop/utils.ts +7 -20
- package/src/features/expand-all/feature.ts +29 -5
- package/src/features/expand-all/types.ts +3 -1
- package/src/features/hotkeys-core/feature.ts +3 -0
- package/src/features/hotkeys-core/types.ts +4 -13
- package/src/features/prop-memoization/feature.ts +2 -2
- package/src/features/prop-memoization/prop-memoization.spec.ts +2 -2
- package/src/features/prop-memoization/types.ts +2 -2
- package/src/features/renaming/feature.ts +8 -2
- package/src/features/search/feature.ts +2 -0
- package/src/features/search/types.ts +2 -2
- package/src/features/selection/feature.ts +4 -4
- package/src/features/selection/types.ts +1 -1
- package/src/features/sync-data-loader/feature.ts +26 -7
- package/src/features/sync-data-loader/types.ts +5 -5
- package/src/features/tree/feature.ts +8 -11
- package/src/features/tree/types.ts +7 -5
- package/src/test-utils/test-tree-do.ts +3 -3
- package/src/test-utils/test-tree.ts +26 -22
- package/src/utilities/create-on-drop-handler.ts +3 -3
- package/src/utilities/insert-items-at-target.ts +16 -12
- package/src/utilities/remove-items-from-parents.ts +6 -3
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
2
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
12
|
exports.removeItemsFromParents = void 0;
|
|
4
|
-
const removeItemsFromParents = (movedItems, onChangeChildren) => {
|
|
13
|
+
const removeItemsFromParents = (movedItems, onChangeChildren) => __awaiter(void 0, void 0, void 0, function* () {
|
|
5
14
|
const movedItemsIds = movedItems.map((item) => item.getId());
|
|
6
15
|
const uniqueParents = [
|
|
7
16
|
...new Set(movedItems.map((item) => item.getParent())),
|
|
@@ -12,12 +21,12 @@ const removeItemsFromParents = (movedItems, onChangeChildren) => {
|
|
|
12
21
|
const newChildren = siblings
|
|
13
22
|
.filter((sibling) => !movedItemsIds.includes(sibling.getId()))
|
|
14
23
|
.map((i) => i.getId());
|
|
15
|
-
onChangeChildren(parent, newChildren);
|
|
24
|
+
yield onChangeChildren(parent, newChildren);
|
|
16
25
|
if (parent && "updateCachedChildrenIds" in parent) {
|
|
17
26
|
parent === null || parent === void 0 ? void 0 : parent.updateCachedChildrenIds(newChildren);
|
|
18
27
|
}
|
|
19
28
|
}
|
|
20
29
|
}
|
|
21
30
|
movedItems[0].getTree().rebuildTree();
|
|
22
|
-
};
|
|
31
|
+
});
|
|
23
32
|
exports.removeItemsFromParents = removeItemsFromParents;
|
|
@@ -89,6 +89,7 @@ export const createTree = (initialConfig) => {
|
|
|
89
89
|
// Not necessary, since I think the subupdate below keeps the state fresh anyways?
|
|
90
90
|
// state = typeof updater === "function" ? updater(state) : updater;
|
|
91
91
|
(_a = config.setState) === null || _a === void 0 ? void 0 : _a.call(config, state); // TODO this cant be right... This doesnt allow external state updates
|
|
92
|
+
// TODO this is never used, remove
|
|
92
93
|
},
|
|
93
94
|
applySubStateUpdate: ({}, stateName, updater) => {
|
|
94
95
|
state[stateName] =
|
|
@@ -104,9 +105,18 @@ export const createTree = (initialConfig) => {
|
|
|
104
105
|
},
|
|
105
106
|
getConfig: () => config,
|
|
106
107
|
setConfig: (_, updater) => {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
108
|
+
var _a, _b, _c;
|
|
109
|
+
const newConfig = typeof updater === "function" ? updater(config) : updater;
|
|
110
|
+
const hasChangedExpandedItems = ((_a = newConfig.state) === null || _a === void 0 ? void 0 : _a.expandedItems) &&
|
|
111
|
+
((_b = newConfig.state) === null || _b === void 0 ? void 0 : _b.expandedItems) !== state.expandedItems;
|
|
112
|
+
config = newConfig;
|
|
113
|
+
if (newConfig.state) {
|
|
114
|
+
state = Object.assign(Object.assign({}, state), newConfig.state);
|
|
115
|
+
}
|
|
116
|
+
if (hasChangedExpandedItems) {
|
|
117
|
+
// if expanded items where changed from the outside
|
|
118
|
+
rebuildItemMeta();
|
|
119
|
+
(_c = config.setState) === null || _c === void 0 ? void 0 : _c.call(config, state);
|
|
110
120
|
}
|
|
111
121
|
},
|
|
112
122
|
getItemInstance: ({}, itemId) => itemInstancesMap[itemId],
|
|
@@ -128,7 +138,6 @@ export const createTree = (initialConfig) => {
|
|
|
128
138
|
getHotkeyPresets: () => hotkeyPresets,
|
|
129
139
|
},
|
|
130
140
|
itemInstance: {
|
|
131
|
-
// TODO just change to a getRef method that memoizes, maybe as part of getProps
|
|
132
141
|
registerElement: ({ itemId, item }, element) => {
|
|
133
142
|
if (itemElementsMap[itemId] === element) {
|
|
134
143
|
return;
|
|
@@ -1,81 +1,106 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
1
10
|
import { makeStateUpdater } from "../../utils";
|
|
2
11
|
export const asyncDataLoaderFeature = {
|
|
3
12
|
key: "async-data-loader",
|
|
4
|
-
getInitialState: (initialState) => (Object.assign({
|
|
5
|
-
getDefaultConfig: (defaultConfig, tree) => (Object.assign({
|
|
13
|
+
getInitialState: (initialState) => (Object.assign({ loadingItemData: [], loadingItemChildrens: [] }, initialState)),
|
|
14
|
+
getDefaultConfig: (defaultConfig, tree) => (Object.assign({ setLoadingItemData: makeStateUpdater("loadingItemData", tree), setLoadingItemChildrens: makeStateUpdater("loadingItemChildrens", tree) }, defaultConfig)),
|
|
6
15
|
stateHandlerNames: {
|
|
7
|
-
|
|
16
|
+
loadingItemData: "setLoadingItemData",
|
|
17
|
+
loadingItemChildrens: "setLoadingItemChildrens",
|
|
8
18
|
},
|
|
9
19
|
treeInstance: {
|
|
20
|
+
waitForItemDataLoaded: (_a, itemId_1) => __awaiter(void 0, [_a, itemId_1], void 0, function* ({ tree }, itemId) {
|
|
21
|
+
tree.retrieveItemData(itemId);
|
|
22
|
+
if (!tree.getState().loadingItemData.includes(itemId)) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
yield new Promise((resolve) => {
|
|
26
|
+
var _a, _b;
|
|
27
|
+
var _c, _d;
|
|
28
|
+
const dataRef = tree.getDataRef();
|
|
29
|
+
(_a = (_c = dataRef.current).awaitingItemDataLoading) !== null && _a !== void 0 ? _a : (_c.awaitingItemDataLoading = {});
|
|
30
|
+
(_b = (_d = dataRef.current.awaitingItemDataLoading)[itemId]) !== null && _b !== void 0 ? _b : (_d[itemId] = []);
|
|
31
|
+
dataRef.current.awaitingItemDataLoading[itemId].push(resolve);
|
|
32
|
+
});
|
|
33
|
+
}),
|
|
34
|
+
waitForItemChildrenLoaded: (_a, itemId_1) => __awaiter(void 0, [_a, itemId_1], void 0, function* ({ tree }, itemId) {
|
|
35
|
+
tree.retrieveChildrenIds(itemId);
|
|
36
|
+
if (!tree.getState().loadingItemChildrens.includes(itemId)) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
yield new Promise((resolve) => {
|
|
40
|
+
var _a, _b;
|
|
41
|
+
var _c, _d;
|
|
42
|
+
const dataRef = tree.getDataRef();
|
|
43
|
+
(_a = (_c = dataRef.current).awaitingItemChildrensLoading) !== null && _a !== void 0 ? _a : (_c.awaitingItemChildrensLoading = {});
|
|
44
|
+
(_b = (_d = dataRef.current.awaitingItemChildrensLoading)[itemId]) !== null && _b !== void 0 ? _b : (_d[itemId] = []);
|
|
45
|
+
dataRef.current.awaitingItemChildrensLoading[itemId].push(resolve);
|
|
46
|
+
});
|
|
47
|
+
}),
|
|
10
48
|
retrieveItemData: ({ tree }, itemId) => {
|
|
11
|
-
var _a, _b, _c, _d
|
|
12
|
-
var
|
|
49
|
+
var _a, _b, _c, _d;
|
|
50
|
+
var _e, _f;
|
|
13
51
|
const config = tree.getConfig();
|
|
14
52
|
const dataRef = tree.getDataRef();
|
|
15
|
-
(_a = (
|
|
16
|
-
(_b = (
|
|
53
|
+
(_a = (_e = dataRef.current).itemData) !== null && _a !== void 0 ? _a : (_e.itemData = {});
|
|
54
|
+
(_b = (_f = dataRef.current).childrenIds) !== null && _b !== void 0 ? _b : (_f.childrenIds = {});
|
|
17
55
|
if (dataRef.current.itemData[itemId]) {
|
|
18
56
|
return dataRef.current.itemData[itemId];
|
|
19
57
|
}
|
|
20
|
-
if (!tree.getState().
|
|
21
|
-
tree.applySubStateUpdate("
|
|
22
|
-
...
|
|
58
|
+
if (!tree.getState().loadingItemData.includes(itemId)) {
|
|
59
|
+
tree.applySubStateUpdate("loadingItemData", (loadingItemData) => [
|
|
60
|
+
...loadingItemData,
|
|
23
61
|
itemId,
|
|
24
62
|
]);
|
|
25
|
-
(
|
|
26
|
-
var _a;
|
|
63
|
+
(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
64
|
+
var _a, _b, _c;
|
|
65
|
+
const item = yield config.dataLoader.getItem(itemId);
|
|
27
66
|
dataRef.current.itemData[itemId] = item;
|
|
28
67
|
(_a = config.onLoadedItem) === null || _a === void 0 ? void 0 : _a.call(config, itemId, item);
|
|
29
|
-
tree.applySubStateUpdate("
|
|
30
|
-
|
|
68
|
+
tree.applySubStateUpdate("loadingItemData", (loadingItemData) => loadingItemData.filter((id) => id !== itemId));
|
|
69
|
+
(_b = dataRef.current.awaitingItemDataLoading) === null || _b === void 0 ? void 0 : _b[itemId].forEach((cb) => cb());
|
|
70
|
+
(_c = dataRef.current.awaitingItemDataLoading) === null || _c === void 0 ? true : delete _c[itemId];
|
|
71
|
+
}))();
|
|
31
72
|
}
|
|
32
|
-
return (
|
|
73
|
+
return (_d = (_c = config.createLoadingItemData) === null || _c === void 0 ? void 0 : _c.call(config)) !== null && _d !== void 0 ? _d : null;
|
|
33
74
|
},
|
|
34
75
|
retrieveChildrenIds: ({ tree }, itemId) => {
|
|
35
|
-
var _a
|
|
36
|
-
var
|
|
76
|
+
var _a;
|
|
77
|
+
var _b;
|
|
37
78
|
const config = tree.getConfig();
|
|
38
79
|
const dataRef = tree.getDataRef();
|
|
39
|
-
(_a = (
|
|
40
|
-
(_b = (_g = dataRef.current).childrenIds) !== null && _b !== void 0 ? _b : (_g.childrenIds = {});
|
|
80
|
+
(_a = (_b = dataRef.current).childrenIds) !== null && _a !== void 0 ? _a : (_b.childrenIds = {});
|
|
41
81
|
if (dataRef.current.childrenIds[itemId]) {
|
|
42
82
|
return dataRef.current.childrenIds[itemId];
|
|
43
83
|
}
|
|
44
|
-
if (tree.getState().
|
|
84
|
+
if (tree.getState().loadingItemChildrens.includes(itemId)) {
|
|
45
85
|
return [];
|
|
46
86
|
}
|
|
47
|
-
tree.applySubStateUpdate("
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const childrenIds = children.map(({ id }) => id);
|
|
59
|
-
dataRef.current.childrenIds[itemId] = childrenIds;
|
|
60
|
-
(_b = config.onLoadedChildren) === null || _b === void 0 ? void 0 : _b.call(config, itemId, childrenIds);
|
|
61
|
-
tree.applySubStateUpdate("loadingItems", (loadingItems) => loadingItems.filter((id) => id !== itemId));
|
|
62
|
-
tree.rebuildTree();
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
(_e = config.asyncDataLoader) === null || _e === void 0 ? void 0 : _e.getChildren(itemId).then((childrenIds) => {
|
|
67
|
-
var _a;
|
|
68
|
-
dataRef.current.childrenIds[itemId] = childrenIds;
|
|
69
|
-
(_a = config.onLoadedChildren) === null || _a === void 0 ? void 0 : _a.call(config, itemId, childrenIds);
|
|
70
|
-
tree.applySubStateUpdate("loadingItems", (loadingItems) => loadingItems.filter((id) => id !== itemId));
|
|
71
|
-
tree.rebuildTree();
|
|
72
|
-
});
|
|
73
|
-
}
|
|
87
|
+
tree.applySubStateUpdate("loadingItemChildrens", (loadingItemChildrens) => [...loadingItemChildrens, itemId]);
|
|
88
|
+
(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
89
|
+
var _a, _b, _c, _d;
|
|
90
|
+
const childrenIds = yield config.dataLoader.getChildren(itemId);
|
|
91
|
+
dataRef.current.childrenIds[itemId] = childrenIds;
|
|
92
|
+
(_a = config.onLoadedChildren) === null || _a === void 0 ? void 0 : _a.call(config, itemId, childrenIds);
|
|
93
|
+
tree.applySubStateUpdate("loadingItemChildrens", (loadingItemChildrens) => loadingItemChildrens.filter((id) => id !== itemId));
|
|
94
|
+
tree.rebuildTree();
|
|
95
|
+
(_c = (_b = dataRef.current.awaitingItemChildrensLoading) === null || _b === void 0 ? void 0 : _b[itemId]) === null || _c === void 0 ? void 0 : _c.forEach((cb) => cb());
|
|
96
|
+
(_d = dataRef.current.awaitingItemChildrensLoading) === null || _d === void 0 ? true : delete _d[itemId];
|
|
97
|
+
}))();
|
|
74
98
|
return [];
|
|
75
99
|
},
|
|
76
100
|
},
|
|
77
101
|
itemInstance: {
|
|
78
|
-
isLoading: ({ tree, item }) => tree.getState().
|
|
102
|
+
isLoading: ({ tree, item }) => tree.getState().loadingItemData.includes(item.getItemMeta().itemId) ||
|
|
103
|
+
tree.getState().loadingItemChildrens.includes(item.getItemMeta().itemId),
|
|
79
104
|
invalidateItemData: ({ tree, itemId }) => {
|
|
80
105
|
var _a;
|
|
81
106
|
const dataRef = tree.getDataRef();
|
|
@@ -1,33 +1,35 @@
|
|
|
1
1
|
import { SetStateFn } from "../../types/core";
|
|
2
2
|
import { SyncDataLoaderFeatureDef } from "../sync-data-loader/types";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
getChildren: (itemId: string) => Promise<string[]>;
|
|
6
|
-
getChildrenWithData?: (itemId: string) => Promise<{
|
|
7
|
-
id: string;
|
|
8
|
-
data: T;
|
|
9
|
-
}[]>;
|
|
10
|
-
};
|
|
11
|
-
export type AsyncDataLoaderRef<T = any> = {
|
|
3
|
+
type AwaitingLoaderCallbacks = Record<string, (() => void)[]>;
|
|
4
|
+
export interface AsyncDataLoaderDataRef<T = any> {
|
|
12
5
|
itemData: Record<string, T>;
|
|
13
6
|
childrenIds: Record<string, string[]>;
|
|
14
|
-
|
|
7
|
+
awaitingItemDataLoading: AwaitingLoaderCallbacks;
|
|
8
|
+
awaitingItemChildrensLoading: AwaitingLoaderCallbacks;
|
|
9
|
+
}
|
|
15
10
|
/**
|
|
16
11
|
* @category Async Data Loader/General
|
|
17
12
|
* */
|
|
18
13
|
export type AsyncDataLoaderFeatureDef<T> = {
|
|
19
14
|
state: {
|
|
20
|
-
|
|
15
|
+
loadingItemData: string[];
|
|
16
|
+
loadingItemChildrens: string[];
|
|
21
17
|
};
|
|
22
18
|
config: {
|
|
23
19
|
rootItemId: string;
|
|
20
|
+
/** Will be called when HT retrieves item data for an item whose item data is asynchronously being loaded.
|
|
21
|
+
* Can be used to create placeholder data to use for rendering the tree item while it is loaded. If not defined,
|
|
22
|
+
* the tree item data will be null. */
|
|
24
23
|
createLoadingItemData?: () => T;
|
|
25
|
-
|
|
24
|
+
setLoadingItemData?: SetStateFn<string[]>;
|
|
25
|
+
setLoadingItemChildrens?: SetStateFn<string[]>;
|
|
26
26
|
onLoadedItem?: (itemId: string, item: T) => void;
|
|
27
27
|
onLoadedChildren?: (itemId: string, childrenIds: string[]) => void;
|
|
28
|
-
asyncDataLoader?: AsyncTreeDataLoader<T>;
|
|
29
28
|
};
|
|
30
|
-
treeInstance: SyncDataLoaderFeatureDef<T>["treeInstance"]
|
|
29
|
+
treeInstance: SyncDataLoaderFeatureDef<T>["treeInstance"] & {
|
|
30
|
+
waitForItemDataLoaded: (itemId: string) => Promise<void>;
|
|
31
|
+
waitForItemChildrenLoaded: (itemId: string) => Promise<void>;
|
|
32
|
+
};
|
|
31
33
|
itemInstance: SyncDataLoaderFeatureDef<T>["itemInstance"] & {
|
|
32
34
|
/** Invalidate fetched data for item, and triggers a refetch and subsequent rerender if the item is visible */
|
|
33
35
|
invalidateItemData: () => void;
|
|
@@ -37,3 +39,4 @@ export type AsyncDataLoaderFeatureDef<T> = {
|
|
|
37
39
|
};
|
|
38
40
|
hotkeys: SyncDataLoaderFeatureDef<T>["hotkeys"];
|
|
39
41
|
};
|
|
42
|
+
export {};
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
1
10
|
import { canDrop, getDragCode, getDropTarget } from "./utils";
|
|
2
11
|
import { makeStateUpdater } from "../../utils";
|
|
3
12
|
export const dragAndDropFeature = {
|
|
@@ -17,7 +26,7 @@ export const dragAndDropFeature = {
|
|
|
17
26
|
const target = tree.getDropTarget();
|
|
18
27
|
const indent = ((_a = target === null || target === void 0 ? void 0 : target.item.getItemMeta().level) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
19
28
|
const treeBb = (_b = tree.getElement()) === null || _b === void 0 ? void 0 : _b.getBoundingClientRect();
|
|
20
|
-
if (!target || !treeBb ||
|
|
29
|
+
if (!target || !treeBb || !("childIndex" in target))
|
|
21
30
|
return null;
|
|
22
31
|
const leftOffset = target.dragLineLevel * ((_c = tree.getConfig().indent) !== null && _c !== void 0 ? _c : 1);
|
|
23
32
|
const targetItem = tree.getItems()[target.dragLineIndex];
|
|
@@ -55,93 +64,89 @@ export const dragAndDropFeature = {
|
|
|
55
64
|
}
|
|
56
65
|
: { display: "none" };
|
|
57
66
|
},
|
|
58
|
-
getContainerProps: ({ prev }) => {
|
|
59
|
-
const prevProps = prev === null || prev === void 0 ? void 0 : prev();
|
|
67
|
+
getContainerProps: ({ prev }, treeLabel) => {
|
|
68
|
+
const prevProps = prev === null || prev === void 0 ? void 0 : prev(treeLabel);
|
|
60
69
|
return Object.assign(Object.assign({}, prevProps), { style: Object.assign(Object.assign({}, prevProps === null || prevProps === void 0 ? void 0 : prevProps.style), { position: "relative" }) });
|
|
61
70
|
},
|
|
62
71
|
},
|
|
63
72
|
itemInstance: {
|
|
64
|
-
getProps: ({ tree, item, prev }) => {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
if (!((_b = (_a = config.canDrag) === null || _a === void 0 ? void 0 : _a.call(config, items)) !== null && _b !== void 0 ? _b : true)) {
|
|
75
|
-
e.preventDefault();
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
if (config.createForeignDragObject) {
|
|
79
|
-
const { format, data } = config.createForeignDragObject(items);
|
|
80
|
-
(_c = e.dataTransfer) === null || _c === void 0 ? void 0 : _c.setData(format, data);
|
|
81
|
-
}
|
|
82
|
-
tree.applySubStateUpdate("dnd", {
|
|
83
|
-
draggedItems: items,
|
|
84
|
-
draggingOverItem: tree.getFocusedItem(),
|
|
85
|
-
});
|
|
86
|
-
}, onDragOver: (e) => {
|
|
87
|
-
var _a, _b, _c;
|
|
88
|
-
const dataRef = tree.getDataRef();
|
|
89
|
-
const nextDragCode = getDragCode(e, item, tree);
|
|
90
|
-
if (nextDragCode === dataRef.current.lastDragCode) {
|
|
91
|
-
if (dataRef.current.lastAllowDrop) {
|
|
92
|
-
e.preventDefault();
|
|
93
|
-
}
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
dataRef.current.lastDragCode = nextDragCode;
|
|
97
|
-
const target = getDropTarget(e, item, tree);
|
|
98
|
-
if (!((_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems) &&
|
|
99
|
-
(!e.dataTransfer ||
|
|
100
|
-
!((_c = (_b = tree
|
|
101
|
-
.getConfig()).canDropForeignDragObject) === null || _c === void 0 ? void 0 : _c.call(_b, e.dataTransfer, target)))) {
|
|
102
|
-
dataRef.current.lastAllowDrop = false;
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
if (!canDrop(e.dataTransfer, target, tree)) {
|
|
106
|
-
dataRef.current.lastAllowDrop = false;
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
tree.applySubStateUpdate("dnd", (state) => (Object.assign(Object.assign({}, state), { dragTarget: target, draggingOverItem: item })));
|
|
110
|
-
dataRef.current.lastAllowDrop = true;
|
|
111
|
-
e.preventDefault();
|
|
112
|
-
}, onDragLeave: () => {
|
|
113
|
-
const dataRef = tree.getDataRef();
|
|
114
|
-
dataRef.current.lastDragCode = "no-drag";
|
|
115
|
-
tree.applySubStateUpdate("dnd", (state) => (Object.assign(Object.assign({}, state), { draggingOverItem: undefined, dragTarget: undefined })));
|
|
116
|
-
}, onDragEnd: (e) => {
|
|
117
|
-
var _a, _b, _c, _d;
|
|
118
|
-
const draggedItems = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems;
|
|
119
|
-
tree.applySubStateUpdate("dnd", null);
|
|
120
|
-
if (((_b = e.dataTransfer) === null || _b === void 0 ? void 0 : _b.dropEffect) === "none" || !draggedItems) {
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
(_d = (_c = tree.getConfig()).onCompleteForeignDrop) === null || _d === void 0 ? void 0 : _d.call(_c, draggedItems);
|
|
124
|
-
}, onDrop: (e) => {
|
|
125
|
-
var _a, _b, _c;
|
|
126
|
-
const dataRef = tree.getDataRef();
|
|
127
|
-
const target = getDropTarget(e, item, tree);
|
|
128
|
-
if (!canDrop(e.dataTransfer, target, tree)) {
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
73
|
+
getProps: ({ tree, item, prev }) => (Object.assign(Object.assign({}, prev === null || prev === void 0 ? void 0 : prev()), { draggable: true, onDragStart: (e) => {
|
|
74
|
+
var _a, _b, _c;
|
|
75
|
+
const selectedItems = tree.getSelectedItems();
|
|
76
|
+
const items = selectedItems.includes(item) ? selectedItems : [item];
|
|
77
|
+
const config = tree.getConfig();
|
|
78
|
+
if (!selectedItems.includes(item)) {
|
|
79
|
+
tree.setSelectedItems([item.getItemMeta().itemId]);
|
|
80
|
+
}
|
|
81
|
+
if (!((_b = (_a = config.canDrag) === null || _a === void 0 ? void 0 : _a.call(config, items)) !== null && _b !== void 0 ? _b : true)) {
|
|
131
82
|
e.preventDefault();
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (config.createForeignDragObject) {
|
|
86
|
+
const { format, data } = config.createForeignDragObject(items);
|
|
87
|
+
(_c = e.dataTransfer) === null || _c === void 0 ? void 0 : _c.setData(format, data);
|
|
88
|
+
}
|
|
89
|
+
tree.applySubStateUpdate("dnd", {
|
|
90
|
+
draggedItems: items,
|
|
91
|
+
draggingOverItem: tree.getFocusedItem(),
|
|
92
|
+
});
|
|
93
|
+
}, onDragOver: (e) => {
|
|
94
|
+
var _a, _b, _c;
|
|
95
|
+
const dataRef = tree.getDataRef();
|
|
96
|
+
const nextDragCode = getDragCode(e, item, tree);
|
|
97
|
+
if (nextDragCode === dataRef.current.lastDragCode) {
|
|
98
|
+
if (dataRef.current.lastAllowDrop) {
|
|
99
|
+
e.preventDefault();
|
|
141
100
|
}
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
dataRef.current.lastDragCode = nextDragCode;
|
|
104
|
+
const target = getDropTarget(e, item, tree);
|
|
105
|
+
if (!((_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems) &&
|
|
106
|
+
(!e.dataTransfer ||
|
|
107
|
+
!((_c = (_b = tree
|
|
108
|
+
.getConfig()).canDropForeignDragObject) === null || _c === void 0 ? void 0 : _c.call(_b, e.dataTransfer, target)))) {
|
|
109
|
+
dataRef.current.lastAllowDrop = false;
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (!canDrop(e.dataTransfer, target, tree)) {
|
|
113
|
+
dataRef.current.lastAllowDrop = false;
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
tree.applySubStateUpdate("dnd", (state) => (Object.assign(Object.assign({}, state), { dragTarget: target, draggingOverItem: item })));
|
|
117
|
+
dataRef.current.lastAllowDrop = true;
|
|
118
|
+
e.preventDefault();
|
|
119
|
+
}, onDragLeave: () => {
|
|
120
|
+
const dataRef = tree.getDataRef();
|
|
121
|
+
dataRef.current.lastDragCode = "no-drag";
|
|
122
|
+
tree.applySubStateUpdate("dnd", (state) => (Object.assign(Object.assign({}, state), { draggingOverItem: undefined, dragTarget: undefined })));
|
|
123
|
+
}, onDragEnd: (e) => {
|
|
124
|
+
var _a, _b, _c, _d;
|
|
125
|
+
const draggedItems = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems;
|
|
126
|
+
tree.applySubStateUpdate("dnd", null);
|
|
127
|
+
if (((_b = e.dataTransfer) === null || _b === void 0 ? void 0 : _b.dropEffect) === "none" || !draggedItems) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
(_d = (_c = tree.getConfig()).onCompleteForeignDrop) === null || _d === void 0 ? void 0 : _d.call(_c, draggedItems);
|
|
131
|
+
}, onDrop: (e) => __awaiter(void 0, void 0, void 0, function* () {
|
|
132
|
+
var _a, _b, _c;
|
|
133
|
+
const dataRef = tree.getDataRef();
|
|
134
|
+
const target = getDropTarget(e, item, tree);
|
|
135
|
+
if (!canDrop(e.dataTransfer, target, tree)) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
e.preventDefault();
|
|
139
|
+
const config = tree.getConfig();
|
|
140
|
+
const draggedItems = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems;
|
|
141
|
+
dataRef.current.lastDragCode = undefined;
|
|
142
|
+
tree.applySubStateUpdate("dnd", null);
|
|
143
|
+
if (draggedItems) {
|
|
144
|
+
yield ((_b = config.onDrop) === null || _b === void 0 ? void 0 : _b.call(config, draggedItems, target));
|
|
145
|
+
}
|
|
146
|
+
else if (e.dataTransfer) {
|
|
147
|
+
yield ((_c = config.onDropForeignDragObject) === null || _c === void 0 ? void 0 : _c.call(config, e.dataTransfer, target));
|
|
148
|
+
}
|
|
149
|
+
}) })),
|
|
145
150
|
isDropTarget: ({ tree, item }) => {
|
|
146
151
|
const target = tree.getDropTarget();
|
|
147
152
|
return target ? target.item.getId() === item.getId() : false;
|
|
@@ -149,7 +154,7 @@ export const dragAndDropFeature = {
|
|
|
149
154
|
isDropTargetAbove: ({ tree, item }) => {
|
|
150
155
|
const target = tree.getDropTarget();
|
|
151
156
|
if (!target ||
|
|
152
|
-
|
|
157
|
+
!("childIndex" in target) ||
|
|
153
158
|
target.item !== item.getParent())
|
|
154
159
|
return false;
|
|
155
160
|
return target.childIndex === item.getItemMeta().posInSet;
|
|
@@ -157,7 +162,7 @@ export const dragAndDropFeature = {
|
|
|
157
162
|
isDropTargetBelow: ({ tree, item }) => {
|
|
158
163
|
const target = tree.getDropTarget();
|
|
159
164
|
if (!target ||
|
|
160
|
-
|
|
165
|
+
!("childIndex" in target) ||
|
|
161
166
|
target.item !== item.getParent())
|
|
162
167
|
return false;
|
|
163
168
|
return target.childIndex - 1 === item.getItemMeta().posInSet;
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { ItemInstance, SetStateFn } from "../../types/core";
|
|
2
|
-
export
|
|
2
|
+
export interface DndDataRef {
|
|
3
3
|
lastDragCode?: string;
|
|
4
4
|
lastAllowDrop?: boolean;
|
|
5
|
-
}
|
|
6
|
-
export
|
|
5
|
+
}
|
|
6
|
+
export interface DndState<T> {
|
|
7
7
|
draggedItems?: ItemInstance<T>[];
|
|
8
8
|
draggingOverItem?: ItemInstance<T>;
|
|
9
9
|
dragTarget?: DropTarget<T>;
|
|
10
|
-
}
|
|
11
|
-
export
|
|
10
|
+
}
|
|
11
|
+
export interface DragLineData {
|
|
12
12
|
indent: number;
|
|
13
13
|
top: number;
|
|
14
14
|
left: number;
|
|
15
15
|
width: number;
|
|
16
|
-
}
|
|
16
|
+
}
|
|
17
17
|
export type DropTarget<T> = {
|
|
18
18
|
item: ItemInstance<T>;
|
|
19
19
|
childIndex: number;
|
|
@@ -22,10 +22,6 @@ export type DropTarget<T> = {
|
|
|
22
22
|
dragLineLevel: number;
|
|
23
23
|
} | {
|
|
24
24
|
item: ItemInstance<T>;
|
|
25
|
-
childIndex: null;
|
|
26
|
-
insertionIndex: null;
|
|
27
|
-
dragLineIndex: null;
|
|
28
|
-
dragLineLevel: null;
|
|
29
25
|
};
|
|
30
26
|
export declare enum DropTargetPosition {
|
|
31
27
|
Top = "top",
|
|
@@ -43,7 +39,6 @@ export type DragAndDropFeatureDef<T> = {
|
|
|
43
39
|
* If `canReorder` is `false`, this is ignored. */
|
|
44
40
|
reorderAreaPercentage?: number;
|
|
45
41
|
canReorder?: boolean;
|
|
46
|
-
isItemDraggable?: (item: ItemInstance<T>) => boolean;
|
|
47
42
|
canDrag?: (items: ItemInstance<T>[]) => boolean;
|
|
48
43
|
canDrop?: (items: ItemInstance<T>[], target: DropTarget<T>) => boolean;
|
|
49
44
|
indent?: number;
|
|
@@ -52,15 +47,8 @@ export type DragAndDropFeatureDef<T> = {
|
|
|
52
47
|
data: any;
|
|
53
48
|
};
|
|
54
49
|
canDropForeignDragObject?: (dataTransfer: DataTransfer, target: DropTarget<T>) => boolean;
|
|
55
|
-
onDrop?: (items: ItemInstance<T>[], target: DropTarget<T>) => void
|
|
56
|
-
onDropForeignDragObject?: (dataTransfer: DataTransfer, target: DropTarget<T>) => void
|
|
57
|
-
/** Runs in the onDragEnd event, if `ev.dataTransfer.dropEffect` is not `none`, i.e. the drop
|
|
58
|
-
* was not aborted. No target is provided as parameter since the target may be a foreign drop target.
|
|
59
|
-
* This is useful to seperate out the logic to move dragged items out of their previous parents.
|
|
60
|
-
* Use `onDrop` to handle drop-related logic.
|
|
61
|
-
*
|
|
62
|
-
* This ignores the `canDrop` handler, since the drop target is unknown in this handler.
|
|
63
|
-
*/
|
|
50
|
+
onDrop?: (items: ItemInstance<T>[], target: DropTarget<T>) => void | Promise<void>;
|
|
51
|
+
onDropForeignDragObject?: (dataTransfer: DataTransfer, target: DropTarget<T>) => void | Promise<void>;
|
|
64
52
|
onCompleteForeignDrop?: (items: ItemInstance<T>[]) => void;
|
|
65
53
|
};
|
|
66
54
|
treeInstance: {
|
|
@@ -35,13 +35,13 @@ const getItemDropCategory = (item) => {
|
|
|
35
35
|
return ItemDropCategory.ExpandedFolder;
|
|
36
36
|
}
|
|
37
37
|
const parent = item.getParent();
|
|
38
|
-
if (parent && item.getIndexInParent() ===
|
|
38
|
+
if (parent && item.getIndexInParent() === item.getItemMeta().setSize - 1) {
|
|
39
39
|
return ItemDropCategory.LastInGroup;
|
|
40
40
|
}
|
|
41
41
|
return ItemDropCategory.Item;
|
|
42
42
|
};
|
|
43
43
|
const getTargetPlacement = (e, item, tree, canMakeChild) => {
|
|
44
|
-
var _a, _b, _c;
|
|
44
|
+
var _a, _b, _c, _d, _e;
|
|
45
45
|
const config = tree.getConfig();
|
|
46
46
|
if (!config.canReorder) {
|
|
47
47
|
return canMakeChild
|
|
@@ -49,8 +49,8 @@ const getTargetPlacement = (e, item, tree, canMakeChild) => {
|
|
|
49
49
|
: { type: PlacementType.ReorderBelow };
|
|
50
50
|
}
|
|
51
51
|
const bb = (_a = item.getElement()) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
|
|
52
|
-
const topPercent = bb ? (e.
|
|
53
|
-
const leftPixels = bb ? e.
|
|
52
|
+
const topPercent = bb ? (e.clientY - bb.top) / bb.height : 0.5;
|
|
53
|
+
const leftPixels = bb ? e.clientX - bb.left : 0;
|
|
54
54
|
const targetDropCategory = getItemDropCategory(item);
|
|
55
55
|
const reorderAreaPercentage = !canMakeChild
|
|
56
56
|
? 0.5
|
|
@@ -70,9 +70,10 @@ const getTargetPlacement = (e, item, tree, canMakeChild) => {
|
|
|
70
70
|
if (topPercent < 0.5) {
|
|
71
71
|
return { type: PlacementType.ReorderAbove };
|
|
72
72
|
}
|
|
73
|
+
const minLevel = (_e = (_d = item.getItemBelow()) === null || _d === void 0 ? void 0 : _d.getItemMeta().level) !== null && _e !== void 0 ? _e : 0;
|
|
73
74
|
return {
|
|
74
75
|
type: PlacementType.Reparent,
|
|
75
|
-
reparentLevel: Math.floor(leftPixels / indent),
|
|
76
|
+
reparentLevel: Math.max(minLevel, Math.floor(leftPixels / indent)),
|
|
76
77
|
};
|
|
77
78
|
}
|
|
78
79
|
// if not at left of item area, treat as if it was a normal item
|
|
@@ -105,22 +106,8 @@ export const getDropTarget = (e, item, tree, canReorder = tree.getConfig().canRe
|
|
|
105
106
|
const draggedItems = (_b = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems) !== null && _b !== void 0 ? _b : [];
|
|
106
107
|
const itemMeta = item.getItemMeta();
|
|
107
108
|
const parent = item.getParent();
|
|
108
|
-
const itemTarget = {
|
|
109
|
-
|
|
110
|
-
childIndex: null,
|
|
111
|
-
insertionIndex: null,
|
|
112
|
-
dragLineIndex: null,
|
|
113
|
-
dragLineLevel: null,
|
|
114
|
-
};
|
|
115
|
-
const parentTarget = parent
|
|
116
|
-
? {
|
|
117
|
-
item: parent,
|
|
118
|
-
childIndex: null,
|
|
119
|
-
insertionIndex: null,
|
|
120
|
-
dragLineIndex: null,
|
|
121
|
-
dragLineLevel: null,
|
|
122
|
-
}
|
|
123
|
-
: null;
|
|
109
|
+
const itemTarget = { item };
|
|
110
|
+
const parentTarget = parent ? { item: parent } : null;
|
|
124
111
|
const canBecomeSibling = parentTarget && canDrop(e.dataTransfer, parentTarget, tree);
|
|
125
112
|
const canMakeChild = canDrop(e.dataTransfer, itemTarget, tree);
|
|
126
113
|
const placement = getTargetPlacement(e, item, tree, canMakeChild);
|