@headless-tree/core 0.0.0-20230802230636

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/lib/cjs/core/create-tree.d.ts +2 -0
  3. package/lib/cjs/core/create-tree.js +138 -0
  4. package/lib/cjs/features/async-data-loader/feature.d.ts +5 -0
  5. package/lib/cjs/features/async-data-loader/feature.js +88 -0
  6. package/lib/cjs/features/async-data-loader/types.d.ts +41 -0
  7. package/lib/cjs/features/async-data-loader/types.js +2 -0
  8. package/lib/cjs/features/drag-and-drop/feature.d.ts +3 -0
  9. package/lib/cjs/features/drag-and-drop/feature.js +138 -0
  10. package/lib/cjs/features/drag-and-drop/types.d.ts +69 -0
  11. package/lib/cjs/features/drag-and-drop/types.js +9 -0
  12. package/lib/cjs/features/drag-and-drop/utils.d.ts +6 -0
  13. package/lib/cjs/features/drag-and-drop/utils.js +79 -0
  14. package/lib/cjs/features/expand-all/feature.d.ts +6 -0
  15. package/lib/cjs/features/expand-all/feature.js +41 -0
  16. package/lib/cjs/features/expand-all/types.d.ts +17 -0
  17. package/lib/cjs/features/expand-all/types.js +2 -0
  18. package/lib/cjs/features/hotkeys-core/feature.d.ts +4 -0
  19. package/lib/cjs/features/hotkeys-core/feature.js +71 -0
  20. package/lib/cjs/features/hotkeys-core/types.d.ts +25 -0
  21. package/lib/cjs/features/hotkeys-core/types.js +2 -0
  22. package/lib/cjs/features/main/types.d.ts +39 -0
  23. package/lib/cjs/features/main/types.js +2 -0
  24. package/lib/cjs/features/renaming/feature.d.ts +5 -0
  25. package/lib/cjs/features/renaming/feature.js +64 -0
  26. package/lib/cjs/features/renaming/types.d.ts +27 -0
  27. package/lib/cjs/features/renaming/types.js +2 -0
  28. package/lib/cjs/features/search/feature.d.ts +5 -0
  29. package/lib/cjs/features/search/feature.js +103 -0
  30. package/lib/cjs/features/search/types.d.ts +33 -0
  31. package/lib/cjs/features/search/types.js +2 -0
  32. package/lib/cjs/features/selection/feature.d.ts +5 -0
  33. package/lib/cjs/features/selection/feature.js +113 -0
  34. package/lib/cjs/features/selection/types.d.ts +21 -0
  35. package/lib/cjs/features/selection/types.js +2 -0
  36. package/lib/cjs/features/sync-data-loader/feature.d.ts +4 -0
  37. package/lib/cjs/features/sync-data-loader/feature.js +14 -0
  38. package/lib/cjs/features/sync-data-loader/types.d.ts +19 -0
  39. package/lib/cjs/features/sync-data-loader/types.js +2 -0
  40. package/lib/cjs/features/tree/feature.d.ts +6 -0
  41. package/lib/cjs/features/tree/feature.js +230 -0
  42. package/lib/cjs/features/tree/types.d.ts +62 -0
  43. package/lib/cjs/features/tree/types.js +2 -0
  44. package/lib/cjs/index.d.ts +23 -0
  45. package/lib/cjs/index.js +39 -0
  46. package/lib/cjs/mddocs-entry.d.ts +21 -0
  47. package/lib/cjs/mddocs-entry.js +17 -0
  48. package/lib/cjs/types/core.d.ts +67 -0
  49. package/lib/cjs/types/core.js +2 -0
  50. package/lib/cjs/types/deep-merge.d.ts +13 -0
  51. package/lib/cjs/types/deep-merge.js +2 -0
  52. package/lib/cjs/utilities/create-on-drop-handler.d.ts +3 -0
  53. package/lib/cjs/utilities/create-on-drop-handler.js +11 -0
  54. package/lib/cjs/utilities/insert-items-at-target.d.ts +3 -0
  55. package/lib/cjs/utilities/insert-items-at-target.js +24 -0
  56. package/lib/cjs/utilities/remove-items-from-parents.d.ts +2 -0
  57. package/lib/cjs/utilities/remove-items-from-parents.js +17 -0
  58. package/lib/cjs/utils.d.ts +6 -0
  59. package/lib/cjs/utils.js +53 -0
  60. package/lib/esm/core/create-tree.d.ts +2 -0
  61. package/lib/esm/core/create-tree.js +134 -0
  62. package/lib/esm/features/async-data-loader/feature.d.ts +5 -0
  63. package/lib/esm/features/async-data-loader/feature.js +85 -0
  64. package/lib/esm/features/async-data-loader/types.d.ts +41 -0
  65. package/lib/esm/features/async-data-loader/types.js +1 -0
  66. package/lib/esm/features/drag-and-drop/feature.d.ts +3 -0
  67. package/lib/esm/features/drag-and-drop/feature.js +135 -0
  68. package/lib/esm/features/drag-and-drop/types.d.ts +69 -0
  69. package/lib/esm/features/drag-and-drop/types.js +6 -0
  70. package/lib/esm/features/drag-and-drop/utils.d.ts +6 -0
  71. package/lib/esm/features/drag-and-drop/utils.js +72 -0
  72. package/lib/esm/features/expand-all/feature.d.ts +6 -0
  73. package/lib/esm/features/expand-all/feature.js +38 -0
  74. package/lib/esm/features/expand-all/types.d.ts +17 -0
  75. package/lib/esm/features/expand-all/types.js +1 -0
  76. package/lib/esm/features/hotkeys-core/feature.d.ts +4 -0
  77. package/lib/esm/features/hotkeys-core/feature.js +68 -0
  78. package/lib/esm/features/hotkeys-core/types.d.ts +25 -0
  79. package/lib/esm/features/hotkeys-core/types.js +1 -0
  80. package/lib/esm/features/main/types.d.ts +39 -0
  81. package/lib/esm/features/main/types.js +1 -0
  82. package/lib/esm/features/renaming/feature.d.ts +5 -0
  83. package/lib/esm/features/renaming/feature.js +61 -0
  84. package/lib/esm/features/renaming/types.d.ts +27 -0
  85. package/lib/esm/features/renaming/types.js +1 -0
  86. package/lib/esm/features/search/feature.d.ts +5 -0
  87. package/lib/esm/features/search/feature.js +100 -0
  88. package/lib/esm/features/search/types.d.ts +33 -0
  89. package/lib/esm/features/search/types.js +1 -0
  90. package/lib/esm/features/selection/feature.d.ts +5 -0
  91. package/lib/esm/features/selection/feature.js +110 -0
  92. package/lib/esm/features/selection/types.d.ts +21 -0
  93. package/lib/esm/features/selection/types.js +1 -0
  94. package/lib/esm/features/sync-data-loader/feature.d.ts +4 -0
  95. package/lib/esm/features/sync-data-loader/feature.js +11 -0
  96. package/lib/esm/features/sync-data-loader/types.d.ts +19 -0
  97. package/lib/esm/features/sync-data-loader/types.js +1 -0
  98. package/lib/esm/features/tree/feature.d.ts +6 -0
  99. package/lib/esm/features/tree/feature.js +227 -0
  100. package/lib/esm/features/tree/types.d.ts +62 -0
  101. package/lib/esm/features/tree/types.js +1 -0
  102. package/lib/esm/index.d.ts +23 -0
  103. package/lib/esm/index.js +23 -0
  104. package/lib/esm/mddocs-entry.d.ts +21 -0
  105. package/lib/esm/mddocs-entry.js +1 -0
  106. package/lib/esm/types/core.d.ts +67 -0
  107. package/lib/esm/types/core.js +1 -0
  108. package/lib/esm/types/deep-merge.d.ts +13 -0
  109. package/lib/esm/types/deep-merge.js +1 -0
  110. package/lib/esm/utilities/create-on-drop-handler.d.ts +3 -0
  111. package/lib/esm/utilities/create-on-drop-handler.js +7 -0
  112. package/lib/esm/utilities/insert-items-at-target.d.ts +3 -0
  113. package/lib/esm/utilities/insert-items-at-target.js +20 -0
  114. package/lib/esm/utilities/remove-items-from-parents.d.ts +2 -0
  115. package/lib/esm/utilities/remove-items-from-parents.js +13 -0
  116. package/lib/esm/utils.d.ts +6 -0
  117. package/lib/esm/utils.js +46 -0
  118. package/package.json +23 -0
  119. package/src/core/create-tree.ts +228 -0
  120. package/src/features/async-data-loader/feature.ts +126 -0
  121. package/src/features/async-data-loader/types.ts +41 -0
  122. package/src/features/drag-and-drop/feature.ts +214 -0
  123. package/src/features/drag-and-drop/types.ts +89 -0
  124. package/src/features/drag-and-drop/utils.ts +117 -0
  125. package/src/features/expand-all/feature.ts +63 -0
  126. package/src/features/expand-all/types.ts +13 -0
  127. package/src/features/hotkeys-core/feature.ts +110 -0
  128. package/src/features/hotkeys-core/types.ts +36 -0
  129. package/src/features/main/types.ts +48 -0
  130. package/src/features/renaming/feature.ts +105 -0
  131. package/src/features/renaming/types.ts +28 -0
  132. package/src/features/search/feature.ts +158 -0
  133. package/src/features/search/types.ts +40 -0
  134. package/src/features/selection/feature.ts +157 -0
  135. package/src/features/selection/types.ts +28 -0
  136. package/src/features/sync-data-loader/feature.ts +41 -0
  137. package/src/features/sync-data-loader/types.ts +20 -0
  138. package/src/features/tree/feature.ts +326 -0
  139. package/src/features/tree/types.ts +78 -0
  140. package/src/index.ts +26 -0
  141. package/src/mddocs-entry.ts +26 -0
  142. package/src/types/core.ts +183 -0
  143. package/src/types/deep-merge.ts +31 -0
  144. package/src/utilities/create-on-drop-handler.ts +14 -0
  145. package/src/utilities/insert-items-at-target.ts +30 -0
  146. package/src/utilities/remove-items-from-parents.ts +21 -0
  147. package/src/utils.ts +68 -0
  148. package/tsconfig.json +7 -0
  149. package/typedoc.json +4 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,43 @@
1
+ # @headless-tree/core
2
+
3
+ ## 0.0.0-20230802230636
4
+
5
+ ### Patch Changes
6
+
7
+ - 076dfc5: dev release
8
+
9
+ ## 0.0.7
10
+
11
+ ### Patch Changes
12
+
13
+ - 6ec53b3: dev release
14
+
15
+ ## 0.0.6
16
+
17
+ ### Patch Changes
18
+
19
+ - bc9c446: dev release
20
+
21
+ ## 0.0.5
22
+
23
+ ### Patch Changes
24
+
25
+ - 751682a: dev release
26
+
27
+ ## 0.0.4
28
+
29
+ ### Patch Changes
30
+
31
+ - dc6d813: tag pushing
32
+
33
+ ## 0.0.3
34
+
35
+ ### Patch Changes
36
+
37
+ - 6460368: tree shaking
38
+
39
+ ## 0.0.2
40
+
41
+ ### Patch Changes
42
+
43
+ - 05e24de: release test
@@ -0,0 +1,2 @@
1
+ import { TreeConfig, TreeInstance } from "../types/core";
2
+ export declare const createTree: <T>(initialConfig: TreeConfig<T>) => TreeInstance<T>;
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createTree = void 0;
4
+ const feature_1 = require("../features/tree/feature");
5
+ const buildItemInstance = (features, tree, itemId) => {
6
+ var _a, _b;
7
+ const itemInstance = {};
8
+ for (const feature of features) {
9
+ Object.assign(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 : {});
10
+ }
11
+ return itemInstance;
12
+ };
13
+ const verifyFeatures = (features) => {
14
+ var _a;
15
+ const loadedFeatures = features === null || features === void 0 ? void 0 : features.map((feature) => feature.key);
16
+ for (const feature of features !== null && features !== void 0 ? features : []) {
17
+ const missingDependency = (_a = feature.deps) === null || _a === void 0 ? void 0 : _a.find((dep) => !(loadedFeatures === null || loadedFeatures === void 0 ? void 0 : loadedFeatures.includes(dep)));
18
+ if (missingDependency) {
19
+ throw new Error(`${feature.key} needs ${missingDependency}`);
20
+ }
21
+ }
22
+ };
23
+ const compareFeatures = (feature1, feature2) => {
24
+ var _a;
25
+ if (feature2.key && ((_a = feature1.overwrites) === null || _a === void 0 ? void 0 : _a.includes(feature2.key))) {
26
+ return 1;
27
+ }
28
+ return -1;
29
+ };
30
+ const sortFeatures = (features = []) => features.sort(compareFeatures);
31
+ const createTree = (initialConfig) => {
32
+ var _a, _b, _c, _d, _e;
33
+ const treeInstance = {};
34
+ const additionalFeatures = [
35
+ feature_1.treeFeature,
36
+ ...sortFeatures(initialConfig.features),
37
+ ];
38
+ verifyFeatures(additionalFeatures);
39
+ 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; }, (_b = (_a = initialConfig.initialState) !== null && _a !== void 0 ? _a : initialConfig.state) !== null && _b !== void 0 ? _b : {});
40
+ 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);
41
+ const stateHandlerNames = additionalFeatures.reduce((acc, feature) => (Object.assign(Object.assign({}, acc), feature.stateHandlerNames)), {});
42
+ let treeElement;
43
+ const treeDataRef = { current: {} };
44
+ const itemInstancesMap = {};
45
+ let itemInstances = [];
46
+ const itemElementsMap = {};
47
+ const itemDataRefs = {};
48
+ let itemMetaMap = {};
49
+ const hotkeyPresets = {};
50
+ const rebuildItemMeta = (main) => {
51
+ // TODO can we find a way to only run this for the changed substructure?
52
+ itemInstances = [];
53
+ itemMetaMap = {};
54
+ const rootInstance = buildItemInstance([main, ...additionalFeatures], treeInstance, config.rootItemId);
55
+ itemInstancesMap[config.rootItemId] = rootInstance;
56
+ itemMetaMap[config.rootItemId] = {
57
+ itemId: config.rootItemId,
58
+ index: -1,
59
+ parentId: null,
60
+ level: -1,
61
+ posInSet: 0,
62
+ setSize: 1,
63
+ };
64
+ for (const item of treeInstance.getItemsMeta()) {
65
+ itemMetaMap[item.itemId] = item;
66
+ if (!itemInstancesMap[item.itemId]) {
67
+ const instance = buildItemInstance([main, ...additionalFeatures], treeInstance, item.itemId);
68
+ itemInstancesMap[item.itemId] = instance;
69
+ itemInstances.push(instance);
70
+ }
71
+ else {
72
+ itemInstances.push(itemInstancesMap[item.itemId]);
73
+ }
74
+ }
75
+ console.log("REBUILT");
76
+ };
77
+ const eachFeature = (fn) => {
78
+ for (const feature of additionalFeatures) {
79
+ fn(feature);
80
+ }
81
+ };
82
+ const mainFeature = {
83
+ key: "main",
84
+ createTreeInstance: (prev) => (Object.assign(Object.assign({}, prev), { getState: () => state, setState: (updater) => {
85
+ var _a;
86
+ // Not necessary, since I think the subupdate below keeps the state fresh anyways?
87
+ // state = typeof updater === "function" ? updater(state) : updater;
88
+ (_a = config.setState) === null || _a === void 0 ? void 0 : _a.call(config, state);
89
+ }, applySubStateUpdate: (stateName, updater) => {
90
+ state[stateName] =
91
+ typeof updater === "function" ? updater(state[stateName]) : updater;
92
+ config[stateHandlerNames[stateName]](state[stateName]);
93
+ }, rebuildTree: () => {
94
+ var _a;
95
+ rebuildItemMeta(mainFeature);
96
+ (_a = config.setState) === null || _a === void 0 ? void 0 : _a.call(config, state);
97
+ }, getConfig: () => config, setConfig: (updater) => {
98
+ config = typeof updater === "function" ? updater(config) : updater;
99
+ if (config.state) {
100
+ state = Object.assign(Object.assign({}, state), config.state);
101
+ }
102
+ }, getItemInstance: (itemId) => itemInstancesMap[itemId], getItems: () => itemInstances, registerElement: (element) => {
103
+ if (treeElement === element) {
104
+ return;
105
+ }
106
+ if (treeElement && !element) {
107
+ eachFeature((feature) => { var _a; return (_a = feature.onTreeUnmount) === null || _a === void 0 ? void 0 : _a.call(feature, treeInstance, treeElement); });
108
+ }
109
+ else if (!treeElement && element) {
110
+ eachFeature((feature) => { var _a; return (_a = feature.onTreeMount) === null || _a === void 0 ? void 0 : _a.call(feature, treeInstance, element); });
111
+ }
112
+ treeElement = element;
113
+ }, getElement: () => treeElement, getDataRef: () => treeDataRef, getHotkeyPresets: () => hotkeyPresets })),
114
+ createItemInstance: (prev, instance, _, itemId) => (Object.assign(Object.assign({}, prev), { registerElement: (element) => {
115
+ if (itemElementsMap[itemId] === element) {
116
+ return;
117
+ }
118
+ const oldElement = itemElementsMap[itemId];
119
+ if (oldElement && !element) {
120
+ eachFeature((feature) => { var _a; return (_a = feature.onItemUnmount) === null || _a === void 0 ? void 0 : _a.call(feature, instance, oldElement, treeInstance); });
121
+ }
122
+ else if (!oldElement && element) {
123
+ eachFeature((feature) => { var _a; return (_a = feature.onItemMount) === null || _a === void 0 ? void 0 : _a.call(feature, instance, element, treeInstance); });
124
+ }
125
+ itemElementsMap[itemId] = element;
126
+ }, getElement: () => itemElementsMap[itemId],
127
+ // eslint-disable-next-line no-return-assign
128
+ getDataRef: () => { var _a; return ((_a = itemDataRefs[itemId]) !== null && _a !== void 0 ? _a : (itemDataRefs[itemId] = { current: {} })); }, getItemMeta: () => itemMetaMap[itemId] })),
129
+ };
130
+ const features = [mainFeature, ...additionalFeatures];
131
+ for (const feature of features) {
132
+ Object.assign(treeInstance, (_d = (_c = feature.createTreeInstance) === null || _c === void 0 ? void 0 : _c.call(feature, Object.assign({}, treeInstance), treeInstance)) !== null && _d !== void 0 ? _d : {});
133
+ Object.assign(hotkeyPresets, (_e = feature.hotkeys) !== null && _e !== void 0 ? _e : {});
134
+ }
135
+ rebuildItemMeta(mainFeature);
136
+ return treeInstance;
137
+ };
138
+ exports.createTree = createTree;
@@ -0,0 +1,5 @@
1
+ import { FeatureImplementation } from "../../types/core";
2
+ import { AsyncDataLoaderFeatureDef } from "./types";
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>>;
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.asyncDataLoaderFeature = void 0;
4
+ const utils_1 = require("../../utils");
5
+ exports.asyncDataLoaderFeature = {
6
+ key: "async-data-loader",
7
+ getInitialState: (initialState) => (Object.assign({ loadingItems: [] }, initialState)),
8
+ getDefaultConfig: (defaultConfig, tree) => (Object.assign({ setLoadingItems: (0, utils_1.makeStateUpdater)("loadingItems", tree) }, defaultConfig)),
9
+ stateHandlerNames: {
10
+ loadingItems: "setLoadingItems",
11
+ },
12
+ createTreeInstance: (prev, instance) => (Object.assign(Object.assign({}, prev), { retrieveItemData: (itemId) => {
13
+ var _a, _b, _c, _d, _e;
14
+ var _f, _g;
15
+ const config = instance.getConfig();
16
+ const dataRef = instance.getDataRef();
17
+ (_a = (_f = dataRef.current).itemData) !== null && _a !== void 0 ? _a : (_f.itemData = {});
18
+ (_b = (_g = dataRef.current).childrenIds) !== null && _b !== void 0 ? _b : (_g.childrenIds = {});
19
+ if (dataRef.current.itemData[itemId]) {
20
+ return dataRef.current.itemData[itemId];
21
+ }
22
+ if (!instance.getState().loadingItems.includes(itemId)) {
23
+ instance.applySubStateUpdate("loadingItems", (loadingItems) => [
24
+ ...loadingItems,
25
+ itemId,
26
+ ]);
27
+ (_c = config.asyncDataLoader) === null || _c === void 0 ? void 0 : _c.getItem(itemId).then((item) => {
28
+ var _a;
29
+ dataRef.current.itemData[itemId] = item;
30
+ (_a = config.onLoadedItem) === null || _a === void 0 ? void 0 : _a.call(config, itemId, item);
31
+ instance.applySubStateUpdate("loadingItems", (loadingItems) => loadingItems.filter((id) => id !== itemId));
32
+ });
33
+ }
34
+ return (_e = (_d = config.createLoadingItemData) === null || _d === void 0 ? void 0 : _d.call(config)) !== null && _e !== void 0 ? _e : null;
35
+ }, retrieveChildrenIds: (itemId) => {
36
+ var _a, _b, _c, _d, _e;
37
+ var _f, _g;
38
+ const config = instance.getConfig();
39
+ const dataRef = instance.getDataRef();
40
+ (_a = (_f = dataRef.current).itemData) !== null && _a !== void 0 ? _a : (_f.itemData = {});
41
+ (_b = (_g = dataRef.current).childrenIds) !== null && _b !== void 0 ? _b : (_g.childrenIds = {});
42
+ if (dataRef.current.childrenIds[itemId]) {
43
+ return dataRef.current.childrenIds[itemId];
44
+ }
45
+ if (instance.getState().loadingItems.includes(itemId)) {
46
+ return [];
47
+ }
48
+ instance.applySubStateUpdate("loadingItems", (loadingItems) => [
49
+ ...loadingItems,
50
+ itemId,
51
+ ]);
52
+ if ((_c = config.asyncDataLoader) === null || _c === void 0 ? void 0 : _c.getChildrenWithData) {
53
+ (_d = config.asyncDataLoader) === null || _d === void 0 ? void 0 : _d.getChildrenWithData(itemId).then((children) => {
54
+ var _a, _b;
55
+ for (const { id, data } of children) {
56
+ dataRef.current.itemData[id] = data;
57
+ (_a = config.onLoadedItem) === null || _a === void 0 ? void 0 : _a.call(config, id, data);
58
+ }
59
+ const childrenIds = children.map(({ id }) => id);
60
+ dataRef.current.childrenIds[itemId] = childrenIds;
61
+ (_b = config.onLoadedChildren) === null || _b === void 0 ? void 0 : _b.call(config, itemId, childrenIds);
62
+ instance.applySubStateUpdate("loadingItems", (loadingItems) => loadingItems.filter((id) => id !== itemId));
63
+ instance.rebuildTree();
64
+ });
65
+ }
66
+ else {
67
+ (_e = config.asyncDataLoader) === null || _e === void 0 ? void 0 : _e.getChildren(itemId).then((childrenIds) => {
68
+ var _a;
69
+ dataRef.current.childrenIds[itemId] = childrenIds;
70
+ (_a = config.onLoadedChildren) === null || _a === void 0 ? void 0 : _a.call(config, itemId, childrenIds);
71
+ instance.applySubStateUpdate("loadingItems", (loadingItems) => loadingItems.filter((id) => id !== itemId));
72
+ instance.rebuildTree();
73
+ });
74
+ }
75
+ return [];
76
+ }, invalidateItemData: (itemId) => {
77
+ var _a;
78
+ const dataRef = instance.getDataRef();
79
+ (_a = dataRef.current.itemData) === null || _a === void 0 ? true : delete _a[itemId];
80
+ instance.retrieveItemData(itemId);
81
+ }, invalidateChildrenIds: (itemId) => {
82
+ var _a;
83
+ const dataRef = instance.getDataRef();
84
+ (_a = dataRef.current.childrenIds) === null || _a === void 0 ? true : delete _a[itemId];
85
+ instance.retrieveChildrenIds(itemId);
86
+ } })),
87
+ createItemInstance: (prev, item, tree) => (Object.assign(Object.assign({}, prev), { isLoading: () => tree.getState().loadingItems.includes(item.getItemMeta().itemId), invalidateItemData: () => tree.invalidateItemData(item.getItemMeta().itemId), invalidateChildrenIds: () => tree.invalidateChildrenIds(item.getItemMeta().itemId) })),
88
+ };
@@ -0,0 +1,41 @@
1
+ import { SetStateFn } from "../../types/core";
2
+ import { SyncDataLoaderFeatureDef } from "../sync-data-loader/types";
3
+ export type AsyncTreeDataLoader<T> = {
4
+ getItem: (itemId: string) => Promise<T>;
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> = {
12
+ itemData: Record<string, T>;
13
+ childrenIds: Record<string, string[]>;
14
+ };
15
+ /**
16
+ * @category Async Data Loader/General
17
+ * */
18
+ export type AsyncDataLoaderFeatureDef<T> = {
19
+ state: {
20
+ loadingItems: string[];
21
+ };
22
+ config: {
23
+ rootItemId: string;
24
+ createLoadingItemData?: () => T;
25
+ setLoadingItems?: SetStateFn<string[]>;
26
+ onLoadedItem?: (itemId: string, item: T) => void;
27
+ onLoadedChildren?: (itemId: string, childrenIds: string[]) => void;
28
+ asyncDataLoader?: AsyncTreeDataLoader<T>;
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
+ };
35
+ itemInstance: SyncDataLoaderFeatureDef<T>["itemInstance"] & {
36
+ invalidateItemData: () => void;
37
+ invalidateChildrenIds: () => void;
38
+ isLoading: () => void;
39
+ };
40
+ hotkeys: SyncDataLoaderFeatureDef<T>["hotkeys"];
41
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,3 @@
1
+ import { FeatureDefs, FeatureImplementation } from "../../types/core";
2
+ import { DragAndDropFeatureDef } from "./types";
3
+ export declare const dragAndDropFeature: FeatureImplementation<any, DragAndDropFeatureDef<any>, FeatureDefs<any>>;
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dragAndDropFeature = void 0;
4
+ const utils_1 = require("./utils");
5
+ const utils_2 = require("../../utils");
6
+ exports.dragAndDropFeature = {
7
+ key: "dragAndDrop",
8
+ deps: ["selection"],
9
+ getDefaultConfig: (defaultConfig, tree) => (Object.assign({ canDrop: (_, target) => target.item.isFolder(), canDropForeignDragObject: () => false, setDndState: (0, utils_2.makeStateUpdater)("dnd", tree) }, defaultConfig)),
10
+ stateHandlerNames: {
11
+ dnd: "setDndState",
12
+ },
13
+ createTreeInstance: (prev, tree) => (Object.assign(Object.assign({}, prev), { getDropTarget: () => {
14
+ var _a, _b;
15
+ return (_b = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.dragTarget) !== null && _b !== void 0 ? _b : null;
16
+ }, getDragLineData: () => {
17
+ var _a, _b, _c, _d, _e;
18
+ const target = tree.getDropTarget();
19
+ const intend = ((_a = target === null || target === void 0 ? void 0 : target.item.getItemMeta().level) !== null && _a !== void 0 ? _a : 0) + 1;
20
+ if (!target || target.childIndex === null)
21
+ return null;
22
+ const children = target.item.getChildren();
23
+ if (target.childIndex === children.length) {
24
+ const bb = (_c = (_b = children[target.childIndex - 1]) === null || _b === void 0 ? void 0 : _b.getElement()) === null || _c === void 0 ? void 0 : _c.getBoundingClientRect();
25
+ if (bb) {
26
+ return {
27
+ intend,
28
+ top: bb.bottom,
29
+ left: bb.left,
30
+ right: bb.right,
31
+ };
32
+ }
33
+ }
34
+ const bb = (_e = (_d = children[target.childIndex]) === null || _d === void 0 ? void 0 : _d.getElement()) === null || _e === void 0 ? void 0 : _e.getBoundingClientRect();
35
+ if (bb) {
36
+ return {
37
+ intend,
38
+ top: bb.top,
39
+ left: bb.left,
40
+ right: bb.right,
41
+ };
42
+ }
43
+ return null;
44
+ } })),
45
+ createItemInstance: (prev, item, tree) => (Object.assign(Object.assign({}, prev), { getProps: () => {
46
+ var _a, _b, _c;
47
+ return (Object.assign(Object.assign({}, prev.getProps()), { draggable: (_c = (_b = (_a = tree.getConfig()).isItemDraggable) === null || _b === void 0 ? void 0 : _b.call(_a, item)) !== null && _c !== void 0 ? _c : true, onDragStart: item.getMemoizedProp("dnd/onDragStart", () => (e) => {
48
+ var _a, _b, _c;
49
+ const selectedItems = tree.getSelectedItems();
50
+ const items = selectedItems.includes(item) ? selectedItems : [item];
51
+ const config = tree.getConfig();
52
+ if (!selectedItems.includes(item)) {
53
+ tree.setSelectedItems([item.getItemMeta().itemId]);
54
+ }
55
+ if (!((_b = (_a = config.canDrag) === null || _a === void 0 ? void 0 : _a.call(config, items)) !== null && _b !== void 0 ? _b : true)) {
56
+ e.preventDefault();
57
+ return;
58
+ }
59
+ if (config.createForeignDragObject) {
60
+ const { format, data } = config.createForeignDragObject(items);
61
+ (_c = e.dataTransfer) === null || _c === void 0 ? void 0 : _c.setData(format, data);
62
+ }
63
+ tree.applySubStateUpdate("dnd", {
64
+ draggedItems: items,
65
+ draggingOverItem: tree.getFocusedItem(),
66
+ });
67
+ }), onDragOver: item.getMemoizedProp("dnd/onDragOver", () => (e) => {
68
+ var _a, _b, _c;
69
+ const target = (0, utils_1.getDropTarget)(e, item, tree);
70
+ const dataRef = tree.getDataRef();
71
+ if (!((_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems) &&
72
+ !((_c = (_b = tree.getConfig()).canDropForeignDragObject) === null || _c === void 0 ? void 0 : _c.call(_b, e.dataTransfer, target))) {
73
+ return;
74
+ }
75
+ if (!(0, utils_1.canDrop)(e.dataTransfer, target, tree)) {
76
+ return;
77
+ }
78
+ e.preventDefault();
79
+ const nextDragCode = (0, utils_1.getDragCode)(target);
80
+ if (nextDragCode === dataRef.current.lastDragCode) {
81
+ return;
82
+ }
83
+ dataRef.current.lastDragCode = nextDragCode;
84
+ tree.applySubStateUpdate("dnd", (state) => (Object.assign(Object.assign({}, state), { dragTarget: target, draggingOverItem: item })));
85
+ }), onDragLeave: item.getMemoizedProp("dnd/onDragLeave", () => () => {
86
+ const dataRef = tree.getDataRef();
87
+ dataRef.current.lastDragCode = "no-drag";
88
+ tree.applySubStateUpdate("dnd", (state) => (Object.assign(Object.assign({}, state), { draggingOverItem: undefined, dragTarget: undefined })));
89
+ }), onDragEnd: item.getMemoizedProp("dnd/onDragEnd", () => (e) => {
90
+ var _a, _b, _c;
91
+ const draggedItems = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems;
92
+ tree.applySubStateUpdate("dnd", null);
93
+ if (e.dataTransfer.dropEffect === "none" || !draggedItems) {
94
+ return;
95
+ }
96
+ (_c = (_b = tree.getConfig()).onCompleteForeignDrop) === null || _c === void 0 ? void 0 : _c.call(_b, draggedItems);
97
+ }), onDrop: item.getMemoizedProp("dnd/onDrop", () => (e) => {
98
+ var _a, _b, _c;
99
+ const dataRef = tree.getDataRef();
100
+ const target = (0, utils_1.getDropTarget)(e, item, tree);
101
+ if (!(0, utils_1.canDrop)(e.dataTransfer, target, tree)) {
102
+ return;
103
+ }
104
+ e.preventDefault();
105
+ const config = tree.getConfig();
106
+ const draggedItems = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems;
107
+ dataRef.current.lastDragCode = undefined;
108
+ tree.applySubStateUpdate("dnd", null);
109
+ if (draggedItems) {
110
+ (_b = config.onDrop) === null || _b === void 0 ? void 0 : _b.call(config, draggedItems, target);
111
+ }
112
+ else {
113
+ (_c = config.onDropForeignDragObject) === null || _c === void 0 ? void 0 : _c.call(config, e.dataTransfer, target);
114
+ }
115
+ // TODO rebuild tree?
116
+ }) }));
117
+ }, isDropTarget: () => {
118
+ const target = tree.getDropTarget();
119
+ return target ? target.item.getId() === item.getId() : false;
120
+ }, isDropTargetAbove: () => {
121
+ const target = tree.getDropTarget();
122
+ if (!target ||
123
+ target.childIndex === null ||
124
+ target.item !== item.getParent())
125
+ return false;
126
+ return target.childIndex === item.getItemMeta().posInSet;
127
+ }, isDropTargetBelow: () => {
128
+ const target = tree.getDropTarget();
129
+ if (!target ||
130
+ target.childIndex === null ||
131
+ target.item !== item.getParent())
132
+ return false;
133
+ return target.childIndex - 1 === item.getItemMeta().posInSet;
134
+ }, isDraggingOver: () => {
135
+ var _a, _b;
136
+ 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
+ } })),
138
+ };
@@ -0,0 +1,69 @@
1
+ import { ItemInstance, SetStateFn } from "../../types/core";
2
+ export type DndDataRef = {
3
+ lastDragCode?: string;
4
+ };
5
+ export type DndState<T> = {
6
+ draggedItems?: ItemInstance<T>[];
7
+ draggingOverItem?: ItemInstance<T>;
8
+ dragTarget?: DropTarget<T>;
9
+ };
10
+ export type DragLineData = {
11
+ intend: number;
12
+ top: number;
13
+ left: number;
14
+ right: number;
15
+ };
16
+ export type DropTarget<T> = {
17
+ item: ItemInstance<T>;
18
+ childIndex: number;
19
+ insertionIndex: number;
20
+ } | {
21
+ item: ItemInstance<T>;
22
+ childIndex: null;
23
+ insertionIndex: null;
24
+ };
25
+ export declare enum DropTargetPosition {
26
+ Top = "top",
27
+ Bottom = "bottom",
28
+ Item = "item"
29
+ }
30
+ export type DragAndDropFeatureDef<T> = {
31
+ state: {
32
+ dnd?: DndState<T> | null;
33
+ };
34
+ config: {
35
+ setDndState?: SetStateFn<DndState<T> | null>;
36
+ topLinePercentage?: number;
37
+ bottomLinePercentage?: number;
38
+ canDropInbetween?: boolean;
39
+ isItemDraggable?: (item: ItemInstance<T>) => boolean;
40
+ canDrag?: (items: ItemInstance<T>[]) => boolean;
41
+ canDrop?: (items: ItemInstance<T>[], target: DropTarget<T>) => boolean;
42
+ createForeignDragObject?: (items: ItemInstance<T>[]) => {
43
+ format: string;
44
+ data: any;
45
+ };
46
+ canDropForeignDragObject?: (dataTransfer: DataTransfer, target: DropTarget<T>) => boolean;
47
+ onDrop?: (items: ItemInstance<T>[], target: DropTarget<T>) => void;
48
+ onDropForeignDragObject?: (dataTransfer: DataTransfer, target: DropTarget<T>) => void;
49
+ /** Runs in the onDragEnd event, if `ev.dataTransfer.dropEffect` is not `none`, i.e. the drop
50
+ * was not aborted. No target is provided as parameter since the target may be a foreign drop target.
51
+ * This is useful to seperate out the logic to move dragged items out of their previous parents.
52
+ * Use `onDrop` to handle drop-related logic.
53
+ *
54
+ * This ignores the `canDrop` handler, since the drop target is unknown in this handler.
55
+ */
56
+ onCompleteForeignDrop?: (items: ItemInstance<T>[]) => void;
57
+ };
58
+ treeInstance: {
59
+ getDropTarget: () => DropTarget<T> | null;
60
+ getDragLineData: () => DragLineData | null;
61
+ };
62
+ itemInstance: {
63
+ isDropTarget: () => boolean;
64
+ isDropTargetAbove: () => boolean;
65
+ isDropTargetBelow: () => boolean;
66
+ isDraggingOver: () => boolean;
67
+ };
68
+ hotkeys: never;
69
+ };
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DropTargetPosition = void 0;
4
+ var DropTargetPosition;
5
+ (function (DropTargetPosition) {
6
+ DropTargetPosition["Top"] = "top";
7
+ DropTargetPosition["Bottom"] = "bottom";
8
+ DropTargetPosition["Item"] = "item";
9
+ })(DropTargetPosition = exports.DropTargetPosition || (exports.DropTargetPosition = {}));
@@ -0,0 +1,6 @@
1
+ import { ItemInstance, TreeInstance } from "../../types/core";
2
+ import { DropTarget } from "./types";
3
+ export declare const getDragCode: ({ item, childIndex }: DropTarget<any>) => string;
4
+ export declare const getDropOffset: (e: any, item: ItemInstance<any>) => number;
5
+ export declare const canDrop: (dataTransfer: DataTransfer | null, target: DropTarget<any>, tree: TreeInstance<any>) => boolean;
6
+ export declare const getDropTarget: (e: any, item: ItemInstance<any>, tree: TreeInstance<any>, canDropInbetween?: boolean | undefined) => DropTarget<any>;
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getDropTarget = exports.canDrop = exports.getDropOffset = exports.getDragCode = void 0;
4
+ const types_1 = require("./types");
5
+ const getDragCode = ({ item, childIndex }) => `${item.getId()}__${childIndex !== null && childIndex !== void 0 ? childIndex : "none"}`;
6
+ exports.getDragCode = getDragCode;
7
+ const getDropOffset = (e, item) => {
8
+ var _a;
9
+ const bb = (_a = item.getElement()) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
10
+ return bb ? (e.pageY - bb.top) / bb.height : 0.5;
11
+ };
12
+ exports.getDropOffset = getDropOffset;
13
+ const canDrop = (dataTransfer, target, tree) => {
14
+ var _a, _b, _c, _d;
15
+ const draggedItems = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems;
16
+ const config = tree.getConfig();
17
+ if (draggedItems && !((_c = (_b = config.canDrop) === null || _b === void 0 ? void 0 : _b.call(config, draggedItems, target)) !== null && _c !== void 0 ? _c : true)) {
18
+ return false;
19
+ }
20
+ if (!draggedItems &&
21
+ dataTransfer &&
22
+ !((_d = config.canDropForeignDragObject) === null || _d === void 0 ? void 0 : _d.call(config, dataTransfer, target))) {
23
+ return false;
24
+ }
25
+ return true;
26
+ };
27
+ exports.canDrop = canDrop;
28
+ const getDropTargetPosition = (offset, topLinePercentage, bottomLinePercentage) => {
29
+ if (offset < topLinePercentage) {
30
+ return types_1.DropTargetPosition.Top;
31
+ }
32
+ if (offset > bottomLinePercentage) {
33
+ return types_1.DropTargetPosition.Bottom;
34
+ }
35
+ return types_1.DropTargetPosition.Item;
36
+ };
37
+ const getDropTarget = (e, item, tree, canDropInbetween = tree.getConfig().canDropInbetween) => {
38
+ var _a, _b, _c, _d;
39
+ const config = tree.getConfig();
40
+ const draggedItems = (_b = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems) !== null && _b !== void 0 ? _b : [];
41
+ const itemTarget = { item, childIndex: null, insertionIndex: null };
42
+ const parentTarget = {
43
+ item: item.getParent(),
44
+ childIndex: null,
45
+ insertionIndex: null,
46
+ };
47
+ if (!canDropInbetween) {
48
+ if (!(0, exports.canDrop)(e.dataTransfer, parentTarget, tree)) {
49
+ return (0, exports.getDropTarget)(e, item.getParent(), tree, false);
50
+ }
51
+ return itemTarget;
52
+ }
53
+ const canDropInside = (0, exports.canDrop)(e.dataTransfer, itemTarget, tree);
54
+ const offset = (0, exports.getDropOffset)(e, item);
55
+ const pos = canDropInside
56
+ ? getDropTargetPosition(offset, (_c = config.topLinePercentage) !== null && _c !== void 0 ? _c : 0.3, (_d = config.bottomLinePercentage) !== null && _d !== void 0 ? _d : 0.7)
57
+ : getDropTargetPosition(offset, 0.5, 0.5);
58
+ if (pos === types_1.DropTargetPosition.Item) {
59
+ return itemTarget;
60
+ }
61
+ if (!(0, exports.canDrop)(e.dataTransfer, parentTarget, tree)) {
62
+ return (0, exports.getDropTarget)(e, item.getParent(), tree, false);
63
+ }
64
+ const childIndex = item.getIndexInParent() + (pos === types_1.DropTargetPosition.Top ? 0 : 1);
65
+ const numberOfDragItemsBeforeTarget = item
66
+ .getParent()
67
+ .getChildren()
68
+ .slice(0, childIndex)
69
+ .reduce((counter, child) => child && (draggedItems === null || draggedItems === void 0 ? void 0 : draggedItems.some((i) => i.getId() === child.getId()))
70
+ ? ++counter
71
+ : counter, 0);
72
+ return {
73
+ item: item.getParent(),
74
+ childIndex,
75
+ // TODO performance could be improved by computing this only when dragcode changed
76
+ insertionIndex: childIndex - numberOfDragItemsBeforeTarget,
77
+ };
78
+ };
79
+ exports.getDropTarget = getDropTarget;
@@ -0,0 +1,6 @@
1
+ import { FeatureImplementation } from "../../types/core";
2
+ import { ExpandAllFeatureDef } from "./types";
3
+ import { MainFeatureDef } from "../main/types";
4
+ import { TreeFeatureDef } from "../tree/types";
5
+ import { SyncDataLoaderFeatureDef } from "../sync-data-loader/types";
6
+ export declare const expandAllFeature: FeatureImplementation<any, ExpandAllFeatureDef, MainFeatureDef | TreeFeatureDef<any> | SyncDataLoaderFeatureDef<any> | ExpandAllFeatureDef>;