@headless-tree/core 0.0.11 → 0.0.13

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 +12 -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
@@ -1,9 +1,9 @@
1
1
  import { canDrop, getDragCode, getDropTarget } from "./utils";
2
2
  import { makeStateUpdater } from "../../utils";
3
3
  export const dragAndDropFeature = {
4
- key: "dragAndDrop",
4
+ key: "drag-and-drop",
5
5
  deps: ["selection"],
6
- getDefaultConfig: (defaultConfig, tree) => (Object.assign({ canDrop: (_, target) => target.item.isFolder(), canDropForeignDragObject: () => false, setDndState: makeStateUpdater("dnd", tree), canDropInbetween: true }, defaultConfig)),
6
+ getDefaultConfig: (defaultConfig, tree) => (Object.assign({ canDrop: (_, target) => target.item.isFolder(), canDropForeignDragObject: () => false, setDndState: makeStateUpdater("dnd", tree), canReorder: true }, defaultConfig)),
7
7
  stateHandlerNames: {
8
8
  dnd: "setDndState",
9
9
  },
@@ -13,33 +13,33 @@ export const dragAndDropFeature = {
13
13
  return (_b = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.dragTarget) !== null && _b !== void 0 ? _b : null;
14
14
  },
15
15
  getDragLineData: ({ tree }) => {
16
- var _a, _b, _c, _d, _e;
17
- // TODO doesnt work if scrolled down!
16
+ var _a, _b, _c, _d, _e, _f;
18
17
  const target = tree.getDropTarget();
19
- 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
20
- if (!target || target.childIndex === null)
18
+ const indent = ((_a = target === null || target === void 0 ? void 0 : target.item.getItemMeta().level) !== null && _a !== void 0 ? _a : 0) + 1;
19
+ const treeBb = (_b = tree.getElement()) === null || _b === void 0 ? void 0 : _b.getBoundingClientRect();
20
+ if (!target || !treeBb || target.childIndex === null)
21
21
  return null;
22
- const leftOffset = target.dragLineLevel * ((_b = tree.getConfig().indent) !== null && _b !== void 0 ? _b : 1);
22
+ const leftOffset = target.dragLineLevel * ((_c = tree.getConfig().indent) !== null && _c !== void 0 ? _c : 1);
23
23
  const targetItem = tree.getItems()[target.dragLineIndex];
24
24
  if (!targetItem) {
25
- const bb = (_d = (_c = tree
26
- .getItems()[target.dragLineIndex - 1]) === null || _c === void 0 ? void 0 : _c.getElement()) === null || _d === void 0 ? void 0 : _d.getBoundingClientRect();
25
+ const bb = (_e = (_d = tree
26
+ .getItems()[target.dragLineIndex - 1]) === null || _d === void 0 ? void 0 : _d.getElement()) === null || _e === void 0 ? void 0 : _e.getBoundingClientRect();
27
27
  if (bb) {
28
28
  return {
29
29
  indent,
30
- top: bb.bottom,
31
- left: bb.left + leftOffset,
32
- right: bb.right,
30
+ top: bb.bottom - treeBb.bottom,
31
+ left: bb.left + leftOffset - treeBb.left,
32
+ width: bb.width - leftOffset,
33
33
  };
34
34
  }
35
35
  }
36
- const bb = (_e = targetItem.getElement()) === null || _e === void 0 ? void 0 : _e.getBoundingClientRect();
36
+ const bb = (_f = targetItem.getElement()) === null || _f === void 0 ? void 0 : _f.getBoundingClientRect();
37
37
  if (bb) {
38
38
  return {
39
39
  indent,
40
- top: bb.top,
41
- left: bb.left + leftOffset,
42
- right: bb.right,
40
+ top: bb.top - treeBb.top,
41
+ left: bb.left + leftOffset - treeBb.left,
42
+ width: bb.width - leftOffset,
43
43
  };
44
44
  }
45
45
  return null;
@@ -50,17 +50,20 @@ export const dragAndDropFeature = {
50
50
  ? {
51
51
  top: `${dragLine.top + topOffset}px`,
52
52
  left: `${dragLine.left + leftOffset}px`,
53
- width: `${dragLine.right - dragLine.left - leftOffset}px`,
53
+ width: `${dragLine.width - leftOffset}px`,
54
54
  pointerEvents: "none", // important to prevent capturing drag events
55
55
  }
56
56
  : { display: "none" };
57
57
  },
58
+ getContainerProps: ({ prev }) => {
59
+ const prevProps = prev === null || prev === void 0 ? void 0 : prev();
60
+ return Object.assign(Object.assign({}, prevProps), { style: Object.assign(Object.assign({}, prevProps === null || prevProps === void 0 ? void 0 : prevProps.style), { position: "relative" }) });
61
+ },
58
62
  },
59
63
  itemInstance: {
60
- // TODO instead of individual getMemoizedProp calls, use a wrapped getMemoizedProps or something (getProps: () => getMemoized({...})
61
64
  getProps: ({ tree, item, prev }) => {
62
65
  var _a, _b, _c;
63
- 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) => {
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: (e) => {
64
67
  var _a, _b, _c;
65
68
  const selectedItems = tree.getSelectedItems();
66
69
  const items = selectedItems.includes(item) ? selectedItems : [item];
@@ -80,7 +83,7 @@ export const dragAndDropFeature = {
80
83
  draggedItems: items,
81
84
  draggingOverItem: tree.getFocusedItem(),
82
85
  });
83
- }), onDragOver: item.getMemoizedProp("dnd/onDragOver", () => (e) => {
86
+ }, onDragOver: (e) => {
84
87
  var _a, _b, _c;
85
88
  const dataRef = tree.getDataRef();
86
89
  const nextDragCode = getDragCode(e, item, tree);
@@ -106,11 +109,11 @@ export const dragAndDropFeature = {
106
109
  tree.applySubStateUpdate("dnd", (state) => (Object.assign(Object.assign({}, state), { dragTarget: target, draggingOverItem: item })));
107
110
  dataRef.current.lastAllowDrop = true;
108
111
  e.preventDefault();
109
- }), onDragLeave: item.getMemoizedProp("dnd/onDragLeave", () => () => {
112
+ }, onDragLeave: () => {
110
113
  const dataRef = tree.getDataRef();
111
114
  dataRef.current.lastDragCode = "no-drag";
112
115
  tree.applySubStateUpdate("dnd", (state) => (Object.assign(Object.assign({}, state), { draggingOverItem: undefined, dragTarget: undefined })));
113
- }), onDragEnd: item.getMemoizedProp("dnd/onDragEnd", () => (e) => {
116
+ }, onDragEnd: (e) => {
114
117
  var _a, _b, _c, _d;
115
118
  const draggedItems = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems;
116
119
  tree.applySubStateUpdate("dnd", null);
@@ -118,7 +121,7 @@ export const dragAndDropFeature = {
118
121
  return;
119
122
  }
120
123
  (_d = (_c = tree.getConfig()).onCompleteForeignDrop) === null || _d === void 0 ? void 0 : _d.call(_c, draggedItems);
121
- }), onDrop: item.getMemoizedProp("dnd/onDrop", () => (e) => {
124
+ }, onDrop: (e) => {
122
125
  var _a, _b, _c;
123
126
  const dataRef = tree.getDataRef();
124
127
  const target = getDropTarget(e, item, tree);
@@ -137,7 +140,7 @@ export const dragAndDropFeature = {
137
140
  (_c = config.onDropForeignDragObject) === null || _c === void 0 ? void 0 : _c.call(config, e.dataTransfer, target);
138
141
  }
139
142
  // TODO rebuild tree?
140
- }) }));
143
+ } }));
141
144
  },
142
145
  isDropTarget: ({ tree, item }) => {
143
146
  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>;
@@ -43,7 +43,7 @@ const getItemDropCategory = (item) => {
43
43
  const getTargetPlacement = (e, item, tree, canMakeChild) => {
44
44
  var _a, _b, _c;
45
45
  const config = tree.getConfig();
46
- if (!config.canDropInbetween) {
46
+ if (!config.canReorder) {
47
47
  return canMakeChild
48
48
  ? { type: PlacementType.MakeChild }
49
49
  : { type: PlacementType.ReorderBelow };
@@ -100,7 +100,7 @@ const getNthParent = (item, n) => {
100
100
  }
101
101
  return getNthParent(item.getParent(), n);
102
102
  };
103
- export const getDropTarget = (e, item, tree, canDropInbetween = tree.getConfig().canDropInbetween) => {
103
+ export const getDropTarget = (e, item, tree, canReorder = tree.getConfig().canReorder) => {
104
104
  var _a, _b, _c;
105
105
  const draggedItems = (_b = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems) !== null && _b !== void 0 ? _b : [];
106
106
  const itemMeta = item.getItemMeta();
@@ -124,13 +124,13 @@ export const getDropTarget = (e, item, tree, canDropInbetween = tree.getConfig()
124
124
  const canBecomeSibling = parentTarget && canDrop(e.dataTransfer, parentTarget, tree);
125
125
  const canMakeChild = canDrop(e.dataTransfer, itemTarget, tree);
126
126
  const placement = getTargetPlacement(e, item, tree, canMakeChild);
127
- if (!canDropInbetween &&
127
+ if (!canReorder &&
128
128
  parent &&
129
129
  canBecomeSibling &&
130
130
  placement.type !== PlacementType.MakeChild) {
131
131
  return parentTarget;
132
132
  }
133
- if (!canDropInbetween && parent && !canBecomeSibling) {
133
+ if (!canReorder && parent && !canBecomeSibling) {
134
134
  // TODO! this breaks in story DND/Can Drop. Maybe move this logic into a composable DropTargetStrategy[] ?
135
135
  return getDropTarget(e, parent, tree, false);
136
136
  }
@@ -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,45 @@
1
+ const memoize = (props, dataRef) => {
2
+ var _a;
3
+ (_a = dataRef.memoizedProps) !== null && _a !== void 0 ? _a : (dataRef.memoizedProps = {});
4
+ for (const key in props) {
5
+ if (typeof props[key] === "function") {
6
+ if (key in dataRef.memoizedProps) {
7
+ props[key] = dataRef.memoizedProps[key];
8
+ }
9
+ else {
10
+ dataRef.memoizedProps[key] = props[key];
11
+ }
12
+ }
13
+ }
14
+ return props;
15
+ };
16
+ export const propMemoizationFeature = {
17
+ key: "prop-memoization",
18
+ overwrites: [
19
+ "main",
20
+ "async-data-loader",
21
+ "sync-data-loader",
22
+ "drag-and-drop",
23
+ "expand-all",
24
+ "hotkeys-core",
25
+ "renaming",
26
+ "search",
27
+ "selection",
28
+ ],
29
+ treeInstance: {
30
+ getContainerProps: ({ tree, prev }) => {
31
+ var _a;
32
+ const dataRef = tree.getDataRef();
33
+ const props = (_a = prev === null || prev === void 0 ? void 0 : prev()) !== null && _a !== void 0 ? _a : {};
34
+ return memoize(props, dataRef.current);
35
+ },
36
+ },
37
+ itemInstance: {
38
+ getProps: ({ item, prev }) => {
39
+ var _a;
40
+ const dataRef = item.getDataRef();
41
+ const props = (_a = prev === null || prev === void 0 ? void 0 : prev()) !== null && _a !== void 0 ? _a : {};
42
+ return memoize(props, dataRef.current);
43
+ },
44
+ },
45
+ };
@@ -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 @@
1
+ export {};
@@ -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;
@@ -7,14 +7,6 @@ export const renamingFeature = {
7
7
  renamingValue: "setRenamingValue",
8
8
  },
9
9
  treeInstance: {
10
- startRenamingItem: ({ tree }, itemId) => {
11
- const item = tree.getItemInstance(itemId);
12
- if (!item.canRename()) {
13
- return;
14
- }
15
- tree.applySubStateUpdate("renamingItem", itemId);
16
- tree.applySubStateUpdate("renamingValue", item.getItemName());
17
- },
18
10
  getRenamingItem: ({ tree }) => {
19
11
  const itemId = tree.getState().renamingItem;
20
12
  return itemId ? tree.getItemInstance(itemId) : null;
@@ -37,6 +29,13 @@ export const renamingFeature = {
37
29
  isRenamingItem: ({ tree }) => !!tree.getState().renamingItem,
38
30
  },
39
31
  itemInstance: {
32
+ startRenaming: ({ tree, item, itemId }) => {
33
+ if (!item.canRename()) {
34
+ return;
35
+ }
36
+ tree.applySubStateUpdate("renamingItem", itemId);
37
+ tree.applySubStateUpdate("renamingValue", item.getItemName());
38
+ },
40
39
  getRenameInputProps: ({ tree }) => ({
41
40
  onBlur: () => tree.abortRenaming(),
42
41
  value: tree.getRenamingValue(),
@@ -53,7 +52,7 @@ export const renamingFeature = {
53
52
  renameItem: {
54
53
  hotkey: "F2",
55
54
  handler: (e, tree) => {
56
- tree.startRenamingItem(tree.getFocusedItem().getId());
55
+ tree.getFocusedItem().startRenaming();
57
56
  },
58
57
  },
59
58
  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;
@@ -16,15 +16,15 @@ export const selectionFeature = {
16
16
  },
17
17
  },
18
18
  itemInstance: {
19
- select: ({ tree, item }) => {
19
+ select: ({ tree, itemId }) => {
20
20
  const { selectedItems } = tree.getState();
21
- tree.setSelectedItems(selectedItems.includes(item.getItemMeta().itemId)
21
+ tree.setSelectedItems(selectedItems.includes(itemId)
22
22
  ? selectedItems
23
- : [...selectedItems, item.getItemMeta().itemId]);
23
+ : [...selectedItems, itemId]);
24
24
  },
25
- deselect: ({ tree, item }) => {
25
+ deselect: ({ tree, itemId }) => {
26
26
  const { selectedItems } = tree.getState();
27
- tree.setSelectedItems(selectedItems.filter((id) => id !== item.getItemMeta().itemId));
27
+ tree.setSelectedItems(selectedItems.filter((id) => id !== itemId));
28
28
  },
29
29
  isSelected: ({ tree, item }) => {
30
30
  const { selectedItems } = tree.getState();
@@ -57,7 +57,7 @@ export const selectionFeature = {
57
57
  item.select();
58
58
  }
59
59
  },
60
- 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) => {
60
+ getProps: ({ tree, item, prev }) => (Object.assign(Object.assign({}, prev === null || prev === void 0 ? void 0 : prev()), { "aria-selected": item.isSelected() ? "true" : "false", onClick: (e) => {
61
61
  var _a, _b;
62
62
  if (e.shiftKey) {
63
63
  item.selectUpTo(e.ctrlKey || e.metaKey);
@@ -69,7 +69,7 @@ export const selectionFeature = {
69
69
  tree.setSelectedItems([item.getItemMeta().itemId]);
70
70
  }
71
71
  (_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);
72
- }) })),
72
+ } })),
73
73
  },
74
74
  hotkeys: {
75
75
  // setSelectedItem: {
@@ -85,27 +85,37 @@ export const selectionFeature = {
85
85
  },
86
86
  },
87
87
  selectUpwards: {
88
- hotkey: "shift+ArrowUp",
89
- handler: () => {
90
- // TODO
88
+ hotkey: "Shift+ArrowUp",
89
+ handler: (e, tree) => {
90
+ const focused = tree.getFocusedItem();
91
+ const above = focused.getItemAbove();
92
+ if (!above)
93
+ return;
94
+ if (focused.isSelected() && above.isSelected()) {
95
+ focused.deselect();
96
+ }
97
+ else {
98
+ above.select();
99
+ }
100
+ above.setFocused();
101
+ tree.updateDomFocus();
91
102
  },
92
103
  },
93
104
  selectDownwards: {
94
- hotkey: "shift+ArrowDown",
95
- handler: () => {
96
- // TODO
97
- },
98
- },
99
- selectUpwardsCtrl: {
100
- hotkey: "shift+ctrl+ArrowUp",
101
- handler: () => {
102
- // TODO
103
- },
104
- },
105
- selectDownwardsCtrl: {
106
- hotkey: "shift+ctrl+ArrowUp",
107
- handler: () => {
108
- // TODO
105
+ hotkey: "Shift+ArrowDown",
106
+ handler: (e, tree) => {
107
+ const focused = tree.getFocusedItem();
108
+ const below = focused.getItemBelow();
109
+ if (!below)
110
+ return;
111
+ if (focused.isSelected() && below.isSelected()) {
112
+ focused.deselect();
113
+ }
114
+ else {
115
+ below.select();
116
+ }
117
+ below.setFocused();
118
+ tree.updateDomFocus();
109
119
  },
110
120
  },
111
121
  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>;