@headless-tree/core 0.0.11 → 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/lib/cjs/core/build-static-instance.js +1 -2
  3. package/lib/cjs/core/create-tree.js +7 -4
  4. package/lib/cjs/features/async-data-loader/feature.d.ts +1 -4
  5. package/lib/cjs/features/async-data-loader/feature.js +5 -7
  6. package/lib/cjs/features/async-data-loader/types.d.ts +2 -5
  7. package/lib/cjs/features/drag-and-drop/feature.d.ts +2 -3
  8. package/lib/cjs/features/drag-and-drop/feature.js +27 -24
  9. package/lib/cjs/features/drag-and-drop/types.d.ts +3 -3
  10. package/lib/cjs/features/drag-and-drop/utils.d.ts +1 -1
  11. package/lib/cjs/features/drag-and-drop/utils.js +4 -4
  12. package/lib/cjs/features/expand-all/feature.d.ts +1 -5
  13. package/lib/cjs/features/hotkeys-core/feature.d.ts +1 -3
  14. package/lib/cjs/features/prop-memoization/feature.d.ts +2 -0
  15. package/lib/cjs/features/prop-memoization/feature.js +48 -0
  16. package/lib/cjs/features/prop-memoization/types.d.ts +10 -0
  17. package/lib/cjs/features/prop-memoization/types.js +2 -0
  18. package/lib/cjs/features/renaming/feature.d.ts +1 -4
  19. package/lib/cjs/features/renaming/feature.js +8 -9
  20. package/lib/cjs/features/renaming/types.d.ts +1 -1
  21. package/lib/cjs/features/search/feature.d.ts +1 -4
  22. package/lib/cjs/features/selection/feature.d.ts +1 -4
  23. package/lib/cjs/features/selection/feature.js +35 -25
  24. package/lib/cjs/features/selection/types.d.ts +1 -1
  25. package/lib/cjs/features/sync-data-loader/feature.d.ts +1 -3
  26. package/lib/cjs/features/tree/feature.d.ts +1 -6
  27. package/lib/cjs/features/tree/feature.js +40 -57
  28. package/lib/cjs/features/tree/types.d.ts +0 -5
  29. package/lib/cjs/index.d.ts +2 -0
  30. package/lib/cjs/index.js +2 -0
  31. package/lib/cjs/mddocs-entry.d.ts +10 -0
  32. package/lib/cjs/test-utils/test-tree-do.d.ts +1 -1
  33. package/lib/cjs/test-utils/test-tree-expect.d.ts +1 -1
  34. package/lib/cjs/test-utils/test-tree-expect.js +1 -1
  35. package/lib/cjs/test-utils/test-tree.d.ts +1 -1
  36. package/lib/cjs/test-utils/test-tree.js +9 -1
  37. package/lib/cjs/types/core.d.ts +29 -30
  38. package/lib/esm/core/build-static-instance.js +1 -2
  39. package/lib/esm/core/create-tree.js +7 -4
  40. package/lib/esm/features/async-data-loader/feature.d.ts +1 -4
  41. package/lib/esm/features/async-data-loader/feature.js +5 -7
  42. package/lib/esm/features/async-data-loader/types.d.ts +2 -5
  43. package/lib/esm/features/drag-and-drop/feature.d.ts +2 -3
  44. package/lib/esm/features/drag-and-drop/feature.js +27 -24
  45. package/lib/esm/features/drag-and-drop/types.d.ts +3 -3
  46. package/lib/esm/features/drag-and-drop/utils.d.ts +1 -1
  47. package/lib/esm/features/drag-and-drop/utils.js +4 -4
  48. package/lib/esm/features/expand-all/feature.d.ts +1 -5
  49. package/lib/esm/features/hotkeys-core/feature.d.ts +1 -3
  50. package/lib/esm/features/prop-memoization/feature.d.ts +2 -0
  51. package/lib/esm/features/prop-memoization/feature.js +45 -0
  52. package/lib/esm/features/prop-memoization/types.d.ts +10 -0
  53. package/lib/esm/features/prop-memoization/types.js +1 -0
  54. package/lib/esm/features/renaming/feature.d.ts +1 -4
  55. package/lib/esm/features/renaming/feature.js +8 -9
  56. package/lib/esm/features/renaming/types.d.ts +1 -1
  57. package/lib/esm/features/search/feature.d.ts +1 -4
  58. package/lib/esm/features/selection/feature.d.ts +1 -4
  59. package/lib/esm/features/selection/feature.js +35 -25
  60. package/lib/esm/features/selection/types.d.ts +1 -1
  61. package/lib/esm/features/sync-data-loader/feature.d.ts +1 -3
  62. package/lib/esm/features/tree/feature.d.ts +1 -6
  63. package/lib/esm/features/tree/feature.js +40 -57
  64. package/lib/esm/features/tree/types.d.ts +0 -5
  65. package/lib/esm/index.d.ts +2 -0
  66. package/lib/esm/index.js +2 -0
  67. package/lib/esm/mddocs-entry.d.ts +10 -0
  68. package/lib/esm/test-utils/test-tree-do.d.ts +1 -1
  69. package/lib/esm/test-utils/test-tree-expect.d.ts +1 -1
  70. package/lib/esm/test-utils/test-tree-expect.js +1 -1
  71. package/lib/esm/test-utils/test-tree.d.ts +1 -1
  72. package/lib/esm/test-utils/test-tree.js +9 -1
  73. package/lib/esm/types/core.d.ts +29 -30
  74. package/package.json +1 -1
  75. package/src/core/build-proxified-instance.ts +5 -3
  76. package/src/core/build-static-instance.ts +1 -2
  77. package/src/core/core.spec.ts +210 -0
  78. package/src/core/create-tree.ts +13 -16
  79. package/src/features/async-data-loader/async-data-loader.spec.ts +12 -31
  80. package/src/features/async-data-loader/feature.ts +8 -20
  81. package/src/features/async-data-loader/types.ts +2 -6
  82. package/src/features/drag-and-drop/drag-and-drop.spec.ts +4 -3
  83. package/src/features/drag-and-drop/feature.ts +87 -86
  84. package/src/features/drag-and-drop/types.ts +4 -4
  85. package/src/features/drag-and-drop/utils.ts +4 -4
  86. package/src/features/expand-all/expand-all.spec.ts +5 -1
  87. package/src/features/expand-all/feature.ts +1 -12
  88. package/src/features/hotkeys-core/feature.ts +4 -13
  89. package/src/features/prop-memoization/feature.ts +51 -0
  90. package/src/features/prop-memoization/prop-memoization.spec.ts +68 -0
  91. package/src/features/prop-memoization/types.ts +11 -0
  92. package/src/features/renaming/feature.ts +11 -20
  93. package/src/features/renaming/renaming.spec.ts +11 -9
  94. package/src/features/renaming/types.ts +1 -1
  95. package/src/features/search/feature.ts +2 -8
  96. package/src/features/search/search.spec.ts +3 -1
  97. package/src/features/selection/feature.ts +45 -47
  98. package/src/features/selection/selection.spec.ts +13 -14
  99. package/src/features/selection/types.ts +0 -2
  100. package/src/features/sync-data-loader/feature.ts +1 -7
  101. package/src/features/tree/feature.ts +47 -85
  102. package/src/features/tree/tree.spec.ts +24 -64
  103. package/src/features/tree/types.ts +0 -6
  104. package/src/index.ts +2 -0
  105. package/src/mddocs-entry.ts +13 -0
  106. package/src/test-utils/test-tree-expect.ts +1 -1
  107. package/src/test-utils/test-tree.ts +11 -1
  108. package/src/types/core.ts +56 -147
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @headless-tree/core
2
2
 
3
+ ## 0.0.12
4
+
5
+ ### Patch Changes
6
+
7
+ - 7236907: dev release
8
+
3
9
  ## 0.0.11
4
10
 
5
11
  ### Patch Changes
@@ -7,8 +7,7 @@ const buildStaticInstance = (features, instanceType, buildOpts) => {
7
7
  const finalize = () => {
8
8
  const opts = buildOpts(instance);
9
9
  featureLoop: for (let i = 0; i < features.length; i++) {
10
- // Loop goes in forward order, because later features overwrite previous ones
11
- // TODO loop order correct? I think so...
10
+ // Loop goes in forward order, each features overwrite previous ones and wraps those in a prev() fn
12
11
  const definition = features[i][instanceType];
13
12
  if (!definition)
14
13
  continue featureLoop;
@@ -14,14 +14,17 @@ const verifyFeatures = (features) => {
14
14
  }
15
15
  }
16
16
  };
17
- const compareFeatures = (feature1, feature2) => {
18
- var _a;
17
+ const compareFeatures = (originalOrder) => (feature1, feature2) => {
18
+ var _a, _b;
19
19
  if (feature2.key && ((_a = feature1.overwrites) === null || _a === void 0 ? void 0 : _a.includes(feature2.key))) {
20
20
  return 1;
21
21
  }
22
- return -1;
22
+ if (feature1.key && ((_b = feature2.overwrites) === null || _b === void 0 ? void 0 : _b.includes(feature1.key))) {
23
+ return -1;
24
+ }
25
+ return originalOrder.indexOf(feature1) - originalOrder.indexOf(feature2);
23
26
  };
24
- const sortFeatures = (features = []) => features.sort(compareFeatures);
27
+ const sortFeatures = (features = []) => features.sort(compareFeatures(features));
25
28
  const createTree = (initialConfig) => {
26
29
  var _a, _b, _c, _d;
27
30
  const buildInstance = (_a = initialConfig.instanceBuilder) !== null && _a !== void 0 ? _a : build_static_instance_1.buildStaticInstance;
@@ -1,5 +1,2 @@
1
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>>;
2
+ export declare const asyncDataLoaderFeature: FeatureImplementation;
@@ -76,23 +76,21 @@ exports.asyncDataLoaderFeature = {
76
76
  }
77
77
  return [];
78
78
  },
79
- invalidateItemData: ({ tree }, itemId) => {
79
+ },
80
+ itemInstance: {
81
+ isLoading: ({ tree, item }) => tree.getState().loadingItems.includes(item.getItemMeta().itemId),
82
+ invalidateItemData: ({ tree, itemId }) => {
80
83
  var _a;
81
84
  const dataRef = tree.getDataRef();
82
85
  (_a = dataRef.current.itemData) === null || _a === void 0 ? true : delete _a[itemId];
83
86
  tree.retrieveItemData(itemId);
84
87
  },
85
- invalidateChildrenIds: ({ tree }, itemId) => {
88
+ invalidateChildrenIds: ({ tree, itemId }) => {
86
89
  var _a;
87
90
  const dataRef = tree.getDataRef();
88
91
  (_a = dataRef.current.childrenIds) === null || _a === void 0 ? true : delete _a[itemId];
89
92
  tree.retrieveChildrenIds(itemId);
90
93
  },
91
- },
92
- itemInstance: {
93
- isLoading: ({ tree, item }) => tree.getState().loadingItems.includes(item.getItemMeta().itemId),
94
- invalidateItemData: ({ tree, item }) => tree.invalidateItemData(item.getItemMeta().itemId),
95
- invalidateChildrenIds: ({ tree, item }) => tree.invalidateChildrenIds(item.getItemMeta().itemId),
96
94
  updateCachedChildrenIds: ({ tree, itemId }, childrenIds) => {
97
95
  const dataRef = tree.getDataRef();
98
96
  dataRef.current.childrenIds[itemId] = childrenIds;
@@ -27,12 +27,9 @@ export type AsyncDataLoaderFeatureDef<T> = {
27
27
  onLoadedChildren?: (itemId: string, childrenIds: string[]) => void;
28
28
  asyncDataLoader?: AsyncTreeDataLoader<T>;
29
29
  };
30
- treeInstance: SyncDataLoaderFeatureDef<T>["treeInstance"] & {
31
- /** Invalidate fetched data for item, and triggers a refetch and subsequent rerender if the item is visible */
32
- invalidateItemData: (itemId: string) => void;
33
- invalidateChildrenIds: (itemId: string) => void;
34
- };
30
+ treeInstance: SyncDataLoaderFeatureDef<T>["treeInstance"];
35
31
  itemInstance: SyncDataLoaderFeatureDef<T>["itemInstance"] & {
32
+ /** Invalidate fetched data for item, and triggers a refetch and subsequent rerender if the item is visible */
36
33
  invalidateItemData: () => void;
37
34
  invalidateChildrenIds: () => void;
38
35
  updateCachedChildrenIds: (childrenIds: string[]) => void;
@@ -1,3 +1,2 @@
1
- import { FeatureDefs, FeatureImplementation } from "../../types/core";
2
- import { DragAndDropFeatureDef } from "./types";
3
- export declare const dragAndDropFeature: FeatureImplementation<any, DragAndDropFeatureDef<any>, FeatureDefs<any>>;
1
+ import { FeatureImplementation } from "../../types/core";
2
+ export declare const dragAndDropFeature: FeatureImplementation;
@@ -4,9 +4,9 @@ exports.dragAndDropFeature = void 0;
4
4
  const utils_1 = require("./utils");
5
5
  const utils_2 = require("../../utils");
6
6
  exports.dragAndDropFeature = {
7
- key: "dragAndDrop",
7
+ key: "drag-and-drop",
8
8
  deps: ["selection"],
9
- getDefaultConfig: (defaultConfig, tree) => (Object.assign({ canDrop: (_, target) => target.item.isFolder(), canDropForeignDragObject: () => false, setDndState: (0, utils_2.makeStateUpdater)("dnd", tree), canDropInbetween: true }, defaultConfig)),
9
+ getDefaultConfig: (defaultConfig, tree) => (Object.assign({ canDrop: (_, target) => target.item.isFolder(), canDropForeignDragObject: () => false, setDndState: (0, utils_2.makeStateUpdater)("dnd", tree), canReorder: true }, defaultConfig)),
10
10
  stateHandlerNames: {
11
11
  dnd: "setDndState",
12
12
  },
@@ -16,33 +16,33 @@ exports.dragAndDropFeature = {
16
16
  return (_b = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.dragTarget) !== null && _b !== void 0 ? _b : null;
17
17
  },
18
18
  getDragLineData: ({ tree }) => {
19
- var _a, _b, _c, _d, _e;
20
- // TODO doesnt work if scrolled down!
19
+ var _a, _b, _c, _d, _e, _f;
21
20
  const target = tree.getDropTarget();
22
- const indent = ((_a = target === null || target === void 0 ? void 0 : target.item.getItemMeta().level) !== null && _a !== void 0 ? _a : 0) + 1; // TODO rename to indent
23
- if (!target || target.childIndex === null)
21
+ const indent = ((_a = target === null || target === void 0 ? void 0 : target.item.getItemMeta().level) !== null && _a !== void 0 ? _a : 0) + 1;
22
+ const treeBb = (_b = tree.getElement()) === null || _b === void 0 ? void 0 : _b.getBoundingClientRect();
23
+ if (!target || !treeBb || target.childIndex === null)
24
24
  return null;
25
- const leftOffset = target.dragLineLevel * ((_b = tree.getConfig().indent) !== null && _b !== void 0 ? _b : 1);
25
+ const leftOffset = target.dragLineLevel * ((_c = tree.getConfig().indent) !== null && _c !== void 0 ? _c : 1);
26
26
  const targetItem = tree.getItems()[target.dragLineIndex];
27
27
  if (!targetItem) {
28
- const bb = (_d = (_c = tree
29
- .getItems()[target.dragLineIndex - 1]) === null || _c === void 0 ? void 0 : _c.getElement()) === null || _d === void 0 ? void 0 : _d.getBoundingClientRect();
28
+ const bb = (_e = (_d = tree
29
+ .getItems()[target.dragLineIndex - 1]) === null || _d === void 0 ? void 0 : _d.getElement()) === null || _e === void 0 ? void 0 : _e.getBoundingClientRect();
30
30
  if (bb) {
31
31
  return {
32
32
  indent,
33
- top: bb.bottom,
34
- left: bb.left + leftOffset,
35
- right: bb.right,
33
+ top: bb.bottom - treeBb.bottom,
34
+ left: bb.left + leftOffset - treeBb.left,
35
+ width: bb.width - leftOffset,
36
36
  };
37
37
  }
38
38
  }
39
- const bb = (_e = targetItem.getElement()) === null || _e === void 0 ? void 0 : _e.getBoundingClientRect();
39
+ const bb = (_f = targetItem.getElement()) === null || _f === void 0 ? void 0 : _f.getBoundingClientRect();
40
40
  if (bb) {
41
41
  return {
42
42
  indent,
43
- top: bb.top,
44
- left: bb.left + leftOffset,
45
- right: bb.right,
43
+ top: bb.top - treeBb.top,
44
+ left: bb.left + leftOffset - treeBb.left,
45
+ width: bb.width - leftOffset,
46
46
  };
47
47
  }
48
48
  return null;
@@ -53,17 +53,20 @@ exports.dragAndDropFeature = {
53
53
  ? {
54
54
  top: `${dragLine.top + topOffset}px`,
55
55
  left: `${dragLine.left + leftOffset}px`,
56
- width: `${dragLine.right - dragLine.left - leftOffset}px`,
56
+ width: `${dragLine.width - leftOffset}px`,
57
57
  pointerEvents: "none", // important to prevent capturing drag events
58
58
  }
59
59
  : { display: "none" };
60
60
  },
61
+ getContainerProps: ({ prev }) => {
62
+ const prevProps = prev === null || prev === void 0 ? void 0 : prev();
63
+ return Object.assign(Object.assign({}, prevProps), { style: Object.assign(Object.assign({}, prevProps === null || prevProps === void 0 ? void 0 : prevProps.style), { position: "relative" }) });
64
+ },
61
65
  },
62
66
  itemInstance: {
63
- // TODO instead of individual getMemoizedProp calls, use a wrapped getMemoizedProps or something (getProps: () => getMemoized({...})
64
67
  getProps: ({ tree, item, prev }) => {
65
68
  var _a, _b, _c;
66
- return (Object.assign(Object.assign({}, prev === null || prev === void 0 ? void 0 : prev()), { draggable: (_c = (_b = (_a = tree.getConfig()).isItemDraggable) === null || _b === void 0 ? void 0 : _b.call(_a, item)) !== null && _c !== void 0 ? _c : true, onDragStart: item.getMemoizedProp("dnd/onDragStart", () => (e) => {
69
+ return (Object.assign(Object.assign({}, prev === null || prev === void 0 ? void 0 : prev()), { draggable: (_c = (_b = (_a = tree.getConfig()).isItemDraggable) === null || _b === void 0 ? void 0 : _b.call(_a, item)) !== null && _c !== void 0 ? _c : true, onDragStart: (e) => {
67
70
  var _a, _b, _c;
68
71
  const selectedItems = tree.getSelectedItems();
69
72
  const items = selectedItems.includes(item) ? selectedItems : [item];
@@ -83,7 +86,7 @@ exports.dragAndDropFeature = {
83
86
  draggedItems: items,
84
87
  draggingOverItem: tree.getFocusedItem(),
85
88
  });
86
- }), onDragOver: item.getMemoizedProp("dnd/onDragOver", () => (e) => {
89
+ }, onDragOver: (e) => {
87
90
  var _a, _b, _c;
88
91
  const dataRef = tree.getDataRef();
89
92
  const nextDragCode = (0, utils_1.getDragCode)(e, item, tree);
@@ -109,11 +112,11 @@ exports.dragAndDropFeature = {
109
112
  tree.applySubStateUpdate("dnd", (state) => (Object.assign(Object.assign({}, state), { dragTarget: target, draggingOverItem: item })));
110
113
  dataRef.current.lastAllowDrop = true;
111
114
  e.preventDefault();
112
- }), onDragLeave: item.getMemoizedProp("dnd/onDragLeave", () => () => {
115
+ }, onDragLeave: () => {
113
116
  const dataRef = tree.getDataRef();
114
117
  dataRef.current.lastDragCode = "no-drag";
115
118
  tree.applySubStateUpdate("dnd", (state) => (Object.assign(Object.assign({}, state), { draggingOverItem: undefined, dragTarget: undefined })));
116
- }), onDragEnd: item.getMemoizedProp("dnd/onDragEnd", () => (e) => {
119
+ }, onDragEnd: (e) => {
117
120
  var _a, _b, _c, _d;
118
121
  const draggedItems = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems;
119
122
  tree.applySubStateUpdate("dnd", null);
@@ -121,7 +124,7 @@ exports.dragAndDropFeature = {
121
124
  return;
122
125
  }
123
126
  (_d = (_c = tree.getConfig()).onCompleteForeignDrop) === null || _d === void 0 ? void 0 : _d.call(_c, draggedItems);
124
- }), onDrop: item.getMemoizedProp("dnd/onDrop", () => (e) => {
127
+ }, onDrop: (e) => {
125
128
  var _a, _b, _c;
126
129
  const dataRef = tree.getDataRef();
127
130
  const target = (0, utils_1.getDropTarget)(e, item, tree);
@@ -140,7 +143,7 @@ exports.dragAndDropFeature = {
140
143
  (_c = config.onDropForeignDragObject) === null || _c === void 0 ? void 0 : _c.call(config, e.dataTransfer, target);
141
144
  }
142
145
  // TODO rebuild tree?
143
- }) }));
146
+ } }));
144
147
  },
145
148
  isDropTarget: ({ tree, item }) => {
146
149
  const target = tree.getDropTarget();
@@ -12,7 +12,7 @@ export type DragLineData = {
12
12
  indent: number;
13
13
  top: number;
14
14
  left: number;
15
- right: number;
15
+ width: number;
16
16
  };
17
17
  export type DropTarget<T> = {
18
18
  item: ItemInstance<T>;
@@ -40,9 +40,9 @@ export type DragAndDropFeatureDef<T> = {
40
40
  setDndState?: SetStateFn<DndState<T> | undefined | null>;
41
41
  /** Defines the size of the area at the top and bottom of an item where, when an item is dropped, the item willö
42
42
  * be placed above or below the item within the same parent, as opposed to being placed inside the item.
43
- * If `canDropInbetween` is `false`, this is ignored. */
43
+ * If `canReorder` is `false`, this is ignored. */
44
44
  reorderAreaPercentage?: number;
45
- canDropInbetween?: boolean;
45
+ canReorder?: boolean;
46
46
  isItemDraggable?: (item: ItemInstance<T>) => boolean;
47
47
  canDrag?: (items: ItemInstance<T>[]) => boolean;
48
48
  canDrop?: (items: ItemInstance<T>[], target: DropTarget<T>) => boolean;
@@ -2,4 +2,4 @@ import { ItemInstance, TreeInstance } from "../../types/core";
2
2
  import { DropTarget } from "./types";
3
3
  export declare const canDrop: (dataTransfer: DataTransfer | null, target: DropTarget<any>, tree: TreeInstance<any>) => boolean;
4
4
  export declare const getDragCode: (e: any, item: ItemInstance<any>, tree: TreeInstance<any>) => string;
5
- export declare const getDropTarget: (e: any, item: ItemInstance<any>, tree: TreeInstance<any>, canDropInbetween?: boolean | undefined) => DropTarget<any>;
5
+ export declare const getDropTarget: (e: any, item: ItemInstance<any>, tree: TreeInstance<any>, canReorder?: boolean | undefined) => DropTarget<any>;
@@ -47,7 +47,7 @@ const getItemDropCategory = (item) => {
47
47
  const getTargetPlacement = (e, item, tree, canMakeChild) => {
48
48
  var _a, _b, _c;
49
49
  const config = tree.getConfig();
50
- if (!config.canDropInbetween) {
50
+ if (!config.canReorder) {
51
51
  return canMakeChild
52
52
  ? { type: PlacementType.MakeChild }
53
53
  : { type: PlacementType.ReorderBelow };
@@ -105,7 +105,7 @@ const getNthParent = (item, n) => {
105
105
  }
106
106
  return getNthParent(item.getParent(), n);
107
107
  };
108
- const getDropTarget = (e, item, tree, canDropInbetween = tree.getConfig().canDropInbetween) => {
108
+ const getDropTarget = (e, item, tree, canReorder = tree.getConfig().canReorder) => {
109
109
  var _a, _b, _c;
110
110
  const draggedItems = (_b = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems) !== null && _b !== void 0 ? _b : [];
111
111
  const itemMeta = item.getItemMeta();
@@ -129,13 +129,13 @@ const getDropTarget = (e, item, tree, canDropInbetween = tree.getConfig().canDro
129
129
  const canBecomeSibling = parentTarget && (0, exports.canDrop)(e.dataTransfer, parentTarget, tree);
130
130
  const canMakeChild = (0, exports.canDrop)(e.dataTransfer, itemTarget, tree);
131
131
  const placement = getTargetPlacement(e, item, tree, canMakeChild);
132
- if (!canDropInbetween &&
132
+ if (!canReorder &&
133
133
  parent &&
134
134
  canBecomeSibling &&
135
135
  placement.type !== PlacementType.MakeChild) {
136
136
  return parentTarget;
137
137
  }
138
- if (!canDropInbetween && parent && !canBecomeSibling) {
138
+ if (!canReorder && parent && !canBecomeSibling) {
139
139
  // TODO! this breaks in story DND/Can Drop. Maybe move this logic into a composable DropTargetStrategy[] ?
140
140
  return (0, exports.getDropTarget)(e, parent, tree, false);
141
141
  }
@@ -1,6 +1,2 @@
1
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>;
2
+ export declare const expandAllFeature: FeatureImplementation;
@@ -1,4 +1,2 @@
1
1
  import { FeatureImplementation } from "../../types/core";
2
- import { HotkeysCoreFeatureDef } from "./types";
3
- import { MainFeatureDef } from "../main/types";
4
- export declare const hotkeysCoreFeature: FeatureImplementation<any, HotkeysCoreFeatureDef<any>, MainFeatureDef | HotkeysCoreFeatureDef<any>>;
2
+ export declare const hotkeysCoreFeature: FeatureImplementation;
@@ -0,0 +1,2 @@
1
+ import { FeatureImplementation } from "../../types/core";
2
+ export declare const propMemoizationFeature: FeatureImplementation;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.propMemoizationFeature = void 0;
4
+ const memoize = (props, dataRef) => {
5
+ var _a;
6
+ (_a = dataRef.memoizedProps) !== null && _a !== void 0 ? _a : (dataRef.memoizedProps = {});
7
+ for (const key in props) {
8
+ if (typeof props[key] === "function") {
9
+ if (key in dataRef.memoizedProps) {
10
+ props[key] = dataRef.memoizedProps[key];
11
+ }
12
+ else {
13
+ dataRef.memoizedProps[key] = props[key];
14
+ }
15
+ }
16
+ }
17
+ return props;
18
+ };
19
+ exports.propMemoizationFeature = {
20
+ key: "prop-memoization",
21
+ overwrites: [
22
+ "main",
23
+ "async-data-loader",
24
+ "sync-data-loader",
25
+ "drag-and-drop",
26
+ "expand-all",
27
+ "hotkeys-core",
28
+ "renaming",
29
+ "search",
30
+ "selection",
31
+ ],
32
+ treeInstance: {
33
+ getContainerProps: ({ tree, prev }) => {
34
+ var _a;
35
+ const dataRef = tree.getDataRef();
36
+ const props = (_a = prev === null || prev === void 0 ? void 0 : prev()) !== null && _a !== void 0 ? _a : {};
37
+ return memoize(props, dataRef.current);
38
+ },
39
+ },
40
+ itemInstance: {
41
+ getProps: ({ item, prev }) => {
42
+ var _a;
43
+ const dataRef = item.getDataRef();
44
+ const props = (_a = prev === null || prev === void 0 ? void 0 : prev()) !== null && _a !== void 0 ? _a : {};
45
+ return memoize(props, dataRef.current);
46
+ },
47
+ },
48
+ };
@@ -0,0 +1,10 @@
1
+ export type PropMemoizationDataRef = {
2
+ memoizedProps?: Record<string, any>;
3
+ };
4
+ export type PropMemoizationFeatureDef = {
5
+ state: {};
6
+ config: {};
7
+ treeInstance: {};
8
+ itemInstance: {};
9
+ hotkeys: never;
10
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,5 +1,2 @@
1
1
  import { FeatureImplementation } from "../../types/core";
2
- import { RenamingFeatureDef } from "./types";
3
- import { MainFeatureDef } from "../main/types";
4
- import { TreeFeatureDef } from "../tree/types";
5
- export declare const renamingFeature: FeatureImplementation<any, RenamingFeatureDef<any>, MainFeatureDef | TreeFeatureDef<any> | RenamingFeatureDef<any>>;
2
+ export declare const renamingFeature: FeatureImplementation;
@@ -10,14 +10,6 @@ exports.renamingFeature = {
10
10
  renamingValue: "setRenamingValue",
11
11
  },
12
12
  treeInstance: {
13
- startRenamingItem: ({ tree }, itemId) => {
14
- const item = tree.getItemInstance(itemId);
15
- if (!item.canRename()) {
16
- return;
17
- }
18
- tree.applySubStateUpdate("renamingItem", itemId);
19
- tree.applySubStateUpdate("renamingValue", item.getItemName());
20
- },
21
13
  getRenamingItem: ({ tree }) => {
22
14
  const itemId = tree.getState().renamingItem;
23
15
  return itemId ? tree.getItemInstance(itemId) : null;
@@ -40,6 +32,13 @@ exports.renamingFeature = {
40
32
  isRenamingItem: ({ tree }) => !!tree.getState().renamingItem,
41
33
  },
42
34
  itemInstance: {
35
+ startRenaming: ({ tree, item, itemId }) => {
36
+ if (!item.canRename()) {
37
+ return;
38
+ }
39
+ tree.applySubStateUpdate("renamingItem", itemId);
40
+ tree.applySubStateUpdate("renamingValue", item.getItemName());
41
+ },
43
42
  getRenameInputProps: ({ tree }) => ({
44
43
  onBlur: () => tree.abortRenaming(),
45
44
  value: tree.getRenamingValue(),
@@ -56,7 +55,7 @@ exports.renamingFeature = {
56
55
  renameItem: {
57
56
  hotkey: "F2",
58
57
  handler: (e, tree) => {
59
- tree.startRenamingItem(tree.getFocusedItem().getId());
58
+ tree.getFocusedItem().startRenaming();
60
59
  },
61
60
  },
62
61
  abortRenaming: {
@@ -11,7 +11,6 @@ export type RenamingFeatureDef<T> = {
11
11
  onRename?: (item: ItemInstance<T>, value: string) => void;
12
12
  };
13
13
  treeInstance: {
14
- startRenamingItem: (itemId: string) => void;
15
14
  getRenamingItem: () => ItemInstance<T> | null;
16
15
  getRenamingValue: () => string;
17
16
  abortRenaming: () => void;
@@ -22,6 +21,7 @@ export type RenamingFeatureDef<T> = {
22
21
  getRenameInputProps: () => any;
23
22
  canRename: () => boolean;
24
23
  isRenaming: () => boolean;
24
+ startRenaming: () => void;
25
25
  };
26
26
  hotkeys: "renameItem" | "abortRenaming" | "completeRenaming";
27
27
  };
@@ -1,5 +1,2 @@
1
1
  import { FeatureImplementation } from "../../types/core";
2
- import { SearchFeatureDef } from "./types";
3
- import { MainFeatureDef } from "../main/types";
4
- import { TreeFeatureDef } from "../tree/types";
5
- export declare const searchFeature: FeatureImplementation<any, SearchFeatureDef<any>, MainFeatureDef | TreeFeatureDef<any> | SearchFeatureDef<any>>;
2
+ export declare const searchFeature: FeatureImplementation;
@@ -1,5 +1,2 @@
1
1
  import { FeatureImplementation } from "../../types/core";
2
- import { SelectionFeatureDef } from "./types";
3
- import { MainFeatureDef } from "../main/types";
4
- import { TreeFeatureDef } from "../tree/types";
5
- export declare const selectionFeature: FeatureImplementation<any, SelectionFeatureDef<any>, MainFeatureDef | TreeFeatureDef<any> | SelectionFeatureDef<any>>;
2
+ export declare const selectionFeature: FeatureImplementation;
@@ -19,15 +19,15 @@ exports.selectionFeature = {
19
19
  },
20
20
  },
21
21
  itemInstance: {
22
- select: ({ tree, item }) => {
22
+ select: ({ tree, itemId }) => {
23
23
  const { selectedItems } = tree.getState();
24
- tree.setSelectedItems(selectedItems.includes(item.getItemMeta().itemId)
24
+ tree.setSelectedItems(selectedItems.includes(itemId)
25
25
  ? selectedItems
26
- : [...selectedItems, item.getItemMeta().itemId]);
26
+ : [...selectedItems, itemId]);
27
27
  },
28
- deselect: ({ tree, item }) => {
28
+ deselect: ({ tree, itemId }) => {
29
29
  const { selectedItems } = tree.getState();
30
- tree.setSelectedItems(selectedItems.filter((id) => id !== item.getItemMeta().itemId));
30
+ tree.setSelectedItems(selectedItems.filter((id) => id !== itemId));
31
31
  },
32
32
  isSelected: ({ tree, item }) => {
33
33
  const { selectedItems } = tree.getState();
@@ -60,7 +60,7 @@ exports.selectionFeature = {
60
60
  item.select();
61
61
  }
62
62
  },
63
- getProps: ({ tree, item, prev }) => (Object.assign(Object.assign({}, prev === null || prev === void 0 ? void 0 : prev()), { "aria-selected": item.isSelected() ? "true" : "false", onClick: item.getMemoizedProp("selection/onClick", () => (e) => {
63
+ getProps: ({ tree, item, prev }) => (Object.assign(Object.assign({}, prev === null || prev === void 0 ? void 0 : prev()), { "aria-selected": item.isSelected() ? "true" : "false", onClick: (e) => {
64
64
  var _a, _b;
65
65
  if (e.shiftKey) {
66
66
  item.selectUpTo(e.ctrlKey || e.metaKey);
@@ -72,7 +72,7 @@ exports.selectionFeature = {
72
72
  tree.setSelectedItems([item.getItemMeta().itemId]);
73
73
  }
74
74
  (_b = (_a = prev === null || prev === void 0 ? void 0 : prev()) === null || _a === void 0 ? void 0 : _a.onClick) === null || _b === void 0 ? void 0 : _b.call(_a, e);
75
- }) })),
75
+ } })),
76
76
  },
77
77
  hotkeys: {
78
78
  // setSelectedItem: {
@@ -88,27 +88,37 @@ exports.selectionFeature = {
88
88
  },
89
89
  },
90
90
  selectUpwards: {
91
- hotkey: "shift+ArrowUp",
92
- handler: () => {
93
- // TODO
91
+ hotkey: "Shift+ArrowUp",
92
+ handler: (e, tree) => {
93
+ const focused = tree.getFocusedItem();
94
+ const above = focused.getItemAbove();
95
+ if (!above)
96
+ return;
97
+ if (focused.isSelected() && above.isSelected()) {
98
+ focused.deselect();
99
+ }
100
+ else {
101
+ above.select();
102
+ }
103
+ above.setFocused();
104
+ tree.updateDomFocus();
94
105
  },
95
106
  },
96
107
  selectDownwards: {
97
- hotkey: "shift+ArrowDown",
98
- handler: () => {
99
- // TODO
100
- },
101
- },
102
- selectUpwardsCtrl: {
103
- hotkey: "shift+ctrl+ArrowUp",
104
- handler: () => {
105
- // TODO
106
- },
107
- },
108
- selectDownwardsCtrl: {
109
- hotkey: "shift+ctrl+ArrowUp",
110
- handler: () => {
111
- // TODO
108
+ hotkey: "Shift+ArrowDown",
109
+ handler: (e, tree) => {
110
+ const focused = tree.getFocusedItem();
111
+ const below = focused.getItemBelow();
112
+ if (!below)
113
+ return;
114
+ if (focused.isSelected() && below.isSelected()) {
115
+ focused.deselect();
116
+ }
117
+ else {
118
+ below.select();
119
+ }
120
+ below.setFocused();
121
+ tree.updateDomFocus();
112
122
  },
113
123
  },
114
124
  selectAll: {
@@ -17,5 +17,5 @@ export type SelectionFeatureDef<T> = {
17
17
  isSelected: () => boolean;
18
18
  selectUpTo: (ctrl: boolean) => void;
19
19
  };
20
- hotkeys: "toggleSelectItem" | "selectUpwards" | "selectDownwards" | "selectUpwardsCtrl" | "selectDownwardsCtrl" | "selectAll";
20
+ hotkeys: "toggleSelectItem" | "selectUpwards" | "selectDownwards" | "selectAll";
21
21
  };
@@ -1,4 +1,2 @@
1
1
  import { FeatureImplementation } from "../../types/core";
2
- import { SyncDataLoaderFeatureDef } from "./types";
3
- import { MainFeatureDef } from "../main/types";
4
- export declare const syncDataLoaderFeature: FeatureImplementation<any, SyncDataLoaderFeatureDef<any>, MainFeatureDef | SyncDataLoaderFeatureDef<any>>;
2
+ export declare const syncDataLoaderFeature: FeatureImplementation;
@@ -1,7 +1,2 @@
1
1
  import { FeatureImplementation } from "../../types/core";
2
- import { TreeFeatureDef } from "./types";
3
- import { MainFeatureDef } from "../main/types";
4
- import { HotkeysCoreFeatureDef } from "../hotkeys-core/types";
5
- import { SyncDataLoaderFeatureDef } from "../sync-data-loader/types";
6
- import { SearchFeatureDef } from "../search/types";
7
- export declare const treeFeature: FeatureImplementation<any, TreeFeatureDef<any>, MainFeatureDef | TreeFeatureDef<any> | HotkeysCoreFeatureDef<any> | SyncDataLoaderFeatureDef<any> | SearchFeatureDef<any>>;
2
+ export declare const treeFeature: FeatureImplementation<any>;