@headless-tree/core 0.0.14 → 1.0.0
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.
- package/CHANGELOG.md +13 -0
- package/lib/cjs/core/create-tree.js +13 -4
- package/lib/cjs/features/async-data-loader/feature.js +73 -48
- package/lib/cjs/features/async-data-loader/types.d.ts +17 -14
- package/lib/cjs/features/drag-and-drop/feature.js +98 -93
- package/lib/cjs/features/drag-and-drop/types.d.ts +17 -29
- package/lib/cjs/features/drag-and-drop/types.js +7 -7
- package/lib/cjs/features/drag-and-drop/utils.d.ts +25 -3
- package/lib/cjs/features/drag-and-drop/utils.js +51 -51
- package/lib/cjs/features/expand-all/feature.js +26 -3
- package/lib/cjs/features/expand-all/types.d.ts +3 -1
- package/lib/cjs/features/hotkeys-core/feature.js +7 -3
- package/lib/cjs/features/hotkeys-core/types.d.ts +4 -5
- package/lib/cjs/features/keyboard-drag-and-drop/feature.d.ts +2 -0
- package/lib/cjs/features/keyboard-drag-and-drop/feature.js +206 -0
- package/lib/cjs/features/keyboard-drag-and-drop/types.d.ts +27 -0
- package/lib/cjs/features/keyboard-drag-and-drop/types.js +11 -0
- package/lib/cjs/features/prop-memoization/feature.js +33 -11
- package/lib/cjs/features/prop-memoization/types.d.ts +8 -3
- package/lib/cjs/features/renaming/feature.js +1 -1
- package/lib/cjs/features/search/feature.js +2 -0
- package/lib/cjs/features/search/types.d.ts +2 -2
- package/lib/cjs/features/selection/feature.js +4 -4
- package/lib/cjs/features/selection/types.d.ts +1 -1
- package/lib/cjs/features/sync-data-loader/feature.js +31 -5
- package/lib/cjs/features/sync-data-loader/types.d.ts +5 -5
- package/lib/cjs/features/tree/feature.js +4 -9
- package/lib/cjs/features/tree/types.d.ts +7 -5
- package/lib/cjs/index.d.ts +2 -0
- package/lib/cjs/index.js +2 -0
- package/lib/cjs/mddocs-entry.d.ts +10 -0
- package/lib/cjs/test-utils/test-tree-do.d.ts +2 -2
- package/lib/cjs/test-utils/test-tree-do.js +19 -6
- package/lib/cjs/test-utils/test-tree-expect.d.ts +5 -3
- package/lib/cjs/test-utils/test-tree-expect.js +3 -0
- package/lib/cjs/test-utils/test-tree.d.ts +2 -1
- package/lib/cjs/test-utils/test-tree.js +24 -21
- package/lib/cjs/types/core.d.ts +2 -1
- package/lib/cjs/utilities/create-on-drop-handler.d.ts +2 -2
- package/lib/cjs/utilities/create-on-drop-handler.js +13 -4
- package/lib/cjs/utilities/insert-items-at-target.d.ts +2 -2
- package/lib/cjs/utilities/insert-items-at-target.js +21 -12
- package/lib/cjs/utilities/remove-items-from-parents.d.ts +1 -1
- package/lib/cjs/utilities/remove-items-from-parents.js +12 -3
- package/lib/esm/core/create-tree.js +13 -4
- package/lib/esm/features/async-data-loader/feature.js +73 -48
- package/lib/esm/features/async-data-loader/types.d.ts +17 -14
- package/lib/esm/features/drag-and-drop/feature.js +99 -94
- package/lib/esm/features/drag-and-drop/types.d.ts +17 -29
- package/lib/esm/features/drag-and-drop/types.js +6 -6
- package/lib/esm/features/drag-and-drop/utils.d.ts +25 -3
- package/lib/esm/features/drag-and-drop/utils.js +45 -49
- package/lib/esm/features/expand-all/feature.js +26 -3
- package/lib/esm/features/expand-all/types.d.ts +3 -1
- package/lib/esm/features/hotkeys-core/feature.js +7 -3
- package/lib/esm/features/hotkeys-core/types.d.ts +4 -5
- package/lib/esm/features/keyboard-drag-and-drop/feature.d.ts +2 -0
- package/lib/esm/features/keyboard-drag-and-drop/feature.js +203 -0
- package/lib/esm/features/keyboard-drag-and-drop/types.d.ts +27 -0
- package/lib/esm/features/keyboard-drag-and-drop/types.js +8 -0
- package/lib/esm/features/prop-memoization/feature.js +33 -11
- package/lib/esm/features/prop-memoization/types.d.ts +8 -3
- package/lib/esm/features/renaming/feature.js +1 -1
- package/lib/esm/features/search/feature.js +2 -0
- package/lib/esm/features/search/types.d.ts +2 -2
- package/lib/esm/features/selection/feature.js +4 -4
- package/lib/esm/features/selection/types.d.ts +1 -1
- package/lib/esm/features/sync-data-loader/feature.js +31 -5
- package/lib/esm/features/sync-data-loader/types.d.ts +5 -5
- package/lib/esm/features/tree/feature.js +4 -9
- package/lib/esm/features/tree/types.d.ts +7 -5
- package/lib/esm/index.d.ts +2 -0
- package/lib/esm/index.js +2 -0
- package/lib/esm/mddocs-entry.d.ts +10 -0
- package/lib/esm/test-utils/test-tree-do.d.ts +2 -2
- package/lib/esm/test-utils/test-tree-do.js +19 -6
- package/lib/esm/test-utils/test-tree-expect.d.ts +5 -3
- package/lib/esm/test-utils/test-tree-expect.js +3 -0
- package/lib/esm/test-utils/test-tree.d.ts +2 -1
- package/lib/esm/test-utils/test-tree.js +24 -21
- package/lib/esm/types/core.d.ts +2 -1
- package/lib/esm/utilities/create-on-drop-handler.d.ts +2 -2
- package/lib/esm/utilities/create-on-drop-handler.js +13 -4
- package/lib/esm/utilities/insert-items-at-target.d.ts +2 -2
- package/lib/esm/utilities/insert-items-at-target.js +21 -12
- package/lib/esm/utilities/remove-items-from-parents.d.ts +1 -1
- package/lib/esm/utilities/remove-items-from-parents.js +12 -3
- package/package.json +2 -2
- package/src/core/core.spec.ts +31 -0
- package/src/core/create-tree.ts +15 -5
- package/src/features/async-data-loader/async-data-loader.spec.ts +10 -6
- package/src/features/async-data-loader/feature.ts +76 -48
- package/src/features/async-data-loader/types.ts +18 -11
- package/src/features/drag-and-drop/drag-and-drop.spec.ts +75 -89
- package/src/features/drag-and-drop/feature.ts +26 -22
- package/src/features/drag-and-drop/types.ts +23 -35
- package/src/features/drag-and-drop/utils.ts +70 -57
- package/src/features/expand-all/feature.ts +29 -5
- package/src/features/expand-all/types.ts +3 -1
- package/src/features/hotkeys-core/feature.ts +4 -0
- package/src/features/hotkeys-core/types.ts +4 -13
- package/src/features/keyboard-drag-and-drop/feature.ts +255 -0
- package/src/features/keyboard-drag-and-drop/keyboard-drag-and-drop.spec.ts +402 -0
- package/src/features/keyboard-drag-and-drop/types.ts +30 -0
- package/src/features/prop-memoization/feature.ts +27 -8
- package/src/features/prop-memoization/prop-memoization.spec.ts +2 -2
- package/src/features/prop-memoization/types.ts +8 -3
- package/src/features/renaming/feature.ts +8 -2
- package/src/features/search/feature.ts +2 -0
- package/src/features/search/types.ts +2 -2
- package/src/features/selection/feature.ts +4 -4
- package/src/features/selection/types.ts +1 -1
- package/src/features/sync-data-loader/feature.ts +26 -7
- package/src/features/sync-data-loader/types.ts +5 -5
- package/src/features/tree/feature.ts +8 -13
- package/src/features/tree/types.ts +7 -5
- package/src/index.ts +2 -0
- package/src/mddocs-entry.ts +16 -0
- package/src/test-utils/test-tree-do.ts +3 -3
- package/src/test-utils/test-tree-expect.ts +7 -2
- package/src/test-utils/test-tree.ts +26 -22
- package/src/types/core.ts +2 -0
- package/src/utilities/create-on-drop-handler.ts +4 -4
- package/src/utilities/insert-items-at-target.ts +18 -14
- package/src/utilities/remove-items-from-parents.ts +6 -3
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
import { ItemInstance, TreeInstance } from "../../types/core";
|
|
2
|
-
import {
|
|
3
|
-
export declare
|
|
2
|
+
import { DragTarget } from "./types";
|
|
3
|
+
export declare enum ItemDropCategory {
|
|
4
|
+
Item = 0,
|
|
5
|
+
ExpandedFolder = 1,
|
|
6
|
+
LastInGroup = 2
|
|
7
|
+
}
|
|
8
|
+
export declare const isOrderedDragTarget: <T>(dragTarget: DragTarget<T>) => dragTarget is {
|
|
9
|
+
item: ItemInstance<T>;
|
|
10
|
+
childIndex: number;
|
|
11
|
+
insertionIndex: number;
|
|
12
|
+
dragLineIndex: number;
|
|
13
|
+
dragLineLevel: number;
|
|
14
|
+
};
|
|
15
|
+
export declare const canDrop: (dataTransfer: DataTransfer | null, target: DragTarget<any>, tree: TreeInstance<any>) => boolean;
|
|
16
|
+
export declare const getItemDropCategory: (item: ItemInstance<any>) => ItemDropCategory;
|
|
17
|
+
export declare const getInsertionIndex: <T>(children: ItemInstance<T>[], childIndex: number, draggedItems: ItemInstance<T>[] | undefined) => number;
|
|
4
18
|
export declare const getDragCode: (e: any, item: ItemInstance<any>, tree: TreeInstance<any>) => string;
|
|
5
|
-
|
|
19
|
+
/** @param item refers to the bottom-most item of the container, at which bottom is being reparented on (e.g. root-1-2-6) */
|
|
20
|
+
export declare const getReparentTarget: <T>(item: ItemInstance<T>, reparentLevel: number, draggedItems: ItemInstance<T>[] | undefined) => {
|
|
21
|
+
item: ItemInstance<any>;
|
|
22
|
+
childIndex: number;
|
|
23
|
+
insertionIndex: number;
|
|
24
|
+
dragLineIndex: number;
|
|
25
|
+
dragLineLevel: number;
|
|
26
|
+
};
|
|
27
|
+
export declare const getDragTarget: (e: any, item: ItemInstance<any>, tree: TreeInstance<any>, canReorder?: boolean | undefined) => DragTarget<any>;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.getDragTarget = exports.getReparentTarget = exports.getDragCode = exports.getInsertionIndex = exports.getItemDropCategory = exports.canDrop = exports.isOrderedDragTarget = exports.ItemDropCategory = void 0;
|
|
4
4
|
var ItemDropCategory;
|
|
5
5
|
(function (ItemDropCategory) {
|
|
6
6
|
ItemDropCategory[ItemDropCategory["Item"] = 0] = "Item";
|
|
7
7
|
ItemDropCategory[ItemDropCategory["ExpandedFolder"] = 1] = "ExpandedFolder";
|
|
8
8
|
ItemDropCategory[ItemDropCategory["LastInGroup"] = 2] = "LastInGroup";
|
|
9
|
-
})(ItemDropCategory || (ItemDropCategory = {}));
|
|
9
|
+
})(ItemDropCategory || (exports.ItemDropCategory = ItemDropCategory = {}));
|
|
10
10
|
var PlacementType;
|
|
11
11
|
(function (PlacementType) {
|
|
12
12
|
PlacementType[PlacementType["ReorderAbove"] = 0] = "ReorderAbove";
|
|
@@ -14,8 +14,10 @@ var PlacementType;
|
|
|
14
14
|
PlacementType[PlacementType["MakeChild"] = 2] = "MakeChild";
|
|
15
15
|
PlacementType[PlacementType["Reparent"] = 3] = "Reparent";
|
|
16
16
|
})(PlacementType || (PlacementType = {}));
|
|
17
|
+
const isOrderedDragTarget = (dragTarget) => "childIndex" in dragTarget;
|
|
18
|
+
exports.isOrderedDragTarget = isOrderedDragTarget;
|
|
17
19
|
const canDrop = (dataTransfer, target, tree) => {
|
|
18
|
-
var _a, _b, _c
|
|
20
|
+
var _a, _b, _c;
|
|
19
21
|
const draggedItems = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems;
|
|
20
22
|
const config = tree.getConfig();
|
|
21
23
|
if (draggedItems && !((_c = (_b = config.canDrop) === null || _b === void 0 ? void 0 : _b.call(config, draggedItems, target)) !== null && _c !== void 0 ? _c : true)) {
|
|
@@ -28,7 +30,8 @@ const canDrop = (dataTransfer, target, tree) => {
|
|
|
28
30
|
}
|
|
29
31
|
if (!draggedItems &&
|
|
30
32
|
dataTransfer &&
|
|
31
|
-
|
|
33
|
+
config.canDropForeignDragObject &&
|
|
34
|
+
!config.canDropForeignDragObject(dataTransfer, target)) {
|
|
32
35
|
return false;
|
|
33
36
|
}
|
|
34
37
|
return true;
|
|
@@ -39,13 +42,24 @@ const getItemDropCategory = (item) => {
|
|
|
39
42
|
return ItemDropCategory.ExpandedFolder;
|
|
40
43
|
}
|
|
41
44
|
const parent = item.getParent();
|
|
42
|
-
if (parent && item.getIndexInParent() ===
|
|
45
|
+
if (parent && item.getIndexInParent() === item.getItemMeta().setSize - 1) {
|
|
43
46
|
return ItemDropCategory.LastInGroup;
|
|
44
47
|
}
|
|
45
48
|
return ItemDropCategory.Item;
|
|
46
49
|
};
|
|
50
|
+
exports.getItemDropCategory = getItemDropCategory;
|
|
51
|
+
const getInsertionIndex = (children, childIndex, draggedItems) => {
|
|
52
|
+
var _a;
|
|
53
|
+
const numberOfDragItemsBeforeTarget = (_a = children
|
|
54
|
+
.slice(0, childIndex)
|
|
55
|
+
.reduce((counter, child) => child && (draggedItems === null || draggedItems === void 0 ? void 0 : draggedItems.some((i) => i.getId() === child.getId()))
|
|
56
|
+
? ++counter
|
|
57
|
+
: counter, 0)) !== null && _a !== void 0 ? _a : 0;
|
|
58
|
+
return childIndex - numberOfDragItemsBeforeTarget;
|
|
59
|
+
};
|
|
60
|
+
exports.getInsertionIndex = getInsertionIndex;
|
|
47
61
|
const getTargetPlacement = (e, item, tree, canMakeChild) => {
|
|
48
|
-
var _a, _b, _c;
|
|
62
|
+
var _a, _b, _c, _d, _e;
|
|
49
63
|
const config = tree.getConfig();
|
|
50
64
|
if (!config.canReorder) {
|
|
51
65
|
return canMakeChild
|
|
@@ -53,9 +67,9 @@ const getTargetPlacement = (e, item, tree, canMakeChild) => {
|
|
|
53
67
|
: { type: PlacementType.ReorderBelow };
|
|
54
68
|
}
|
|
55
69
|
const bb = (_a = item.getElement()) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
|
|
56
|
-
const topPercent = bb ? (e.
|
|
57
|
-
const leftPixels = bb ? e.
|
|
58
|
-
const targetDropCategory = getItemDropCategory(item);
|
|
70
|
+
const topPercent = bb ? (e.clientY - bb.top) / bb.height : 0.5;
|
|
71
|
+
const leftPixels = bb ? e.clientX - bb.left : 0;
|
|
72
|
+
const targetDropCategory = (0, exports.getItemDropCategory)(item);
|
|
59
73
|
const reorderAreaPercentage = !canMakeChild
|
|
60
74
|
? 0.5
|
|
61
75
|
: (_b = config.reorderAreaPercentage) !== null && _b !== void 0 ? _b : 0.3;
|
|
@@ -74,9 +88,10 @@ const getTargetPlacement = (e, item, tree, canMakeChild) => {
|
|
|
74
88
|
if (topPercent < 0.5) {
|
|
75
89
|
return { type: PlacementType.ReorderAbove };
|
|
76
90
|
}
|
|
91
|
+
const minLevel = (_e = (_d = item.getItemBelow()) === null || _d === void 0 ? void 0 : _d.getItemMeta().level) !== null && _e !== void 0 ? _e : 0;
|
|
77
92
|
return {
|
|
78
93
|
type: PlacementType.Reparent,
|
|
79
|
-
reparentLevel: Math.floor(leftPixels / indent),
|
|
94
|
+
reparentLevel: Math.max(minLevel, Math.floor(leftPixels / indent)),
|
|
80
95
|
};
|
|
81
96
|
}
|
|
82
97
|
// if not at left of item area, treat as if it was a normal item
|
|
@@ -105,27 +120,28 @@ const getNthParent = (item, n) => {
|
|
|
105
120
|
}
|
|
106
121
|
return getNthParent(item.getParent(), n);
|
|
107
122
|
};
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
const draggedItems = (_b = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems) !== null && _b !== void 0 ? _b : [];
|
|
123
|
+
/** @param item refers to the bottom-most item of the container, at which bottom is being reparented on (e.g. root-1-2-6) */
|
|
124
|
+
const getReparentTarget = (item, reparentLevel, draggedItems) => {
|
|
111
125
|
const itemMeta = item.getItemMeta();
|
|
112
|
-
const
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
126
|
+
const reparentedTarget = getNthParent(item, reparentLevel - 1);
|
|
127
|
+
const targetItemAbove = getNthParent(item, reparentLevel); // .getItemBelow()!;
|
|
128
|
+
const targetIndex = targetItemAbove.getIndexInParent() + 1;
|
|
129
|
+
return {
|
|
130
|
+
item: reparentedTarget,
|
|
131
|
+
childIndex: targetIndex,
|
|
132
|
+
insertionIndex: (0, exports.getInsertionIndex)(reparentedTarget.getChildren(), targetIndex, draggedItems),
|
|
133
|
+
dragLineIndex: itemMeta.index + 1,
|
|
134
|
+
dragLineLevel: reparentLevel,
|
|
119
135
|
};
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
136
|
+
};
|
|
137
|
+
exports.getReparentTarget = getReparentTarget;
|
|
138
|
+
const getDragTarget = (e, item, tree, canReorder = tree.getConfig().canReorder) => {
|
|
139
|
+
var _a;
|
|
140
|
+
const draggedItems = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems;
|
|
141
|
+
const itemMeta = item.getItemMeta();
|
|
142
|
+
const parent = item.getParent();
|
|
143
|
+
const itemTarget = { item };
|
|
144
|
+
const parentTarget = parent ? { item: parent } : null;
|
|
129
145
|
const canBecomeSibling = parentTarget && (0, exports.canDrop)(e.dataTransfer, parentTarget, tree);
|
|
130
146
|
const canMakeChild = (0, exports.canDrop)(e.dataTransfer, itemTarget, tree);
|
|
131
147
|
const placement = getTargetPlacement(e, item, tree, canMakeChild);
|
|
@@ -136,8 +152,8 @@ const getDropTarget = (e, item, tree, canReorder = tree.getConfig().canReorder)
|
|
|
136
152
|
return parentTarget;
|
|
137
153
|
}
|
|
138
154
|
if (!canReorder && parent && !canBecomeSibling) {
|
|
139
|
-
// TODO! this breaks in story DND/Can Drop. Maybe move this logic into a composable
|
|
140
|
-
return (0, exports.
|
|
155
|
+
// TODO! this breaks in story DND/Can Drop. Maybe move this logic into a composable DragTargetStrategy[] ?
|
|
156
|
+
return (0, exports.getDragTarget)(e, parent, tree, false);
|
|
141
157
|
}
|
|
142
158
|
if (!parent) {
|
|
143
159
|
// Shouldn't happen, but if dropped "next" to root item, just drop it inside
|
|
@@ -147,36 +163,20 @@ const getDropTarget = (e, item, tree, canReorder = tree.getConfig().canReorder)
|
|
|
147
163
|
return itemTarget;
|
|
148
164
|
}
|
|
149
165
|
if (!canBecomeSibling) {
|
|
150
|
-
return (0, exports.
|
|
166
|
+
return (0, exports.getDragTarget)(e, parent, tree, false);
|
|
151
167
|
}
|
|
152
168
|
if (placement.type === PlacementType.Reparent) {
|
|
153
|
-
|
|
154
|
-
const targetItemAbove = getNthParent(item, placement.reparentLevel); // .getItemBelow()!;
|
|
155
|
-
const targetIndex = targetItemAbove.getIndexInParent() + 1;
|
|
156
|
-
// TODO possibly count items dragged out above the new target
|
|
157
|
-
return {
|
|
158
|
-
item: reparentedTarget,
|
|
159
|
-
childIndex: targetIndex,
|
|
160
|
-
insertionIndex: targetIndex,
|
|
161
|
-
dragLineIndex: itemMeta.index + 1,
|
|
162
|
-
dragLineLevel: placement.reparentLevel,
|
|
163
|
-
};
|
|
169
|
+
return (0, exports.getReparentTarget)(item, placement.reparentLevel, draggedItems);
|
|
164
170
|
}
|
|
165
171
|
const maybeAddOneForBelow = placement.type === PlacementType.ReorderAbove ? 0 : 1;
|
|
166
172
|
const childIndex = item.getIndexInParent() + maybeAddOneForBelow;
|
|
167
|
-
const numberOfDragItemsBeforeTarget = (_c = parent
|
|
168
|
-
.getChildren()
|
|
169
|
-
.slice(0, childIndex)
|
|
170
|
-
.reduce((counter, child) => child && (draggedItems === null || draggedItems === void 0 ? void 0 : draggedItems.some((i) => i.getId() === child.getId()))
|
|
171
|
-
? ++counter
|
|
172
|
-
: counter, 0)) !== null && _c !== void 0 ? _c : 0;
|
|
173
173
|
return {
|
|
174
174
|
item: parent,
|
|
175
175
|
dragLineIndex: itemMeta.index + maybeAddOneForBelow,
|
|
176
176
|
dragLineLevel: itemMeta.level,
|
|
177
177
|
childIndex,
|
|
178
178
|
// TODO performance could be improved by computing this only when dragcode changed
|
|
179
|
-
insertionIndex:
|
|
179
|
+
insertionIndex: (0, exports.getInsertionIndex)(parent.getChildren(), childIndex, draggedItems),
|
|
180
180
|
};
|
|
181
181
|
};
|
|
182
|
-
exports.
|
|
182
|
+
exports.getDragTarget = getDragTarget;
|
|
@@ -10,7 +10,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.expandAllFeature = void 0;
|
|
13
|
-
const utils_1 = require("../../utils");
|
|
14
13
|
exports.expandAllFeature = {
|
|
15
14
|
key: "expand-all",
|
|
16
15
|
treeInstance: {
|
|
@@ -31,17 +30,41 @@ exports.expandAllFeature = {
|
|
|
31
30
|
return;
|
|
32
31
|
}
|
|
33
32
|
item.expand();
|
|
34
|
-
yield
|
|
33
|
+
yield tree.waitForItemChildrenLoaded(item.getId());
|
|
35
34
|
yield Promise.all(item.getChildren().map((child) => __awaiter(void 0, void 0, void 0, function* () {
|
|
36
|
-
yield
|
|
35
|
+
yield tree.waitForItemChildrenLoaded(item.getId());
|
|
37
36
|
yield (child === null || child === void 0 ? void 0 : child.expandAll(cancelToken));
|
|
38
37
|
})));
|
|
39
38
|
}),
|
|
40
39
|
collapseAll: ({ item }) => {
|
|
40
|
+
if (!item.isExpanded())
|
|
41
|
+
return;
|
|
41
42
|
for (const child of item.getChildren()) {
|
|
42
43
|
child === null || child === void 0 ? void 0 : child.collapseAll();
|
|
43
44
|
}
|
|
44
45
|
item.collapse();
|
|
45
46
|
},
|
|
46
47
|
},
|
|
48
|
+
hotkeys: {
|
|
49
|
+
expandSelected: {
|
|
50
|
+
hotkey: "Control+Shift+Plus",
|
|
51
|
+
handler: (_, tree) => __awaiter(void 0, void 0, void 0, function* () {
|
|
52
|
+
const cancelToken = { current: false };
|
|
53
|
+
const cancelHandler = (e) => {
|
|
54
|
+
if (e.key === "Escape") {
|
|
55
|
+
cancelToken.current = true;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
document.addEventListener("keydown", cancelHandler);
|
|
59
|
+
yield Promise.all(tree.getSelectedItems().map((item) => item.expandAll(cancelToken)));
|
|
60
|
+
document.removeEventListener("keydown", cancelHandler);
|
|
61
|
+
}),
|
|
62
|
+
},
|
|
63
|
+
collapseSelected: {
|
|
64
|
+
hotkey: "Control+Shift+-",
|
|
65
|
+
handler: (_, tree) => {
|
|
66
|
+
tree.getSelectedItems().forEach((item) => item.collapseAll());
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
},
|
|
47
70
|
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export interface ExpandAllDataRef {
|
|
2
|
+
}
|
|
1
3
|
export type ExpandAllFeatureDef = {
|
|
2
4
|
state: {};
|
|
3
5
|
config: {};
|
|
@@ -13,5 +15,5 @@ export type ExpandAllFeatureDef = {
|
|
|
13
15
|
}) => Promise<void>;
|
|
14
16
|
collapseAll: () => void;
|
|
15
17
|
};
|
|
16
|
-
hotkeys:
|
|
18
|
+
hotkeys: "expandSelected" | "collapseSelected";
|
|
17
19
|
};
|
|
@@ -4,6 +4,8 @@ exports.hotkeysCoreFeature = void 0;
|
|
|
4
4
|
const specialKeys = {
|
|
5
5
|
Letter: /^[a-z]$/,
|
|
6
6
|
LetterOrNumber: /^[a-z0-9]$/,
|
|
7
|
+
Plus: /^\+$/,
|
|
8
|
+
Space: /^ $/,
|
|
7
9
|
};
|
|
8
10
|
const testHotkeyMatch = (pressedKeys, tree, hotkey) => {
|
|
9
11
|
const supposedKeys = hotkey.hotkey.split("+");
|
|
@@ -23,11 +25,12 @@ exports.hotkeysCoreFeature = {
|
|
|
23
25
|
onTreeMount: (tree, element) => {
|
|
24
26
|
const data = tree.getDataRef();
|
|
25
27
|
const keydown = (e) => {
|
|
26
|
-
var _a, _b;
|
|
27
|
-
var
|
|
28
|
-
(_a = (
|
|
28
|
+
var _a, _b, _c, _d;
|
|
29
|
+
var _e;
|
|
30
|
+
(_a = (_e = data.current).pressedKeys) !== null && _a !== void 0 ? _a : (_e.pressedKeys = new Set());
|
|
29
31
|
const newMatch = !data.current.pressedKeys.has(e.key);
|
|
30
32
|
data.current.pressedKeys.add(e.key);
|
|
33
|
+
console.log("HOTKEYS", data.current.pressedKeys);
|
|
31
34
|
const hotkeyName = findHotkeyMatch(data.current.pressedKeys, tree, tree.getHotkeyPresets(), tree.getConfig().hotkeys);
|
|
32
35
|
if (!hotkeyName)
|
|
33
36
|
return;
|
|
@@ -42,6 +45,7 @@ exports.hotkeysCoreFeature = {
|
|
|
42
45
|
if (hotkeyConfig.preventDefault)
|
|
43
46
|
e.preventDefault();
|
|
44
47
|
hotkeyConfig.handler(e, tree);
|
|
48
|
+
(_d = (_c = tree.getConfig()).onTreeHotkey) === null || _d === void 0 ? void 0 : _d.call(_c, hotkeyName, e);
|
|
45
49
|
};
|
|
46
50
|
const keyup = (e) => {
|
|
47
51
|
var _a;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CustomHotkeysConfig,
|
|
1
|
+
import { CustomHotkeysConfig, TreeInstance } from "../../types/core";
|
|
2
2
|
export interface HotkeyConfig<T> {
|
|
3
3
|
hotkey: string;
|
|
4
4
|
canRepeat?: boolean;
|
|
@@ -7,17 +7,16 @@ export interface HotkeyConfig<T> {
|
|
|
7
7
|
preventDefault?: boolean;
|
|
8
8
|
handler: (e: KeyboardEvent, tree: TreeInstance<T>) => void;
|
|
9
9
|
}
|
|
10
|
-
export
|
|
10
|
+
export interface HotkeysCoreDataRef {
|
|
11
11
|
keydownHandler?: (e: KeyboardEvent) => void;
|
|
12
12
|
keyupHandler?: (e: KeyboardEvent) => void;
|
|
13
13
|
pressedKeys: Set<string>;
|
|
14
|
-
}
|
|
14
|
+
}
|
|
15
15
|
export type HotkeysCoreFeatureDef<T> = {
|
|
16
16
|
state: {};
|
|
17
17
|
config: {
|
|
18
18
|
hotkeys?: CustomHotkeysConfig<T>;
|
|
19
|
-
onTreeHotkey?: (name: string,
|
|
20
|
-
onItemHotkey?: (name: string, item: ItemInstance<T>, element: HTMLElement) => void;
|
|
19
|
+
onTreeHotkey?: (name: string, e: KeyboardEvent) => void;
|
|
21
20
|
};
|
|
22
21
|
treeInstance: {};
|
|
23
22
|
itemInstance: {};
|
|
@@ -0,0 +1,206 @@
|
|
|
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.keyboardDragAndDropFeature = void 0;
|
|
13
|
+
const utils_1 = require("../drag-and-drop/utils");
|
|
14
|
+
const utils_2 = require("../../utils");
|
|
15
|
+
const types_1 = require("./types");
|
|
16
|
+
const getNextDragTarget = (tree, isUp, dragTarget) => {
|
|
17
|
+
var _a, _b, _c, _d;
|
|
18
|
+
const direction = isUp ? 0 : 1;
|
|
19
|
+
const draggedItems = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems;
|
|
20
|
+
// currently hovering between items
|
|
21
|
+
if ((0, utils_1.isOrderedDragTarget)(dragTarget)) {
|
|
22
|
+
const parent = dragTarget.item.getParent();
|
|
23
|
+
const targetedItem = tree.getItems()[dragTarget.dragLineIndex - 1]; // item above dragline
|
|
24
|
+
const targetCategory = targetedItem
|
|
25
|
+
? (0, utils_1.getItemDropCategory)(targetedItem)
|
|
26
|
+
: utils_1.ItemDropCategory.Item;
|
|
27
|
+
const maxLevel = (_b = targetedItem === null || targetedItem === void 0 ? void 0 : targetedItem.getItemMeta().level) !== null && _b !== void 0 ? _b : 0;
|
|
28
|
+
const minLevel = (_d = (_c = targetedItem === null || targetedItem === void 0 ? void 0 : targetedItem.getItemBelow()) === null || _c === void 0 ? void 0 : _c.getItemMeta().level) !== null && _d !== void 0 ? _d : 0;
|
|
29
|
+
// reparenting
|
|
30
|
+
if (targetCategory === utils_1.ItemDropCategory.LastInGroup) {
|
|
31
|
+
if (isUp && dragTarget.dragLineLevel < maxLevel) {
|
|
32
|
+
return (0, utils_1.getReparentTarget)(targetedItem, dragTarget.dragLineLevel + 1, draggedItems);
|
|
33
|
+
}
|
|
34
|
+
if (!isUp && dragTarget.dragLineLevel > minLevel && parent) {
|
|
35
|
+
return (0, utils_1.getReparentTarget)(targetedItem, dragTarget.dragLineLevel - 1, draggedItems);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const newIndex = dragTarget.dragLineIndex - 1 + direction;
|
|
39
|
+
const item = tree.getItems()[newIndex];
|
|
40
|
+
return item ? { item } : undefined;
|
|
41
|
+
}
|
|
42
|
+
// moving upwards outside of an open folder
|
|
43
|
+
const targetingExpandedFolder = (0, utils_1.getItemDropCategory)(dragTarget.item) === utils_1.ItemDropCategory.ExpandedFolder;
|
|
44
|
+
if (targetingExpandedFolder && !isUp) {
|
|
45
|
+
return {
|
|
46
|
+
item: dragTarget.item,
|
|
47
|
+
childIndex: 0,
|
|
48
|
+
insertionIndex: (0, utils_1.getInsertionIndex)(dragTarget.item.getChildren(), 0, draggedItems),
|
|
49
|
+
dragLineIndex: dragTarget.item.getItemMeta().index + direction,
|
|
50
|
+
dragLineLevel: dragTarget.item.getItemMeta().level + 1,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
// currently hovering over item
|
|
54
|
+
const childIndex = dragTarget.item.getIndexInParent() + direction;
|
|
55
|
+
return {
|
|
56
|
+
item: dragTarget.item.getParent(),
|
|
57
|
+
childIndex,
|
|
58
|
+
insertionIndex: (0, utils_1.getInsertionIndex)(dragTarget.item.getParent().getChildren(), childIndex, draggedItems),
|
|
59
|
+
dragLineIndex: dragTarget.item.getItemMeta().index + direction,
|
|
60
|
+
dragLineLevel: dragTarget.item.getItemMeta().level,
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
const getNextValidDragTarget = (tree, isUp, previousTarget) => {
|
|
64
|
+
var _a, _b;
|
|
65
|
+
if (previousTarget === void 0) { previousTarget = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.dragTarget; }
|
|
66
|
+
if (!previousTarget)
|
|
67
|
+
return undefined;
|
|
68
|
+
const nextTarget = getNextDragTarget(tree, isUp, previousTarget);
|
|
69
|
+
const dataTransfer = (_b = tree.getDataRef().current.kDndDataTransfer) !== null && _b !== void 0 ? _b : null;
|
|
70
|
+
if (!nextTarget)
|
|
71
|
+
return undefined;
|
|
72
|
+
if ((0, utils_1.canDrop)(dataTransfer, nextTarget, tree)) {
|
|
73
|
+
return nextTarget;
|
|
74
|
+
}
|
|
75
|
+
return getNextValidDragTarget(tree, isUp, nextTarget);
|
|
76
|
+
};
|
|
77
|
+
const updateScroll = (tree) => {
|
|
78
|
+
const state = tree.getState().dnd;
|
|
79
|
+
if (!(state === null || state === void 0 ? void 0 : state.dragTarget) || (0, utils_1.isOrderedDragTarget)(state.dragTarget))
|
|
80
|
+
return;
|
|
81
|
+
state.dragTarget.item.scrollTo({ block: "nearest", inline: "nearest" });
|
|
82
|
+
};
|
|
83
|
+
const initiateDrag = (tree, draggedItems, dataTransfer) => {
|
|
84
|
+
var _a, _b;
|
|
85
|
+
const focusedItem = tree.getFocusedItem();
|
|
86
|
+
const { canDrag } = tree.getConfig();
|
|
87
|
+
if (draggedItems && canDrag && !canDrag(draggedItems)) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (draggedItems) {
|
|
91
|
+
tree.applySubStateUpdate("dnd", { draggedItems });
|
|
92
|
+
// getNextValidDragTarget->canDrop needs the draggedItems in state
|
|
93
|
+
(_b = (_a = tree.getConfig()).onStartKeyboardDrag) === null || _b === void 0 ? void 0 : _b.call(_a, draggedItems);
|
|
94
|
+
}
|
|
95
|
+
else if (dataTransfer) {
|
|
96
|
+
tree.getDataRef().current.kDndDataTransfer = dataTransfer;
|
|
97
|
+
}
|
|
98
|
+
const dragTarget = getNextValidDragTarget(tree, false, {
|
|
99
|
+
item: focusedItem,
|
|
100
|
+
});
|
|
101
|
+
if (!dragTarget)
|
|
102
|
+
return;
|
|
103
|
+
tree.applySubStateUpdate("dnd", {
|
|
104
|
+
draggedItems,
|
|
105
|
+
dragTarget,
|
|
106
|
+
});
|
|
107
|
+
tree.applySubStateUpdate("assistiveDndState", types_1.AssistiveDndState.Started);
|
|
108
|
+
updateScroll(tree);
|
|
109
|
+
};
|
|
110
|
+
const moveDragPosition = (tree, isUp) => {
|
|
111
|
+
var _a;
|
|
112
|
+
const dragTarget = getNextValidDragTarget(tree, isUp);
|
|
113
|
+
if (!dragTarget)
|
|
114
|
+
return;
|
|
115
|
+
tree.applySubStateUpdate("dnd", {
|
|
116
|
+
draggedItems: (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems,
|
|
117
|
+
dragTarget,
|
|
118
|
+
});
|
|
119
|
+
tree.applySubStateUpdate("assistiveDndState", types_1.AssistiveDndState.Dragging);
|
|
120
|
+
if (!(0, utils_1.isOrderedDragTarget)(dragTarget)) {
|
|
121
|
+
dragTarget.item.setFocused();
|
|
122
|
+
}
|
|
123
|
+
updateScroll(tree);
|
|
124
|
+
};
|
|
125
|
+
exports.keyboardDragAndDropFeature = {
|
|
126
|
+
key: "keyboard-drag-and-drop",
|
|
127
|
+
deps: ["drag-and-drop"],
|
|
128
|
+
getDefaultConfig: (defaultConfig, tree) => (Object.assign({ setAssistiveDndState: (0, utils_2.makeStateUpdater)("assistiveDndState", tree) }, defaultConfig)),
|
|
129
|
+
stateHandlerNames: {
|
|
130
|
+
assistiveDndState: "setAssistiveDndState",
|
|
131
|
+
},
|
|
132
|
+
treeInstance: {
|
|
133
|
+
startKeyboardDrag: ({ tree }, draggedItems) => {
|
|
134
|
+
initiateDrag(tree, draggedItems, undefined);
|
|
135
|
+
},
|
|
136
|
+
startKeyboardDragOnForeignObject: ({ tree }, dataTransfer) => {
|
|
137
|
+
initiateDrag(tree, undefined, dataTransfer);
|
|
138
|
+
},
|
|
139
|
+
stopKeyboardDrag: ({ tree }) => {
|
|
140
|
+
tree.getDataRef().current.kDndDataTransfer = undefined;
|
|
141
|
+
tree.applySubStateUpdate("dnd", null);
|
|
142
|
+
tree.applySubStateUpdate("assistiveDndState", types_1.AssistiveDndState.None);
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
hotkeys: {
|
|
146
|
+
startDrag: {
|
|
147
|
+
hotkey: "Control+Shift+D",
|
|
148
|
+
preventDefault: true,
|
|
149
|
+
isEnabled: (tree) => !tree.getState().dnd,
|
|
150
|
+
handler: (_, tree) => {
|
|
151
|
+
tree.startKeyboardDrag(tree.getSelectedItems());
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
dragUp: {
|
|
155
|
+
hotkey: "ArrowUp",
|
|
156
|
+
preventDefault: true,
|
|
157
|
+
isEnabled: (tree) => !!tree.getState().dnd,
|
|
158
|
+
handler: (_, tree) => {
|
|
159
|
+
moveDragPosition(tree, true);
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
dragDown: {
|
|
163
|
+
hotkey: "ArrowDown",
|
|
164
|
+
preventDefault: true,
|
|
165
|
+
isEnabled: (tree) => !!tree.getState().dnd,
|
|
166
|
+
handler: (_, tree) => {
|
|
167
|
+
moveDragPosition(tree, false);
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
cancelDrag: {
|
|
171
|
+
hotkey: "Escape",
|
|
172
|
+
isEnabled: (tree) => !!tree.getState().dnd,
|
|
173
|
+
handler: (_, tree) => {
|
|
174
|
+
tree.stopKeyboardDrag();
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
completeDrag: {
|
|
178
|
+
hotkey: "Enter",
|
|
179
|
+
preventDefault: true,
|
|
180
|
+
isEnabled: (tree) => !!tree.getState().dnd,
|
|
181
|
+
handler: (e, tree) => __awaiter(void 0, void 0, void 0, function* () {
|
|
182
|
+
var _a, _b, _c, _d;
|
|
183
|
+
e.stopPropagation();
|
|
184
|
+
// TODO copied from keyboard onDrop, unify them
|
|
185
|
+
const dataRef = tree.getDataRef();
|
|
186
|
+
const target = tree.getDragTarget();
|
|
187
|
+
const dataTransfer = (_a = dataRef.current.kDndDataTransfer) !== null && _a !== void 0 ? _a : null;
|
|
188
|
+
if (!target || !(0, utils_1.canDrop)(dataTransfer, target, tree)) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
const config = tree.getConfig();
|
|
192
|
+
const draggedItems = (_b = tree.getState().dnd) === null || _b === void 0 ? void 0 : _b.draggedItems;
|
|
193
|
+
dataRef.current.lastDragCode = undefined;
|
|
194
|
+
tree.applySubStateUpdate("dnd", null);
|
|
195
|
+
if (draggedItems) {
|
|
196
|
+
yield ((_c = config.onDrop) === null || _c === void 0 ? void 0 : _c.call(config, draggedItems, target));
|
|
197
|
+
tree.getItemInstance(draggedItems[0].getId()).setFocused();
|
|
198
|
+
}
|
|
199
|
+
else if (dataTransfer) {
|
|
200
|
+
yield ((_d = config.onDropForeignDragObject) === null || _d === void 0 ? void 0 : _d.call(config, dataTransfer, target));
|
|
201
|
+
}
|
|
202
|
+
tree.applySubStateUpdate("assistiveDndState", types_1.AssistiveDndState.Completed);
|
|
203
|
+
}),
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ItemInstance, SetStateFn } from "../../types/core";
|
|
2
|
+
export interface KDndDataRef {
|
|
3
|
+
kDndDataTransfer: DataTransfer | undefined;
|
|
4
|
+
}
|
|
5
|
+
export declare enum AssistiveDndState {
|
|
6
|
+
None = 0,
|
|
7
|
+
Started = 1,
|
|
8
|
+
Dragging = 2,
|
|
9
|
+
Completed = 3,
|
|
10
|
+
Aborted = 4
|
|
11
|
+
}
|
|
12
|
+
export type KeyboardDragAndDropFeatureDef<T> = {
|
|
13
|
+
state: {
|
|
14
|
+
assistiveDndState?: AssistiveDndState | null;
|
|
15
|
+
};
|
|
16
|
+
config: {
|
|
17
|
+
setAssistiveDndState?: SetStateFn<AssistiveDndState | undefined | null>;
|
|
18
|
+
onStartKeyboardDrag?: (items: ItemInstance<T>[]) => void;
|
|
19
|
+
};
|
|
20
|
+
treeInstance: {
|
|
21
|
+
startKeyboardDrag: (items: ItemInstance<T>[]) => void;
|
|
22
|
+
startKeyboardDragOnForeignObject: (dataTransfer: DataTransfer) => void;
|
|
23
|
+
stopKeyboardDrag: () => void;
|
|
24
|
+
};
|
|
25
|
+
itemInstance: {};
|
|
26
|
+
hotkeys: "startDrag" | "cancelDrag" | "completeDrag" | "dragUp" | "dragDown";
|
|
27
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AssistiveDndState = void 0;
|
|
4
|
+
var AssistiveDndState;
|
|
5
|
+
(function (AssistiveDndState) {
|
|
6
|
+
AssistiveDndState[AssistiveDndState["None"] = 0] = "None";
|
|
7
|
+
AssistiveDndState[AssistiveDndState["Started"] = 1] = "Started";
|
|
8
|
+
AssistiveDndState[AssistiveDndState["Dragging"] = 2] = "Dragging";
|
|
9
|
+
AssistiveDndState[AssistiveDndState["Completed"] = 3] = "Completed";
|
|
10
|
+
AssistiveDndState[AssistiveDndState["Aborted"] = 4] = "Aborted";
|
|
11
|
+
})(AssistiveDndState || (exports.AssistiveDndState = AssistiveDndState = {}));
|