@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/src/index.ts ADDED
@@ -0,0 +1,26 @@
1
+ export * from "./types/core";
2
+ export * from "./core/create-tree";
3
+
4
+ export * from "./features/tree/types";
5
+ export * from "./features/main/types";
6
+ export * from "./features/drag-and-drop/types";
7
+ export * from "./features/selection/types";
8
+ export * from "./features/async-data-loader/types";
9
+ export * from "./features/sync-data-loader/types";
10
+ export * from "./features/hotkeys-core/types";
11
+ export * from "./features/search/types";
12
+ export * from "./features/renaming/types";
13
+ export * from "./features/expand-all/types";
14
+
15
+ export * from "./features/selection/feature";
16
+ export * from "./features/hotkeys-core/feature";
17
+ export * from "./features/async-data-loader/feature";
18
+ export * from "./features/sync-data-loader/feature";
19
+ export * from "./features/drag-and-drop/feature";
20
+ export * from "./features/search/feature";
21
+ export * from "./features/renaming/feature";
22
+ export * from "./features/expand-all/feature";
23
+
24
+ export * from "./utilities/create-on-drop-handler";
25
+ export * from "./utilities/insert-items-at-target";
26
+ export * from "./utilities/remove-items-from-parents";
@@ -0,0 +1,26 @@
1
+ import { MainFeatureDef } from "./features/main/types";
2
+ import { DragAndDropFeatureDef } from "./features/drag-and-drop/types";
3
+
4
+ export * from ".";
5
+
6
+ /** @interface */
7
+ export type MainFeatureConfig = MainFeatureDef["config"];
8
+ /** @interface */
9
+ export type MainFeatureState = MainFeatureDef["state"];
10
+ /** @interface */
11
+ export type MainFeatureTreeInstance = MainFeatureDef["treeInstance"];
12
+ /** @interface */
13
+ export type MainFeatureItemInstance = MainFeatureDef["itemInstance"];
14
+ export type MainFeatureHotkeys = MainFeatureDef["hotkeys"];
15
+
16
+ /** @interface */
17
+ export type DragAndDropFeatureConfig<T> = DragAndDropFeatureDef<T>["config"];
18
+ /** @interface */
19
+ export type DragAndDropFeatureState<T> = DragAndDropFeatureDef<T>["state"];
20
+ /** @interface */
21
+ export type DragAndDropFeatureTreeInstance<T> =
22
+ DragAndDropFeatureDef<T>["treeInstance"];
23
+ /** @interface */
24
+ export type DragAndDropFeatureItemInstance<T> =
25
+ DragAndDropFeatureDef<T>["itemInstance"];
26
+ export type DragAndDropFeatureHotkeys<T> = DragAndDropFeatureDef<T>["hotkeys"];
@@ -0,0 +1,183 @@
1
+ import { DragAndDropFeatureDef } from "../features/drag-and-drop/types";
2
+ import { MainFeatureDef } from "../features/main/types";
3
+ import { SelectionFeatureDef } from "../features/selection/types";
4
+ import { TreeFeatureDef } from "../features/tree/types";
5
+ import {
6
+ HotkeyConfig,
7
+ HotkeysCoreFeatureDef,
8
+ } from "../features/hotkeys-core/types";
9
+ import { SyncDataLoaderFeatureDef } from "../features/sync-data-loader/types";
10
+ import { AsyncDataLoaderFeatureDef } from "../features/async-data-loader/types";
11
+ import { SearchFeatureDef } from "../features/search/types";
12
+ import { RenamingFeatureDef } from "../features/renaming/types";
13
+ import { ExpandAllFeatureDef } from "../features/expand-all/types";
14
+
15
+ export type Updater<T> = T | ((old: T) => T);
16
+ export type SetStateFn<T> = (updaterOrValue: Updater<T>) => void;
17
+
18
+ export type FeatureDef = {
19
+ state: object;
20
+ config: object;
21
+ treeInstance: object;
22
+ itemInstance: object;
23
+ hotkeys: string;
24
+ };
25
+
26
+ export type EmptyFeatureDef = {
27
+ state: {};
28
+ config: {};
29
+ treeInstance: {};
30
+ itemInstance: {};
31
+ hotkeys: never;
32
+ };
33
+
34
+ type UnionToIntersection<T> = (T extends any ? (x: T) => any : never) extends (
35
+ x: infer R
36
+ ) => any
37
+ ? R
38
+ : never;
39
+
40
+ export type DefaultFeatures<T> = MainFeatureDef | TreeFeatureDef<T>;
41
+
42
+ export type FeatureDefs<T> =
43
+ | MainFeatureDef
44
+ | TreeFeatureDef<T>
45
+ | SelectionFeatureDef<T>
46
+ | DragAndDropFeatureDef<T>
47
+ | HotkeysCoreFeatureDef<T>
48
+ | SyncDataLoaderFeatureDef<T>
49
+ | AsyncDataLoaderFeatureDef<T>
50
+ | SearchFeatureDef<T>
51
+ | RenamingFeatureDef<T>
52
+ | ExpandAllFeatureDef;
53
+
54
+ type MergedFeatures<F extends FeatureDef> = {
55
+ state: UnionToIntersection<F["state"]>;
56
+ config: UnionToIntersection<F["config"]>;
57
+ treeInstance: UnionToIntersection<F["treeInstance"]>;
58
+ itemInstance: UnionToIntersection<F["itemInstance"]>;
59
+ hotkeys: F["hotkeys"];
60
+ };
61
+
62
+ type TreeStateType<T> = MainFeatureDef["state"] &
63
+ TreeFeatureDef<T>["state"] &
64
+ SelectionFeatureDef<T>["state"] &
65
+ DragAndDropFeatureDef<T>["state"] &
66
+ HotkeysCoreFeatureDef<T>["state"] &
67
+ SyncDataLoaderFeatureDef<T>["state"] &
68
+ AsyncDataLoaderFeatureDef<T>["state"] &
69
+ SearchFeatureDef<T>["state"] &
70
+ RenamingFeatureDef<T>["state"] &
71
+ ExpandAllFeatureDef["state"];
72
+ export interface TreeState<T> extends TreeStateType<T> {}
73
+
74
+ type TreeConfigType<T> = MainFeatureDef["config"] &
75
+ TreeFeatureDef<T>["config"] &
76
+ SelectionFeatureDef<T>["config"] &
77
+ DragAndDropFeatureDef<T>["config"] &
78
+ HotkeysCoreFeatureDef<T>["config"] &
79
+ SyncDataLoaderFeatureDef<T>["config"] &
80
+ AsyncDataLoaderFeatureDef<T>["config"] &
81
+ SearchFeatureDef<T>["config"] &
82
+ RenamingFeatureDef<T>["config"] &
83
+ ExpandAllFeatureDef["config"];
84
+ export interface TreeConfig<T> extends TreeConfigType<T> {}
85
+
86
+ type TreeInstanceType<T> = MainFeatureDef["treeInstance"] &
87
+ TreeFeatureDef<T>["treeInstance"] &
88
+ SelectionFeatureDef<T>["treeInstance"] &
89
+ DragAndDropFeatureDef<T>["treeInstance"] &
90
+ HotkeysCoreFeatureDef<T>["treeInstance"] &
91
+ SyncDataLoaderFeatureDef<T>["treeInstance"] &
92
+ AsyncDataLoaderFeatureDef<T>["treeInstance"] &
93
+ SearchFeatureDef<T>["treeInstance"] &
94
+ RenamingFeatureDef<T>["treeInstance"] &
95
+ ExpandAllFeatureDef["treeInstance"];
96
+ export interface TreeInstance<T> extends TreeInstanceType<T> {}
97
+
98
+ type ItemInstanceType<T> = MainFeatureDef["itemInstance"] &
99
+ TreeFeatureDef<T>["itemInstance"] &
100
+ SelectionFeatureDef<T>["itemInstance"] &
101
+ DragAndDropFeatureDef<T>["itemInstance"] &
102
+ HotkeysCoreFeatureDef<T>["itemInstance"] &
103
+ SyncDataLoaderFeatureDef<T>["itemInstance"] &
104
+ AsyncDataLoaderFeatureDef<T>["itemInstance"] &
105
+ SearchFeatureDef<T>["itemInstance"] &
106
+ RenamingFeatureDef<T>["itemInstance"] &
107
+ ExpandAllFeatureDef["itemInstance"];
108
+ export interface ItemInstance<T> extends ItemInstanceType<T> {}
109
+
110
+ export type HotkeyName<F extends FeatureDef = FeatureDefs<any>> =
111
+ MergedFeatures<F>["hotkeys"];
112
+
113
+ export type HotkeysConfig<T, F extends FeatureDef = FeatureDefs<T>> = Record<
114
+ HotkeyName<F>,
115
+ HotkeyConfig<T>
116
+ >;
117
+
118
+ export type CustomHotkeysConfig<
119
+ T,
120
+ F extends FeatureDef = FeatureDefs<T>
121
+ > = Partial<
122
+ Record<HotkeyName<F> | `custom${string}`, Partial<HotkeyConfig<T>>>
123
+ >;
124
+
125
+ export type FeatureImplementation<
126
+ T = any,
127
+ D extends FeatureDef = any,
128
+ F extends FeatureDef = EmptyFeatureDef
129
+ > = {
130
+ key?: string;
131
+ deps?: string[];
132
+ overwrites?: string[];
133
+
134
+ stateHandlerNames?: Partial<
135
+ Record<keyof MergedFeatures<F>["state"], keyof MergedFeatures<F>["config"]>
136
+ >;
137
+
138
+ getInitialState?: (
139
+ initialState: Partial<MergedFeatures<F>["state"]>,
140
+ tree: MergedFeatures<F>["treeInstance"]
141
+ ) => Partial<D["state"] & MergedFeatures<F>["state"]>;
142
+
143
+ getDefaultConfig?: (
144
+ defaultConfig: Partial<MergedFeatures<F>["config"]>,
145
+ tree: MergedFeatures<F>["treeInstance"]
146
+ ) => Partial<D["config"] & MergedFeatures<F>["config"]>;
147
+
148
+ createTreeInstance?: (
149
+ prev: MergedFeatures<F>["treeInstance"],
150
+ instance: MergedFeatures<F>["treeInstance"]
151
+ ) => D["treeInstance"] & MergedFeatures<F>["treeInstance"];
152
+
153
+ createItemInstance?: (
154
+ prev: MergedFeatures<F>["itemInstance"],
155
+ item: MergedFeatures<F>["itemInstance"],
156
+ tree: MergedFeatures<F>["treeInstance"],
157
+ itemId: string
158
+ ) => D["itemInstance"] & MergedFeatures<F>["itemInstance"];
159
+
160
+ onTreeMount?: (
161
+ instance: MergedFeatures<F>["treeInstance"],
162
+ treeElement: HTMLElement
163
+ ) => void;
164
+
165
+ onTreeUnmount?: (
166
+ instance: MergedFeatures<F>["treeInstance"],
167
+ treeElement: HTMLElement
168
+ ) => void;
169
+
170
+ onItemMount?: (
171
+ instance: MergedFeatures<F>["itemInstance"],
172
+ itemElement: HTMLElement,
173
+ tree: MergedFeatures<F>["treeInstance"]
174
+ ) => void;
175
+
176
+ onItemUnmount?: (
177
+ instance: MergedFeatures<F>["itemInstance"],
178
+ itemElement: HTMLElement,
179
+ tree: MergedFeatures<F>["treeInstance"]
180
+ ) => void;
181
+
182
+ hotkeys?: HotkeysConfig<T, D>;
183
+ };
@@ -0,0 +1,31 @@
1
+ type TAllKeys<T> = T extends any ? keyof T : never;
2
+
3
+ type TIndexValue<T, K extends PropertyKey, D = never> = T extends any
4
+ ? K extends keyof T
5
+ ? T[K]
6
+ : D
7
+ : never;
8
+
9
+ type TPartialKeys<T, K extends keyof T> = Omit<T, K> &
10
+ Partial<Pick<T, K>> extends infer O
11
+ ? { [P in keyof O]: O[P] }
12
+ : never;
13
+
14
+ type TFunction = (...a: any[]) => any;
15
+
16
+ type TPrimitives =
17
+ | string
18
+ | number
19
+ | boolean
20
+ | bigint
21
+ | symbol
22
+ | Date
23
+ | TFunction;
24
+
25
+ export type TMerged<T> = [T] extends [Array<any>]
26
+ ? { [K in keyof T]: TMerged<T[K]> }
27
+ : [T] extends [TPrimitives]
28
+ ? T
29
+ : [T] extends [object]
30
+ ? TPartialKeys<{ [K in TAllKeys<T>]: TMerged<TIndexValue<T, K>> }, never>
31
+ : T;
@@ -0,0 +1,14 @@
1
+ import { ItemInstance } from "../types/core";
2
+ import { DropTarget } from "../features/drag-and-drop/types";
3
+ import { removeItemsFromParents } from "./remove-items-from-parents";
4
+ import { insertItemsAtTarget } from "./insert-items-at-target";
5
+
6
+ export const createOnDropHandler =
7
+ <T>(
8
+ onChangeChildren: (item: ItemInstance<T>, newChildren: string[]) => void
9
+ ) =>
10
+ (items: ItemInstance<T>[], target: DropTarget<T>) => {
11
+ const itemIds = items.map((item) => item.getId());
12
+ removeItemsFromParents(items, onChangeChildren);
13
+ insertItemsAtTarget(itemIds, target, onChangeChildren);
14
+ };
@@ -0,0 +1,30 @@
1
+ import { ItemInstance } from "../types/core";
2
+ import { DropTarget } from "../features/drag-and-drop/types";
3
+
4
+ export const insertItemsAtTarget = <T>(
5
+ itemIds: string[],
6
+ target: DropTarget<T>,
7
+ onChangeChildren: (item: ItemInstance<T>, newChildrenIds: string[]) => void
8
+ ) => {
9
+ // add moved items to new common parent, if dropped onto parent
10
+ if (target.childIndex === null) {
11
+ onChangeChildren(target.item, [
12
+ ...target.item.getChildren().map((item) => item.getId()),
13
+ ...itemIds,
14
+ ]);
15
+ // TODO items[0].getTree().rebuildTree();
16
+ return;
17
+ }
18
+
19
+ // add moved items to new common parent, if dropped between siblings
20
+ const oldChildren = target.item.getChildren();
21
+ const newChildren = [
22
+ ...oldChildren.slice(0, target.insertionIndex).map((item) => item.getId()),
23
+ ...itemIds,
24
+ ...oldChildren.slice(target.insertionIndex).map((item) => item.getId()),
25
+ ];
26
+
27
+ onChangeChildren(target.item, newChildren);
28
+
29
+ target.item.getTree().rebuildTree();
30
+ };
@@ -0,0 +1,21 @@
1
+ import { ItemInstance } from "../types/core";
2
+
3
+ export const removeItemsFromParents = <T>(
4
+ movedItems: ItemInstance<T>[],
5
+ onChangeChildren: (item: ItemInstance<T>, newChildrenIds: string[]) => void
6
+ ) => {
7
+ // TODO bulk sibling changes together
8
+ for (const item of movedItems) {
9
+ const siblings = item.getParent()?.getChildren();
10
+ if (siblings) {
11
+ onChangeChildren(
12
+ item.getParent(),
13
+ siblings
14
+ .filter((sibling) => sibling.getId() !== item.getId())
15
+ .map((i) => i.getId())
16
+ );
17
+ }
18
+ }
19
+
20
+ movedItems[0].getTree().rebuildTree();
21
+ };
package/src/utils.ts ADDED
@@ -0,0 +1,68 @@
1
+ import { TreeState, Updater } from "./types/core";
2
+
3
+ export type NoInfer<T> = [T][T extends any ? 0 : never];
4
+
5
+ export const memo = <D extends readonly any[], R>(
6
+ fn: (...args: [...D]) => R,
7
+ deps: () => [...D]
8
+ ) => {
9
+ let value: R | undefined;
10
+ let oldDeps: D | null = null;
11
+
12
+ return () => {
13
+ const newDeps = deps();
14
+
15
+ if (!value) {
16
+ value = fn(...newDeps);
17
+ oldDeps = newDeps;
18
+ return value;
19
+ }
20
+
21
+ const match =
22
+ oldDeps &&
23
+ oldDeps.length === newDeps.length &&
24
+ !oldDeps.some((dep, i) => dep !== newDeps[i]);
25
+
26
+ if (match) {
27
+ return value;
28
+ }
29
+
30
+ value = fn(...newDeps);
31
+ oldDeps = newDeps;
32
+ return value;
33
+ };
34
+ };
35
+
36
+ export function functionalUpdate<T>(updater: Updater<T>, input: T): T {
37
+ return typeof updater === "function"
38
+ ? (updater as (input: T) => T)(input)
39
+ : updater;
40
+ }
41
+ export function makeStateUpdater<K extends keyof TreeState<any>>(
42
+ key: K,
43
+ instance: unknown
44
+ ) {
45
+ return (updater: Updater<TreeState<any>[K]>) => {
46
+ (instance as any).setState(<TTableState>(old: TTableState) => {
47
+ return {
48
+ ...old,
49
+ [key]: functionalUpdate(updater, (old as any)[key]),
50
+ };
51
+ });
52
+ };
53
+ }
54
+
55
+ export const poll = (fn: () => boolean, interval = 100, timeout = 1000) =>
56
+ new Promise<void>((resolve) => {
57
+ let clear: ReturnType<typeof setTimeout>;
58
+ const i = setInterval(() => {
59
+ if (fn()) {
60
+ resolve();
61
+ clearInterval(i);
62
+ clearTimeout(clear);
63
+ }
64
+ }, interval);
65
+ clear = setTimeout(() => {
66
+ clearInterval(i);
67
+ }, timeout);
68
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "include": ["./src/**/*"],
4
+ "compilerOptions": {
5
+ "outDir": "lib/esm"
6
+ }
7
+ }
package/typedoc.json ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": ["../../typedoc.base.json"],
3
+ "entryPoints": ["src/index.ts"]
4
+ }