@headless-tree/core 0.0.0-20250509212452 → 0.0.0-20250511190858

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 (35) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/lib/cjs/core/create-tree.js +0 -9
  3. package/lib/cjs/features/async-data-loader/feature.js +9 -43
  4. package/lib/cjs/features/async-data-loader/types.d.ts +0 -4
  5. package/lib/cjs/features/main/types.d.ts +0 -2
  6. package/lib/cjs/features/sync-data-loader/types.d.ts +2 -2
  7. package/lib/cjs/index.d.ts +0 -2
  8. package/lib/cjs/index.js +0 -2
  9. package/lib/cjs/types/core.d.ts +1 -2
  10. package/lib/esm/core/create-tree.js +0 -9
  11. package/lib/esm/features/async-data-loader/feature.js +9 -43
  12. package/lib/esm/features/async-data-loader/types.d.ts +0 -4
  13. package/lib/esm/features/main/types.d.ts +0 -2
  14. package/lib/esm/features/sync-data-loader/types.d.ts +2 -2
  15. package/lib/esm/index.d.ts +0 -2
  16. package/lib/esm/index.js +0 -2
  17. package/lib/esm/types/core.d.ts +1 -2
  18. package/package.json +1 -1
  19. package/src/core/create-tree.ts +0 -13
  20. package/src/features/async-data-loader/feature.ts +7 -37
  21. package/src/features/async-data-loader/types.ts +0 -4
  22. package/src/features/main/types.ts +0 -2
  23. package/src/features/sync-data-loader/types.ts +2 -2
  24. package/src/index.ts +0 -2
  25. package/src/types/core.ts +0 -2
  26. package/lib/cjs/features/checkboxes/feature.d.ts +0 -2
  27. package/lib/cjs/features/checkboxes/feature.js +0 -128
  28. package/lib/cjs/features/checkboxes/types.d.ts +0 -26
  29. package/lib/cjs/features/checkboxes/types.js +0 -9
  30. package/lib/esm/features/checkboxes/feature.d.ts +0 -2
  31. package/lib/esm/features/checkboxes/feature.js +0 -125
  32. package/lib/esm/features/checkboxes/types.d.ts +0 -26
  33. package/lib/esm/features/checkboxes/types.js +0 -6
  34. package/src/features/checkboxes/feature.ts +0 -150
  35. package/src/features/checkboxes/types.ts +0 -28
package/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @headless-tree/core
2
2
 
3
- ## 0.0.0-20250509212452
3
+ ## 0.0.0-20250511190858
4
4
 
5
5
  ### Minor Changes
6
6
 
@@ -100,15 +100,6 @@ const createTree = (initialConfig) => {
100
100
  const externalStateSetter = config[stateHandlerNames[stateName]];
101
101
  externalStateSetter === null || externalStateSetter === void 0 ? void 0 : externalStateSetter(state[stateName]);
102
102
  },
103
- buildItemInstance: ({}, itemId) => {
104
- const [instance, finalizeInstance] = buildInstance(features, "itemInstance", (instance) => ({
105
- item: instance,
106
- tree: treeInstance,
107
- itemId,
108
- }));
109
- finalizeInstance();
110
- return instance;
111
- },
112
103
  // TODO rebuildSubTree: (itemId: string) => void;
113
104
  rebuildTree: () => {
114
105
  var _a;
@@ -20,33 +20,28 @@ const getDataRef = (tree) => {
20
20
  return dataRef;
21
21
  };
22
22
  const loadItemData = (tree, itemId) => __awaiter(void 0, void 0, void 0, function* () {
23
- var _a, _b, _c;
23
+ var _a;
24
24
  const config = tree.getConfig();
25
25
  const dataRef = getDataRef(tree);
26
26
  const item = yield config.dataLoader.getItem(itemId);
27
27
  dataRef.current.itemData[itemId] = item;
28
28
  (_a = config.onLoadedItem) === null || _a === void 0 ? void 0 : _a.call(config, itemId, item);
29
29
  tree.applySubStateUpdate("loadingItemData", (loadingItemData) => loadingItemData.filter((id) => id !== itemId));
30
- (_b = dataRef.current.awaitingItemDataLoading) === null || _b === void 0 ? void 0 : _b[itemId].forEach((cb) => cb());
31
- (_c = dataRef.current.awaitingItemDataLoading) === null || _c === void 0 ? true : delete _c[itemId];
32
30
  return item;
33
31
  });
34
32
  const loadChildrenIds = (tree, itemId) => __awaiter(void 0, void 0, void 0, function* () {
35
- var _a, _b, _c, _d, _e;
33
+ var _a, _b;
36
34
  const config = tree.getConfig();
37
35
  const dataRef = getDataRef(tree);
38
36
  let childrenIds;
39
- // TODO is folder check?
40
37
  if ("getChildrenWithData" in config.dataLoader) {
41
38
  const children = yield config.dataLoader.getChildrenWithData(itemId);
42
39
  childrenIds = children.map((c) => c.id);
43
40
  dataRef.current.childrenIds[itemId] = childrenIds;
44
41
  children.forEach(({ id, data }) => {
45
- var _a, _b, _c;
42
+ var _a;
46
43
  dataRef.current.itemData[id] = data;
47
44
  (_a = config.onLoadedItem) === null || _a === void 0 ? void 0 : _a.call(config, id, data);
48
- (_b = dataRef.current.awaitingItemDataLoading) === null || _b === void 0 ? void 0 : _b[id].forEach((cb) => cb());
49
- (_c = dataRef.current.awaitingItemDataLoading) === null || _c === void 0 ? true : delete _c[id];
50
45
  });
51
46
  (_a = config.onLoadedChildren) === null || _a === void 0 ? void 0 : _a.call(config, itemId, childrenIds);
52
47
  tree.rebuildTree();
@@ -59,8 +54,6 @@ const loadChildrenIds = (tree, itemId) => __awaiter(void 0, void 0, void 0, func
59
54
  tree.rebuildTree();
60
55
  }
61
56
  tree.applySubStateUpdate("loadingItemChildrens", (loadingItemChildrens) => loadingItemChildrens.filter((id) => id !== itemId));
62
- (_d = (_c = dataRef.current.awaitingItemChildrensLoading) === null || _c === void 0 ? void 0 : _c[itemId]) === null || _d === void 0 ? void 0 : _d.forEach((cb) => cb());
63
- (_e = dataRef.current.awaitingItemChildrensLoading) === null || _e === void 0 ? true : delete _e[itemId];
64
57
  return childrenIds;
65
58
  });
66
59
  exports.asyncDataLoaderFeature = {
@@ -72,35 +65,8 @@ exports.asyncDataLoaderFeature = {
72
65
  loadingItemChildrens: "setLoadingItemChildrens",
73
66
  },
74
67
  treeInstance: {
75
- waitForItemDataLoaded: (_a, itemId_1) => __awaiter(void 0, [_a, itemId_1], void 0, function* ({ tree }, itemId) {
76
- tree.retrieveItemData(itemId);
77
- if (!tree.getState().loadingItemData.includes(itemId)) {
78
- return;
79
- }
80
- yield new Promise((resolve) => {
81
- var _a, _b;
82
- var _c, _d;
83
- const dataRef = tree.getDataRef();
84
- (_a = (_c = dataRef.current).awaitingItemDataLoading) !== null && _a !== void 0 ? _a : (_c.awaitingItemDataLoading = {});
85
- (_b = (_d = dataRef.current.awaitingItemDataLoading)[itemId]) !== null && _b !== void 0 ? _b : (_d[itemId] = []);
86
- dataRef.current.awaitingItemDataLoading[itemId].push(resolve);
87
- });
88
- }),
89
- waitForItemChildrenLoaded: (_a, itemId_1) => __awaiter(void 0, [_a, itemId_1], void 0, function* ({ tree }, itemId) {
90
- // TODO replace inner implementation with load() fns
91
- tree.retrieveChildrenIds(itemId);
92
- if (!tree.getState().loadingItemChildrens.includes(itemId)) {
93
- return;
94
- }
95
- yield new Promise((resolve) => {
96
- var _a, _b;
97
- var _c, _d;
98
- const dataRef = tree.getDataRef();
99
- (_a = (_c = dataRef.current).awaitingItemChildrensLoading) !== null && _a !== void 0 ? _a : (_c.awaitingItemChildrensLoading = {});
100
- (_b = (_d = dataRef.current.awaitingItemChildrensLoading)[itemId]) !== null && _b !== void 0 ? _b : (_d[itemId] = []);
101
- dataRef.current.awaitingItemChildrensLoading[itemId].push(resolve);
102
- });
103
- }),
68
+ waitForItemDataLoaded: ({ tree }, itemId) => tree.loadItemData(itemId),
69
+ waitForItemChildrenLoaded: ({ tree }, itemId) => tree.loadChildrenIds(itemId),
104
70
  loadItemData: (_a, itemId_1) => __awaiter(void 0, [_a, itemId_1], void 0, function* ({ tree }, itemId) {
105
71
  var _b;
106
72
  return ((_b = getDataRef(tree).current.itemData[itemId]) !== null && _b !== void 0 ? _b : (yield loadItemData(tree, itemId)));
@@ -109,14 +75,14 @@ exports.asyncDataLoaderFeature = {
109
75
  var _b;
110
76
  return ((_b = getDataRef(tree).current.childrenIds[itemId]) !== null && _b !== void 0 ? _b : (yield loadChildrenIds(tree, itemId)));
111
77
  }),
112
- retrieveItemData: ({ tree }, itemId, skipFetch = false) => {
78
+ retrieveItemData: ({ tree }, itemId) => {
113
79
  var _a, _b;
114
80
  const config = tree.getConfig();
115
81
  const dataRef = getDataRef(tree);
116
82
  if (dataRef.current.itemData[itemId]) {
117
83
  return dataRef.current.itemData[itemId];
118
84
  }
119
- if (!tree.getState().loadingItemData.includes(itemId) && !skipFetch) {
85
+ if (!tree.getState().loadingItemData.includes(itemId)) {
120
86
  tree.applySubStateUpdate("loadingItemData", (loadingItemData) => [
121
87
  ...loadingItemData,
122
88
  itemId,
@@ -125,12 +91,12 @@ exports.asyncDataLoaderFeature = {
125
91
  }
126
92
  return (_b = (_a = config.createLoadingItemData) === null || _a === void 0 ? void 0 : _a.call(config)) !== null && _b !== void 0 ? _b : null;
127
93
  },
128
- retrieveChildrenIds: ({ tree }, itemId, skipFetch = false) => {
94
+ retrieveChildrenIds: ({ tree }, itemId) => {
129
95
  const dataRef = getDataRef(tree);
130
96
  if (dataRef.current.childrenIds[itemId]) {
131
97
  return dataRef.current.childrenIds[itemId];
132
98
  }
133
- if (tree.getState().loadingItemChildrens.includes(itemId) || skipFetch) {
99
+ if (tree.getState().loadingItemChildrens.includes(itemId)) {
134
100
  return [];
135
101
  }
136
102
  tree.applySubStateUpdate("loadingItemChildrens", (loadingItemChildrens) => [...loadingItemChildrens, itemId]);
@@ -1,11 +1,8 @@
1
1
  import { SetStateFn } from "../../types/core";
2
2
  import { SyncDataLoaderFeatureDef } from "../sync-data-loader/types";
3
- type AwaitingLoaderCallbacks = Record<string, (() => void)[]>;
4
3
  export interface AsyncDataLoaderDataRef<T = any> {
5
4
  itemData: Record<string, T>;
6
5
  childrenIds: Record<string, string[]>;
7
- awaitingItemDataLoading: AwaitingLoaderCallbacks;
8
- awaitingItemChildrensLoading: AwaitingLoaderCallbacks;
9
6
  }
10
7
  /**
11
8
  * @category Async Data Loader/General
@@ -48,4 +45,3 @@ export type AsyncDataLoaderFeatureDef<T> = {
48
45
  };
49
46
  hotkeys: SyncDataLoaderFeatureDef<T>["hotkeys"];
50
47
  };
51
- export {};
@@ -17,8 +17,6 @@ export type MainFeatureDef<T = any> = {
17
17
  treeInstance: {
18
18
  /** @internal */
19
19
  applySubStateUpdate: <K extends keyof TreeState<any>>(stateName: K, updater: Updater<TreeState<T>[K]>) => void;
20
- /** @internal */
21
- buildItemInstance: (itemId: string) => ItemInstance<T>;
22
20
  setState: SetStateFn<TreeState<T>>;
23
21
  getState: () => TreeState<T>;
24
22
  setConfig: SetStateFn<TreeConfig<T>>;
@@ -18,8 +18,8 @@ export type SyncDataLoaderFeatureDef<T> = {
18
18
  dataLoader: TreeDataLoader<T>;
19
19
  };
20
20
  treeInstance: {
21
- retrieveItemData: (itemId: string, skipFetch?: boolean) => T;
22
- retrieveChildrenIds: (itemId: string, skipFetch?: boolean) => string[];
21
+ retrieveItemData: (itemId: string) => T;
22
+ retrieveChildrenIds: (itemId: string) => string[];
23
23
  };
24
24
  itemInstance: {
25
25
  isLoading: () => boolean;
@@ -5,7 +5,6 @@ export { MainFeatureDef, InstanceBuilder } from "./features/main/types";
5
5
  export * from "./features/drag-and-drop/types";
6
6
  export * from "./features/keyboard-drag-and-drop/types";
7
7
  export * from "./features/selection/types";
8
- export * from "./features/checkboxes/types";
9
8
  export * from "./features/async-data-loader/types";
10
9
  export * from "./features/sync-data-loader/types";
11
10
  export * from "./features/hotkeys-core/types";
@@ -14,7 +13,6 @@ export * from "./features/renaming/types";
14
13
  export * from "./features/expand-all/types";
15
14
  export * from "./features/prop-memoization/types";
16
15
  export * from "./features/selection/feature";
17
- export * from "./features/checkboxes/feature";
18
16
  export * from "./features/hotkeys-core/feature";
19
17
  export * from "./features/async-data-loader/feature";
20
18
  export * from "./features/sync-data-loader/feature";
package/lib/cjs/index.js CHANGED
@@ -20,7 +20,6 @@ __exportStar(require("./features/tree/types"), exports);
20
20
  __exportStar(require("./features/drag-and-drop/types"), exports);
21
21
  __exportStar(require("./features/keyboard-drag-and-drop/types"), exports);
22
22
  __exportStar(require("./features/selection/types"), exports);
23
- __exportStar(require("./features/checkboxes/types"), exports);
24
23
  __exportStar(require("./features/async-data-loader/types"), exports);
25
24
  __exportStar(require("./features/sync-data-loader/types"), exports);
26
25
  __exportStar(require("./features/hotkeys-core/types"), exports);
@@ -29,7 +28,6 @@ __exportStar(require("./features/renaming/types"), exports);
29
28
  __exportStar(require("./features/expand-all/types"), exports);
30
29
  __exportStar(require("./features/prop-memoization/types"), exports);
31
30
  __exportStar(require("./features/selection/feature"), exports);
32
- __exportStar(require("./features/checkboxes/feature"), exports);
33
31
  __exportStar(require("./features/hotkeys-core/feature"), exports);
34
32
  __exportStar(require("./features/async-data-loader/feature"), exports);
35
33
  __exportStar(require("./features/sync-data-loader/feature"), exports);
@@ -10,7 +10,6 @@ import { RenamingFeatureDef } from "../features/renaming/types";
10
10
  import { ExpandAllFeatureDef } from "../features/expand-all/types";
11
11
  import { PropMemoizationFeatureDef } from "../features/prop-memoization/types";
12
12
  import { KeyboardDragAndDropFeatureDef } from "../features/keyboard-drag-and-drop/types";
13
- import { CheckboxesFeatureDef } from "../features/checkboxes/types";
14
13
  export type Updater<T> = T | ((old: T) => T);
15
14
  export type SetStateFn<T> = (updaterOrValue: Updater<T>) => void;
16
15
  export type FeatureDef = {
@@ -35,7 +34,7 @@ type MergedFeatures<F extends FeatureDef> = {
35
34
  itemInstance: UnionToIntersection<F["itemInstance"]>;
36
35
  hotkeys: F["hotkeys"];
37
36
  };
38
- export type RegisteredFeatures<T> = MainFeatureDef<T> | TreeFeatureDef<T> | SelectionFeatureDef<T> | CheckboxesFeatureDef<T> | DragAndDropFeatureDef<T> | KeyboardDragAndDropFeatureDef<T> | HotkeysCoreFeatureDef<T> | SyncDataLoaderFeatureDef<T> | AsyncDataLoaderFeatureDef<T> | SearchFeatureDef<T> | RenamingFeatureDef<T> | ExpandAllFeatureDef | PropMemoizationFeatureDef;
37
+ export type RegisteredFeatures<T> = MainFeatureDef<T> | TreeFeatureDef<T> | SelectionFeatureDef<T> | DragAndDropFeatureDef<T> | KeyboardDragAndDropFeatureDef<T> | HotkeysCoreFeatureDef<T> | SyncDataLoaderFeatureDef<T> | AsyncDataLoaderFeatureDef<T> | SearchFeatureDef<T> | RenamingFeatureDef<T> | ExpandAllFeatureDef | PropMemoizationFeatureDef;
39
38
  type TreeStateType<T> = MergedFeatures<RegisteredFeatures<T>>["state"];
40
39
  export interface TreeState<T> extends TreeStateType<T> {
41
40
  }
@@ -97,15 +97,6 @@ export const createTree = (initialConfig) => {
97
97
  const externalStateSetter = config[stateHandlerNames[stateName]];
98
98
  externalStateSetter === null || externalStateSetter === void 0 ? void 0 : externalStateSetter(state[stateName]);
99
99
  },
100
- buildItemInstance: ({}, itemId) => {
101
- const [instance, finalizeInstance] = buildInstance(features, "itemInstance", (instance) => ({
102
- item: instance,
103
- tree: treeInstance,
104
- itemId,
105
- }));
106
- finalizeInstance();
107
- return instance;
108
- },
109
100
  // TODO rebuildSubTree: (itemId: string) => void;
110
101
  rebuildTree: () => {
111
102
  var _a;
@@ -17,33 +17,28 @@ const getDataRef = (tree) => {
17
17
  return dataRef;
18
18
  };
19
19
  const loadItemData = (tree, itemId) => __awaiter(void 0, void 0, void 0, function* () {
20
- var _a, _b, _c;
20
+ var _a;
21
21
  const config = tree.getConfig();
22
22
  const dataRef = getDataRef(tree);
23
23
  const item = yield config.dataLoader.getItem(itemId);
24
24
  dataRef.current.itemData[itemId] = item;
25
25
  (_a = config.onLoadedItem) === null || _a === void 0 ? void 0 : _a.call(config, itemId, item);
26
26
  tree.applySubStateUpdate("loadingItemData", (loadingItemData) => loadingItemData.filter((id) => id !== itemId));
27
- (_b = dataRef.current.awaitingItemDataLoading) === null || _b === void 0 ? void 0 : _b[itemId].forEach((cb) => cb());
28
- (_c = dataRef.current.awaitingItemDataLoading) === null || _c === void 0 ? true : delete _c[itemId];
29
27
  return item;
30
28
  });
31
29
  const loadChildrenIds = (tree, itemId) => __awaiter(void 0, void 0, void 0, function* () {
32
- var _a, _b, _c, _d, _e;
30
+ var _a, _b;
33
31
  const config = tree.getConfig();
34
32
  const dataRef = getDataRef(tree);
35
33
  let childrenIds;
36
- // TODO is folder check?
37
34
  if ("getChildrenWithData" in config.dataLoader) {
38
35
  const children = yield config.dataLoader.getChildrenWithData(itemId);
39
36
  childrenIds = children.map((c) => c.id);
40
37
  dataRef.current.childrenIds[itemId] = childrenIds;
41
38
  children.forEach(({ id, data }) => {
42
- var _a, _b, _c;
39
+ var _a;
43
40
  dataRef.current.itemData[id] = data;
44
41
  (_a = config.onLoadedItem) === null || _a === void 0 ? void 0 : _a.call(config, id, data);
45
- (_b = dataRef.current.awaitingItemDataLoading) === null || _b === void 0 ? void 0 : _b[id].forEach((cb) => cb());
46
- (_c = dataRef.current.awaitingItemDataLoading) === null || _c === void 0 ? true : delete _c[id];
47
42
  });
48
43
  (_a = config.onLoadedChildren) === null || _a === void 0 ? void 0 : _a.call(config, itemId, childrenIds);
49
44
  tree.rebuildTree();
@@ -56,8 +51,6 @@ const loadChildrenIds = (tree, itemId) => __awaiter(void 0, void 0, void 0, func
56
51
  tree.rebuildTree();
57
52
  }
58
53
  tree.applySubStateUpdate("loadingItemChildrens", (loadingItemChildrens) => loadingItemChildrens.filter((id) => id !== itemId));
59
- (_d = (_c = dataRef.current.awaitingItemChildrensLoading) === null || _c === void 0 ? void 0 : _c[itemId]) === null || _d === void 0 ? void 0 : _d.forEach((cb) => cb());
60
- (_e = dataRef.current.awaitingItemChildrensLoading) === null || _e === void 0 ? true : delete _e[itemId];
61
54
  return childrenIds;
62
55
  });
63
56
  export const asyncDataLoaderFeature = {
@@ -69,35 +62,8 @@ export const asyncDataLoaderFeature = {
69
62
  loadingItemChildrens: "setLoadingItemChildrens",
70
63
  },
71
64
  treeInstance: {
72
- waitForItemDataLoaded: (_a, itemId_1) => __awaiter(void 0, [_a, itemId_1], void 0, function* ({ tree }, itemId) {
73
- tree.retrieveItemData(itemId);
74
- if (!tree.getState().loadingItemData.includes(itemId)) {
75
- return;
76
- }
77
- yield new Promise((resolve) => {
78
- var _a, _b;
79
- var _c, _d;
80
- const dataRef = tree.getDataRef();
81
- (_a = (_c = dataRef.current).awaitingItemDataLoading) !== null && _a !== void 0 ? _a : (_c.awaitingItemDataLoading = {});
82
- (_b = (_d = dataRef.current.awaitingItemDataLoading)[itemId]) !== null && _b !== void 0 ? _b : (_d[itemId] = []);
83
- dataRef.current.awaitingItemDataLoading[itemId].push(resolve);
84
- });
85
- }),
86
- waitForItemChildrenLoaded: (_a, itemId_1) => __awaiter(void 0, [_a, itemId_1], void 0, function* ({ tree }, itemId) {
87
- // TODO replace inner implementation with load() fns
88
- tree.retrieveChildrenIds(itemId);
89
- if (!tree.getState().loadingItemChildrens.includes(itemId)) {
90
- return;
91
- }
92
- yield new Promise((resolve) => {
93
- var _a, _b;
94
- var _c, _d;
95
- const dataRef = tree.getDataRef();
96
- (_a = (_c = dataRef.current).awaitingItemChildrensLoading) !== null && _a !== void 0 ? _a : (_c.awaitingItemChildrensLoading = {});
97
- (_b = (_d = dataRef.current.awaitingItemChildrensLoading)[itemId]) !== null && _b !== void 0 ? _b : (_d[itemId] = []);
98
- dataRef.current.awaitingItemChildrensLoading[itemId].push(resolve);
99
- });
100
- }),
65
+ waitForItemDataLoaded: ({ tree }, itemId) => tree.loadItemData(itemId),
66
+ waitForItemChildrenLoaded: ({ tree }, itemId) => tree.loadChildrenIds(itemId),
101
67
  loadItemData: (_a, itemId_1) => __awaiter(void 0, [_a, itemId_1], void 0, function* ({ tree }, itemId) {
102
68
  var _b;
103
69
  return ((_b = getDataRef(tree).current.itemData[itemId]) !== null && _b !== void 0 ? _b : (yield loadItemData(tree, itemId)));
@@ -106,14 +72,14 @@ export const asyncDataLoaderFeature = {
106
72
  var _b;
107
73
  return ((_b = getDataRef(tree).current.childrenIds[itemId]) !== null && _b !== void 0 ? _b : (yield loadChildrenIds(tree, itemId)));
108
74
  }),
109
- retrieveItemData: ({ tree }, itemId, skipFetch = false) => {
75
+ retrieveItemData: ({ tree }, itemId) => {
110
76
  var _a, _b;
111
77
  const config = tree.getConfig();
112
78
  const dataRef = getDataRef(tree);
113
79
  if (dataRef.current.itemData[itemId]) {
114
80
  return dataRef.current.itemData[itemId];
115
81
  }
116
- if (!tree.getState().loadingItemData.includes(itemId) && !skipFetch) {
82
+ if (!tree.getState().loadingItemData.includes(itemId)) {
117
83
  tree.applySubStateUpdate("loadingItemData", (loadingItemData) => [
118
84
  ...loadingItemData,
119
85
  itemId,
@@ -122,12 +88,12 @@ export const asyncDataLoaderFeature = {
122
88
  }
123
89
  return (_b = (_a = config.createLoadingItemData) === null || _a === void 0 ? void 0 : _a.call(config)) !== null && _b !== void 0 ? _b : null;
124
90
  },
125
- retrieveChildrenIds: ({ tree }, itemId, skipFetch = false) => {
91
+ retrieveChildrenIds: ({ tree }, itemId) => {
126
92
  const dataRef = getDataRef(tree);
127
93
  if (dataRef.current.childrenIds[itemId]) {
128
94
  return dataRef.current.childrenIds[itemId];
129
95
  }
130
- if (tree.getState().loadingItemChildrens.includes(itemId) || skipFetch) {
96
+ if (tree.getState().loadingItemChildrens.includes(itemId)) {
131
97
  return [];
132
98
  }
133
99
  tree.applySubStateUpdate("loadingItemChildrens", (loadingItemChildrens) => [...loadingItemChildrens, itemId]);
@@ -1,11 +1,8 @@
1
1
  import { SetStateFn } from "../../types/core";
2
2
  import { SyncDataLoaderFeatureDef } from "../sync-data-loader/types";
3
- type AwaitingLoaderCallbacks = Record<string, (() => void)[]>;
4
3
  export interface AsyncDataLoaderDataRef<T = any> {
5
4
  itemData: Record<string, T>;
6
5
  childrenIds: Record<string, string[]>;
7
- awaitingItemDataLoading: AwaitingLoaderCallbacks;
8
- awaitingItemChildrensLoading: AwaitingLoaderCallbacks;
9
6
  }
10
7
  /**
11
8
  * @category Async Data Loader/General
@@ -48,4 +45,3 @@ export type AsyncDataLoaderFeatureDef<T> = {
48
45
  };
49
46
  hotkeys: SyncDataLoaderFeatureDef<T>["hotkeys"];
50
47
  };
51
- export {};
@@ -17,8 +17,6 @@ export type MainFeatureDef<T = any> = {
17
17
  treeInstance: {
18
18
  /** @internal */
19
19
  applySubStateUpdate: <K extends keyof TreeState<any>>(stateName: K, updater: Updater<TreeState<T>[K]>) => void;
20
- /** @internal */
21
- buildItemInstance: (itemId: string) => ItemInstance<T>;
22
20
  setState: SetStateFn<TreeState<T>>;
23
21
  getState: () => TreeState<T>;
24
22
  setConfig: SetStateFn<TreeConfig<T>>;
@@ -18,8 +18,8 @@ export type SyncDataLoaderFeatureDef<T> = {
18
18
  dataLoader: TreeDataLoader<T>;
19
19
  };
20
20
  treeInstance: {
21
- retrieveItemData: (itemId: string, skipFetch?: boolean) => T;
22
- retrieveChildrenIds: (itemId: string, skipFetch?: boolean) => string[];
21
+ retrieveItemData: (itemId: string) => T;
22
+ retrieveChildrenIds: (itemId: string) => string[];
23
23
  };
24
24
  itemInstance: {
25
25
  isLoading: () => boolean;
@@ -5,7 +5,6 @@ export { MainFeatureDef, InstanceBuilder } from "./features/main/types";
5
5
  export * from "./features/drag-and-drop/types";
6
6
  export * from "./features/keyboard-drag-and-drop/types";
7
7
  export * from "./features/selection/types";
8
- export * from "./features/checkboxes/types";
9
8
  export * from "./features/async-data-loader/types";
10
9
  export * from "./features/sync-data-loader/types";
11
10
  export * from "./features/hotkeys-core/types";
@@ -14,7 +13,6 @@ export * from "./features/renaming/types";
14
13
  export * from "./features/expand-all/types";
15
14
  export * from "./features/prop-memoization/types";
16
15
  export * from "./features/selection/feature";
17
- export * from "./features/checkboxes/feature";
18
16
  export * from "./features/hotkeys-core/feature";
19
17
  export * from "./features/async-data-loader/feature";
20
18
  export * from "./features/sync-data-loader/feature";
package/lib/esm/index.js CHANGED
@@ -4,7 +4,6 @@ export * from "./features/tree/types";
4
4
  export * from "./features/drag-and-drop/types";
5
5
  export * from "./features/keyboard-drag-and-drop/types";
6
6
  export * from "./features/selection/types";
7
- export * from "./features/checkboxes/types";
8
7
  export * from "./features/async-data-loader/types";
9
8
  export * from "./features/sync-data-loader/types";
10
9
  export * from "./features/hotkeys-core/types";
@@ -13,7 +12,6 @@ export * from "./features/renaming/types";
13
12
  export * from "./features/expand-all/types";
14
13
  export * from "./features/prop-memoization/types";
15
14
  export * from "./features/selection/feature";
16
- export * from "./features/checkboxes/feature";
17
15
  export * from "./features/hotkeys-core/feature";
18
16
  export * from "./features/async-data-loader/feature";
19
17
  export * from "./features/sync-data-loader/feature";
@@ -10,7 +10,6 @@ import { RenamingFeatureDef } from "../features/renaming/types";
10
10
  import { ExpandAllFeatureDef } from "../features/expand-all/types";
11
11
  import { PropMemoizationFeatureDef } from "../features/prop-memoization/types";
12
12
  import { KeyboardDragAndDropFeatureDef } from "../features/keyboard-drag-and-drop/types";
13
- import { CheckboxesFeatureDef } from "../features/checkboxes/types";
14
13
  export type Updater<T> = T | ((old: T) => T);
15
14
  export type SetStateFn<T> = (updaterOrValue: Updater<T>) => void;
16
15
  export type FeatureDef = {
@@ -35,7 +34,7 @@ type MergedFeatures<F extends FeatureDef> = {
35
34
  itemInstance: UnionToIntersection<F["itemInstance"]>;
36
35
  hotkeys: F["hotkeys"];
37
36
  };
38
- export type RegisteredFeatures<T> = MainFeatureDef<T> | TreeFeatureDef<T> | SelectionFeatureDef<T> | CheckboxesFeatureDef<T> | DragAndDropFeatureDef<T> | KeyboardDragAndDropFeatureDef<T> | HotkeysCoreFeatureDef<T> | SyncDataLoaderFeatureDef<T> | AsyncDataLoaderFeatureDef<T> | SearchFeatureDef<T> | RenamingFeatureDef<T> | ExpandAllFeatureDef | PropMemoizationFeatureDef;
37
+ export type RegisteredFeatures<T> = MainFeatureDef<T> | TreeFeatureDef<T> | SelectionFeatureDef<T> | DragAndDropFeatureDef<T> | KeyboardDragAndDropFeatureDef<T> | HotkeysCoreFeatureDef<T> | SyncDataLoaderFeatureDef<T> | AsyncDataLoaderFeatureDef<T> | SearchFeatureDef<T> | RenamingFeatureDef<T> | ExpandAllFeatureDef | PropMemoizationFeatureDef;
39
38
  type TreeStateType<T> = MergedFeatures<RegisteredFeatures<T>>["state"];
40
39
  export interface TreeState<T> extends TreeStateType<T> {
41
40
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@headless-tree/core",
3
- "version": "0.0.0-20250509212452",
3
+ "version": "0.0.0-20250511190858",
4
4
  "type": "module",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/esm/index.js",
@@ -151,19 +151,6 @@ export const createTree = <T>(
151
151
  ] as Function;
152
152
  externalStateSetter?.(state[stateName]);
153
153
  },
154
- buildItemInstance: ({}, itemId) => {
155
- const [instance, finalizeInstance] = buildInstance(
156
- features,
157
- "itemInstance",
158
- (instance) => ({
159
- item: instance,
160
- tree: treeInstance,
161
- itemId,
162
- }),
163
- );
164
- finalizeInstance();
165
- return instance;
166
- },
167
154
  // TODO rebuildSubTree: (itemId: string) => void;
168
155
  rebuildTree: () => {
169
156
  rebuildItemMeta();
@@ -20,8 +20,6 @@ const loadItemData = async <T>(tree: TreeInstance<T>, itemId: string) => {
20
20
  loadingItemData.filter((id) => id !== itemId),
21
21
  );
22
22
 
23
- dataRef.current.awaitingItemDataLoading?.[itemId].forEach((cb) => cb());
24
- delete dataRef.current.awaitingItemDataLoading?.[itemId];
25
23
  return item;
26
24
  };
27
25
 
@@ -30,8 +28,6 @@ const loadChildrenIds = async <T>(tree: TreeInstance<T>, itemId: string) => {
30
28
  const dataRef = getDataRef(tree);
31
29
  let childrenIds: string[];
32
30
 
33
- // TODO is folder check?
34
-
35
31
  if ("getChildrenWithData" in config.dataLoader) {
36
32
  const children = await config.dataLoader.getChildrenWithData(itemId);
37
33
  childrenIds = children.map((c) => c.id);
@@ -39,8 +35,6 @@ const loadChildrenIds = async <T>(tree: TreeInstance<T>, itemId: string) => {
39
35
  children.forEach(({ id, data }) => {
40
36
  dataRef.current.itemData[id] = data;
41
37
  config.onLoadedItem?.(id, data);
42
- dataRef.current.awaitingItemDataLoading?.[id].forEach((cb) => cb());
43
- delete dataRef.current.awaitingItemDataLoading?.[id];
44
38
  });
45
39
 
46
40
  config.onLoadedChildren?.(itemId, childrenIds);
@@ -59,8 +53,6 @@ const loadChildrenIds = async <T>(tree: TreeInstance<T>, itemId: string) => {
59
53
  loadingItemChildrens.filter((id) => id !== itemId),
60
54
  );
61
55
 
62
- dataRef.current.awaitingItemChildrensLoading?.[itemId]?.forEach((cb) => cb());
63
- delete dataRef.current.awaitingItemChildrensLoading?.[itemId];
64
56
  return childrenIds;
65
57
  };
66
58
 
@@ -85,32 +77,10 @@ export const asyncDataLoaderFeature: FeatureImplementation = {
85
77
  },
86
78
 
87
79
  treeInstance: {
88
- waitForItemDataLoaded: async ({ tree }, itemId) => {
89
- tree.retrieveItemData(itemId);
90
- if (!tree.getState().loadingItemData.includes(itemId)) {
91
- return;
92
- }
93
- await new Promise<void>((resolve) => {
94
- const dataRef = tree.getDataRef<AsyncDataLoaderDataRef>();
95
- dataRef.current.awaitingItemDataLoading ??= {};
96
- dataRef.current.awaitingItemDataLoading[itemId] ??= [];
97
- dataRef.current.awaitingItemDataLoading[itemId].push(resolve);
98
- });
99
- },
80
+ waitForItemDataLoaded: ({ tree }, itemId) => tree.loadItemData(itemId),
100
81
 
101
- waitForItemChildrenLoaded: async ({ tree }, itemId) => {
102
- // TODO replace inner implementation with load() fns
103
- tree.retrieveChildrenIds(itemId);
104
- if (!tree.getState().loadingItemChildrens.includes(itemId)) {
105
- return;
106
- }
107
- await new Promise<void>((resolve) => {
108
- const dataRef = tree.getDataRef<AsyncDataLoaderDataRef>();
109
- dataRef.current.awaitingItemChildrensLoading ??= {};
110
- dataRef.current.awaitingItemChildrensLoading[itemId] ??= [];
111
- dataRef.current.awaitingItemChildrensLoading[itemId].push(resolve);
112
- });
113
- },
82
+ waitForItemChildrenLoaded: ({ tree }, itemId) =>
83
+ tree.loadChildrenIds(itemId),
114
84
 
115
85
  loadItemData: async ({ tree }, itemId) => {
116
86
  return (
@@ -125,7 +95,7 @@ export const asyncDataLoaderFeature: FeatureImplementation = {
125
95
  );
126
96
  },
127
97
 
128
- retrieveItemData: ({ tree }, itemId, skipFetch = false) => {
98
+ retrieveItemData: ({ tree }, itemId) => {
129
99
  const config = tree.getConfig();
130
100
  const dataRef = getDataRef(tree);
131
101
 
@@ -133,7 +103,7 @@ export const asyncDataLoaderFeature: FeatureImplementation = {
133
103
  return dataRef.current.itemData[itemId];
134
104
  }
135
105
 
136
- if (!tree.getState().loadingItemData.includes(itemId) && !skipFetch) {
106
+ if (!tree.getState().loadingItemData.includes(itemId)) {
137
107
  tree.applySubStateUpdate("loadingItemData", (loadingItemData) => [
138
108
  ...loadingItemData,
139
109
  itemId,
@@ -145,13 +115,13 @@ export const asyncDataLoaderFeature: FeatureImplementation = {
145
115
  return config.createLoadingItemData?.() ?? null;
146
116
  },
147
117
 
148
- retrieveChildrenIds: ({ tree }, itemId, skipFetch = false) => {
118
+ retrieveChildrenIds: ({ tree }, itemId) => {
149
119
  const dataRef = getDataRef(tree);
150
120
  if (dataRef.current.childrenIds[itemId]) {
151
121
  return dataRef.current.childrenIds[itemId];
152
122
  }
153
123
 
154
- if (tree.getState().loadingItemChildrens.includes(itemId) || skipFetch) {
124
+ if (tree.getState().loadingItemChildrens.includes(itemId)) {
155
125
  return [];
156
126
  }
157
127
 
@@ -1,13 +1,9 @@
1
1
  import { SetStateFn } from "../../types/core";
2
2
  import { SyncDataLoaderFeatureDef } from "../sync-data-loader/types";
3
3
 
4
- type AwaitingLoaderCallbacks = Record<string, (() => void)[]>;
5
-
6
4
  export interface AsyncDataLoaderDataRef<T = any> {
7
5
  itemData: Record<string, T>;
8
6
  childrenIds: Record<string, string[]>;
9
- awaitingItemDataLoading: AwaitingLoaderCallbacks;
10
- awaitingItemChildrensLoading: AwaitingLoaderCallbacks;
11
7
  }
12
8
 
13
9
  /**
@@ -36,8 +36,6 @@ export type MainFeatureDef<T = any> = {
36
36
  stateName: K,
37
37
  updater: Updater<TreeState<T>[K]>,
38
38
  ) => void;
39
- /** @internal */
40
- buildItemInstance: (itemId: string) => ItemInstance<T>;
41
39
  setState: SetStateFn<TreeState<T>>;
42
40
  getState: () => TreeState<T>;
43
41
  setConfig: SetStateFn<TreeConfig<T>>;
@@ -17,8 +17,8 @@ export type SyncDataLoaderFeatureDef<T> = {
17
17
  dataLoader: TreeDataLoader<T>;
18
18
  };
19
19
  treeInstance: {
20
- retrieveItemData: (itemId: string, skipFetch?: boolean) => T;
21
- retrieveChildrenIds: (itemId: string, skipFetch?: boolean) => string[];
20
+ retrieveItemData: (itemId: string) => T;
21
+ retrieveChildrenIds: (itemId: string) => string[];
22
22
  };
23
23
  itemInstance: {
24
24
  isLoading: () => boolean;
package/src/index.ts CHANGED
@@ -6,7 +6,6 @@ export { MainFeatureDef, InstanceBuilder } from "./features/main/types";
6
6
  export * from "./features/drag-and-drop/types";
7
7
  export * from "./features/keyboard-drag-and-drop/types";
8
8
  export * from "./features/selection/types";
9
- export * from "./features/checkboxes/types";
10
9
  export * from "./features/async-data-loader/types";
11
10
  export * from "./features/sync-data-loader/types";
12
11
  export * from "./features/hotkeys-core/types";
@@ -16,7 +15,6 @@ export * from "./features/expand-all/types";
16
15
  export * from "./features/prop-memoization/types";
17
16
 
18
17
  export * from "./features/selection/feature";
19
- export * from "./features/checkboxes/feature";
20
18
  export * from "./features/hotkeys-core/feature";
21
19
  export * from "./features/async-data-loader/feature";
22
20
  export * from "./features/sync-data-loader/feature";
package/src/types/core.ts CHANGED
@@ -13,7 +13,6 @@ import { RenamingFeatureDef } from "../features/renaming/types";
13
13
  import { ExpandAllFeatureDef } from "../features/expand-all/types";
14
14
  import { PropMemoizationFeatureDef } from "../features/prop-memoization/types";
15
15
  import { KeyboardDragAndDropFeatureDef } from "../features/keyboard-drag-and-drop/types";
16
- import { CheckboxesFeatureDef } from "../features/checkboxes/types";
17
16
 
18
17
  export type Updater<T> = T | ((old: T) => T);
19
18
  export type SetStateFn<T> = (updaterOrValue: Updater<T>) => void;
@@ -54,7 +53,6 @@ export type RegisteredFeatures<T> =
54
53
  | MainFeatureDef<T>
55
54
  | TreeFeatureDef<T>
56
55
  | SelectionFeatureDef<T>
57
- | CheckboxesFeatureDef<T>
58
56
  | DragAndDropFeatureDef<T>
59
57
  | KeyboardDragAndDropFeatureDef<T>
60
58
  | HotkeysCoreFeatureDef<T>
@@ -1,2 +0,0 @@
1
- import { FeatureImplementation } from "../../types/core";
2
- export declare const checkboxesFeature: FeatureImplementation;
@@ -1,128 +0,0 @@
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
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.checkboxesFeature = void 0;
13
- const utils_1 = require("../../utils");
14
- const types_1 = require("./types");
15
- /*
16
- * Cases for checking:
17
- * - Check an unchecked item in an unchecked or indeterminate folder
18
- * - Check an explicitly unchecked item in a checked folder
19
- * - Check an unchecked folder in an unchecked or indeterminate folder
20
- *
21
- * Cases for unchecking:
22
- * - Uncheck a checked item in an indeterminate folder
23
- * - Uncheck an explicitly unchecked item in an checked folder
24
- */
25
- const fetchAllDescendants = (tree, itemId) => __awaiter(void 0, void 0, void 0, function* () {
26
- const children = yield tree.loadChildrenIds(itemId);
27
- return [
28
- itemId,
29
- ...(yield Promise.all(children.map((child) => fetchAllDescendants(tree, child)))).flat(),
30
- ];
31
- });
32
- const getAllLoadedDescendants = (tree, itemId) => {
33
- const children = tree.retrieveChildrenIds(itemId, true);
34
- return [
35
- itemId,
36
- ...children.map((child) => getAllLoadedDescendants(tree, child)).flat(),
37
- ];
38
- };
39
- exports.checkboxesFeature = {
40
- key: "checkboxes",
41
- overwrites: ["selection"],
42
- getInitialState: (initialState) => (Object.assign({ checkedItems: [] }, initialState)),
43
- getDefaultConfig: (defaultConfig, tree) => (Object.assign({ setCheckedItems: (0, utils_1.makeStateUpdater)("checkedItems", tree) }, defaultConfig)),
44
- stateHandlerNames: {
45
- checkedItems: "setCheckedItems",
46
- },
47
- treeInstance: {
48
- setCheckedItems: ({ tree }, checkedItems) => {
49
- tree.applySubStateUpdate("checkedItems", checkedItems);
50
- },
51
- },
52
- itemInstance: {
53
- getCheckboxProps: ({ item, itemId }) => {
54
- const checkedState = item.getCheckedState();
55
- // console.log("prop", itemId, checkedState);
56
- return {
57
- onChange: item.toggleCheckedState,
58
- checked: checkedState === types_1.CheckedState.Checked,
59
- ref: (r) => {
60
- if (r) {
61
- // console.log("ref", itemId, checkedState);
62
- r.indeterminate = checkedState === types_1.CheckedState.Indeterminate;
63
- }
64
- },
65
- };
66
- },
67
- toggleCheckedState: (_a) => __awaiter(void 0, [_a], void 0, function* ({ item }) {
68
- if (item.getCheckedState() === types_1.CheckedState.Checked) {
69
- yield item.setUnchecked();
70
- }
71
- else {
72
- yield item.setChecked();
73
- }
74
- }),
75
- getCheckedState: ({ item, tree, itemId }) => {
76
- // TODO checkedcache
77
- const { checkedItems } = tree.getState();
78
- if (checkedItems.includes(itemId)) {
79
- return types_1.CheckedState.Checked;
80
- }
81
- if (item.isFolder()) {
82
- const descendants = getAllLoadedDescendants(tree, itemId);
83
- console.log("descendants of ", itemId, descendants);
84
- if (descendants.every((d) => checkedItems.includes(d))) {
85
- return types_1.CheckedState.Checked;
86
- }
87
- if (descendants.some((d) => checkedItems.includes(d))) {
88
- return types_1.CheckedState.Indeterminate;
89
- }
90
- }
91
- // if (
92
- // item.isFolder() &&
93
- // checkedItems.some((checkedItem) =>
94
- // tree.getItemInstance(checkedItem)?.isDescendentOf(itemId),
95
- // )
96
- // ) {
97
- // // TODO for every descendent, not every checked item
98
- // return checkedItems.every((checkedItem) =>
99
- // tree.getItemInstance(checkedItem)?.isDescendentOf(itemId),
100
- // )
101
- // ? CheckedState.Checked
102
- // : CheckedState.Indeterminate;
103
- // }
104
- return types_1.CheckedState.Unchecked;
105
- },
106
- setChecked: (_a) => __awaiter(void 0, [_a], void 0, function* ({ item, tree, itemId }) {
107
- if (!item.isFolder() || tree.getConfig().canCheckFolders) {
108
- tree.applySubStateUpdate("checkedItems", (items) => [...items, itemId]);
109
- }
110
- else {
111
- const descendants = yield fetchAllDescendants(tree, itemId);
112
- tree.applySubStateUpdate("checkedItems", (items) => [
113
- ...items,
114
- ...descendants,
115
- ]);
116
- }
117
- }),
118
- setUnchecked: (_a) => __awaiter(void 0, [_a], void 0, function* ({ item, tree, itemId }) {
119
- if (!item.isFolder() || tree.getConfig().canCheckFolders) {
120
- tree.applySubStateUpdate("checkedItems", (items) => items.filter((id) => id !== itemId));
121
- }
122
- else {
123
- yield tree.loadChildrenIds(itemId);
124
- item.getChildren().forEach((item) => item.setUnchecked());
125
- }
126
- }),
127
- },
128
- };
@@ -1,26 +0,0 @@
1
- import { SetStateFn } from "../../types/core";
2
- export declare enum CheckedState {
3
- Checked = "checked",
4
- Unchecked = "unchecked",
5
- Indeterminate = "indeterminate"
6
- }
7
- export type CheckboxesFeatureDef<T> = {
8
- state: {
9
- checkedItems: string[];
10
- };
11
- config: {
12
- setCheckedItems?: SetStateFn<string[]>;
13
- canCheckFolders?: boolean;
14
- };
15
- treeInstance: {
16
- setCheckedItems: (checkedItems: string[]) => void;
17
- };
18
- itemInstance: {
19
- setChecked: () => Promise<void>;
20
- setUnchecked: () => Promise<void>;
21
- toggleCheckedState: () => Promise<void>;
22
- getCheckedState: () => CheckedState;
23
- getCheckboxProps: () => Record<string, any>;
24
- };
25
- hotkeys: never;
26
- };
@@ -1,9 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CheckedState = void 0;
4
- var CheckedState;
5
- (function (CheckedState) {
6
- CheckedState["Checked"] = "checked";
7
- CheckedState["Unchecked"] = "unchecked";
8
- CheckedState["Indeterminate"] = "indeterminate";
9
- })(CheckedState || (exports.CheckedState = CheckedState = {}));
@@ -1,2 +0,0 @@
1
- import { FeatureImplementation } from "../../types/core";
2
- export declare const checkboxesFeature: FeatureImplementation;
@@ -1,125 +0,0 @@
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
- };
10
- import { makeStateUpdater } from "../../utils";
11
- import { CheckedState } from "./types";
12
- /*
13
- * Cases for checking:
14
- * - Check an unchecked item in an unchecked or indeterminate folder
15
- * - Check an explicitly unchecked item in a checked folder
16
- * - Check an unchecked folder in an unchecked or indeterminate folder
17
- *
18
- * Cases for unchecking:
19
- * - Uncheck a checked item in an indeterminate folder
20
- * - Uncheck an explicitly unchecked item in an checked folder
21
- */
22
- const fetchAllDescendants = (tree, itemId) => __awaiter(void 0, void 0, void 0, function* () {
23
- const children = yield tree.loadChildrenIds(itemId);
24
- return [
25
- itemId,
26
- ...(yield Promise.all(children.map((child) => fetchAllDescendants(tree, child)))).flat(),
27
- ];
28
- });
29
- const getAllLoadedDescendants = (tree, itemId) => {
30
- const children = tree.retrieveChildrenIds(itemId, true);
31
- return [
32
- itemId,
33
- ...children.map((child) => getAllLoadedDescendants(tree, child)).flat(),
34
- ];
35
- };
36
- export const checkboxesFeature = {
37
- key: "checkboxes",
38
- overwrites: ["selection"],
39
- getInitialState: (initialState) => (Object.assign({ checkedItems: [] }, initialState)),
40
- getDefaultConfig: (defaultConfig, tree) => (Object.assign({ setCheckedItems: makeStateUpdater("checkedItems", tree) }, defaultConfig)),
41
- stateHandlerNames: {
42
- checkedItems: "setCheckedItems",
43
- },
44
- treeInstance: {
45
- setCheckedItems: ({ tree }, checkedItems) => {
46
- tree.applySubStateUpdate("checkedItems", checkedItems);
47
- },
48
- },
49
- itemInstance: {
50
- getCheckboxProps: ({ item, itemId }) => {
51
- const checkedState = item.getCheckedState();
52
- // console.log("prop", itemId, checkedState);
53
- return {
54
- onChange: item.toggleCheckedState,
55
- checked: checkedState === CheckedState.Checked,
56
- ref: (r) => {
57
- if (r) {
58
- // console.log("ref", itemId, checkedState);
59
- r.indeterminate = checkedState === CheckedState.Indeterminate;
60
- }
61
- },
62
- };
63
- },
64
- toggleCheckedState: (_a) => __awaiter(void 0, [_a], void 0, function* ({ item }) {
65
- if (item.getCheckedState() === CheckedState.Checked) {
66
- yield item.setUnchecked();
67
- }
68
- else {
69
- yield item.setChecked();
70
- }
71
- }),
72
- getCheckedState: ({ item, tree, itemId }) => {
73
- // TODO checkedcache
74
- const { checkedItems } = tree.getState();
75
- if (checkedItems.includes(itemId)) {
76
- return CheckedState.Checked;
77
- }
78
- if (item.isFolder()) {
79
- const descendants = getAllLoadedDescendants(tree, itemId);
80
- console.log("descendants of ", itemId, descendants);
81
- if (descendants.every((d) => checkedItems.includes(d))) {
82
- return CheckedState.Checked;
83
- }
84
- if (descendants.some((d) => checkedItems.includes(d))) {
85
- return CheckedState.Indeterminate;
86
- }
87
- }
88
- // if (
89
- // item.isFolder() &&
90
- // checkedItems.some((checkedItem) =>
91
- // tree.getItemInstance(checkedItem)?.isDescendentOf(itemId),
92
- // )
93
- // ) {
94
- // // TODO for every descendent, not every checked item
95
- // return checkedItems.every((checkedItem) =>
96
- // tree.getItemInstance(checkedItem)?.isDescendentOf(itemId),
97
- // )
98
- // ? CheckedState.Checked
99
- // : CheckedState.Indeterminate;
100
- // }
101
- return CheckedState.Unchecked;
102
- },
103
- setChecked: (_a) => __awaiter(void 0, [_a], void 0, function* ({ item, tree, itemId }) {
104
- if (!item.isFolder() || tree.getConfig().canCheckFolders) {
105
- tree.applySubStateUpdate("checkedItems", (items) => [...items, itemId]);
106
- }
107
- else {
108
- const descendants = yield fetchAllDescendants(tree, itemId);
109
- tree.applySubStateUpdate("checkedItems", (items) => [
110
- ...items,
111
- ...descendants,
112
- ]);
113
- }
114
- }),
115
- setUnchecked: (_a) => __awaiter(void 0, [_a], void 0, function* ({ item, tree, itemId }) {
116
- if (!item.isFolder() || tree.getConfig().canCheckFolders) {
117
- tree.applySubStateUpdate("checkedItems", (items) => items.filter((id) => id !== itemId));
118
- }
119
- else {
120
- yield tree.loadChildrenIds(itemId);
121
- item.getChildren().forEach((item) => item.setUnchecked());
122
- }
123
- }),
124
- },
125
- };
@@ -1,26 +0,0 @@
1
- import { SetStateFn } from "../../types/core";
2
- export declare enum CheckedState {
3
- Checked = "checked",
4
- Unchecked = "unchecked",
5
- Indeterminate = "indeterminate"
6
- }
7
- export type CheckboxesFeatureDef<T> = {
8
- state: {
9
- checkedItems: string[];
10
- };
11
- config: {
12
- setCheckedItems?: SetStateFn<string[]>;
13
- canCheckFolders?: boolean;
14
- };
15
- treeInstance: {
16
- setCheckedItems: (checkedItems: string[]) => void;
17
- };
18
- itemInstance: {
19
- setChecked: () => Promise<void>;
20
- setUnchecked: () => Promise<void>;
21
- toggleCheckedState: () => Promise<void>;
22
- getCheckedState: () => CheckedState;
23
- getCheckboxProps: () => Record<string, any>;
24
- };
25
- hotkeys: never;
26
- };
@@ -1,6 +0,0 @@
1
- export var CheckedState;
2
- (function (CheckedState) {
3
- CheckedState["Checked"] = "checked";
4
- CheckedState["Unchecked"] = "unchecked";
5
- CheckedState["Indeterminate"] = "indeterminate";
6
- })(CheckedState || (CheckedState = {}));
@@ -1,150 +0,0 @@
1
- import { FeatureImplementation, TreeInstance } from "../../types/core";
2
- import { makeStateUpdater } from "../../utils";
3
- import { CheckedState } from "./types";
4
-
5
- /*
6
- * Cases for checking:
7
- * - Check an unchecked item in an unchecked or indeterminate folder
8
- * - Check an explicitly unchecked item in a checked folder
9
- * - Check an unchecked folder in an unchecked or indeterminate folder
10
- *
11
- * Cases for unchecking:
12
- * - Uncheck a checked item in an indeterminate folder
13
- * - Uncheck an explicitly unchecked item in an checked folder
14
- */
15
-
16
- const fetchAllDescendants = async <T>(
17
- tree: TreeInstance<T>,
18
- itemId: string,
19
- ): Promise<string[]> => {
20
- const children = await tree.loadChildrenIds(itemId);
21
- return [
22
- itemId,
23
- ...(
24
- await Promise.all(
25
- children.map((child) => fetchAllDescendants(tree, child)),
26
- )
27
- ).flat(),
28
- ];
29
- };
30
-
31
- const getAllLoadedDescendants = <T>(
32
- tree: TreeInstance<T>,
33
- itemId: string,
34
- ): string[] => {
35
- const children = tree.retrieveChildrenIds(itemId, true);
36
- return [
37
- itemId,
38
- ...children.map((child) => getAllLoadedDescendants(tree, child)).flat(),
39
- ];
40
- };
41
-
42
- export const checkboxesFeature: FeatureImplementation = {
43
- key: "checkboxes",
44
-
45
- overwrites: ["selection"],
46
-
47
- getInitialState: (initialState) => ({
48
- checkedItems: [],
49
- ...initialState,
50
- }),
51
-
52
- getDefaultConfig: (defaultConfig, tree) => ({
53
- setCheckedItems: makeStateUpdater("checkedItems", tree),
54
- ...defaultConfig,
55
- }),
56
-
57
- stateHandlerNames: {
58
- checkedItems: "setCheckedItems",
59
- },
60
-
61
- treeInstance: {
62
- setCheckedItems: ({ tree }, checkedItems) => {
63
- tree.applySubStateUpdate("checkedItems", checkedItems);
64
- },
65
- },
66
-
67
- itemInstance: {
68
- getCheckboxProps: ({ item, itemId }) => {
69
- const checkedState = item.getCheckedState();
70
- // console.log("prop", itemId, checkedState);
71
- return {
72
- onChange: item.toggleCheckedState,
73
- checked: checkedState === CheckedState.Checked,
74
- ref: (r: any) => {
75
- if (r) {
76
- // console.log("ref", itemId, checkedState);
77
- r.indeterminate = checkedState === CheckedState.Indeterminate;
78
- }
79
- },
80
- };
81
- },
82
-
83
- toggleCheckedState: async ({ item }) => {
84
- if (item.getCheckedState() === CheckedState.Checked) {
85
- await item.setUnchecked();
86
- } else {
87
- await item.setChecked();
88
- }
89
- },
90
-
91
- getCheckedState: ({ item, tree, itemId }) => {
92
- // TODO checkedcache
93
- const { checkedItems } = tree.getState();
94
-
95
- if (checkedItems.includes(itemId)) {
96
- return CheckedState.Checked;
97
- }
98
-
99
- if (item.isFolder()) {
100
- const descendants = getAllLoadedDescendants(tree, itemId);
101
- console.log("descendants of ", itemId, descendants);
102
- if (descendants.every((d) => checkedItems.includes(d))) {
103
- return CheckedState.Checked;
104
- }
105
- if (descendants.some((d) => checkedItems.includes(d))) {
106
- return CheckedState.Indeterminate;
107
- }
108
- }
109
-
110
- // if (
111
- // item.isFolder() &&
112
- // checkedItems.some((checkedItem) =>
113
- // tree.getItemInstance(checkedItem)?.isDescendentOf(itemId),
114
- // )
115
- // ) {
116
- // // TODO for every descendent, not every checked item
117
- // return checkedItems.every((checkedItem) =>
118
- // tree.getItemInstance(checkedItem)?.isDescendentOf(itemId),
119
- // )
120
- // ? CheckedState.Checked
121
- // : CheckedState.Indeterminate;
122
- // }
123
-
124
- return CheckedState.Unchecked;
125
- },
126
-
127
- setChecked: async ({ item, tree, itemId }) => {
128
- if (!item.isFolder() || tree.getConfig().canCheckFolders) {
129
- tree.applySubStateUpdate("checkedItems", (items) => [...items, itemId]);
130
- } else {
131
- const descendants = await fetchAllDescendants(tree, itemId);
132
- tree.applySubStateUpdate("checkedItems", (items) => [
133
- ...items,
134
- ...descendants,
135
- ]);
136
- }
137
- },
138
-
139
- setUnchecked: async ({ item, tree, itemId }) => {
140
- if (!item.isFolder() || tree.getConfig().canCheckFolders) {
141
- tree.applySubStateUpdate("checkedItems", (items) =>
142
- items.filter((id) => id !== itemId),
143
- );
144
- } else {
145
- await tree.loadChildrenIds(itemId);
146
- item.getChildren().forEach((item) => item.setUnchecked());
147
- }
148
- },
149
- },
150
- };
@@ -1,28 +0,0 @@
1
- import { SetStateFn } from "../../types/core";
2
-
3
- export enum CheckedState {
4
- Checked = "checked",
5
- Unchecked = "unchecked",
6
- Indeterminate = "indeterminate",
7
- }
8
-
9
- export type CheckboxesFeatureDef<T> = {
10
- state: {
11
- checkedItems: string[];
12
- };
13
- config: {
14
- setCheckedItems?: SetStateFn<string[]>;
15
- canCheckFolders?: boolean;
16
- };
17
- treeInstance: {
18
- setCheckedItems: (checkedItems: string[]) => void;
19
- };
20
- itemInstance: {
21
- setChecked: () => Promise<void>;
22
- setUnchecked: () => Promise<void>;
23
- toggleCheckedState: () => Promise<void>;
24
- getCheckedState: () => CheckedState;
25
- getCheckboxProps: () => Record<string, any>;
26
- };
27
- hotkeys: never;
28
- };