@headless-tree/core 0.0.15 → 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 +6 -0
- package/lib/cjs/features/drag-and-drop/feature.js +3 -3
- package/lib/cjs/features/drag-and-drop/utils.d.ts +7 -0
- package/lib/cjs/features/drag-and-drop/utils.js +3 -1
- package/lib/cjs/features/keyboard-drag-and-drop/feature.js +3 -4
- package/lib/cjs/features/prop-memoization/feature.js +32 -10
- package/lib/cjs/features/prop-memoization/types.d.ts +6 -1
- package/lib/cjs/features/tree/feature.js +0 -2
- package/lib/esm/features/drag-and-drop/feature.js +4 -4
- package/lib/esm/features/drag-and-drop/utils.d.ts +7 -0
- package/lib/esm/features/drag-and-drop/utils.js +1 -0
- package/lib/esm/features/keyboard-drag-and-drop/feature.js +4 -5
- package/lib/esm/features/prop-memoization/feature.js +32 -10
- package/lib/esm/features/prop-memoization/types.d.ts +6 -1
- package/lib/esm/features/tree/feature.js +0 -2
- package/package.json +1 -1
- package/src/features/drag-and-drop/feature.ts +9 -4
- package/src/features/drag-and-drop/utils.ts +3 -0
- package/src/features/keyboard-drag-and-drop/feature.ts +4 -4
- package/src/features/keyboard-drag-and-drop/keyboard-drag-and-drop.spec.ts +2 -1
- package/src/features/prop-memoization/feature.ts +26 -7
- package/src/features/prop-memoization/types.ts +6 -1
- package/src/features/tree/feature.ts +0 -2
package/CHANGELOG.md
CHANGED
|
@@ -29,7 +29,7 @@ exports.dragAndDropFeature = {
|
|
|
29
29
|
const target = tree.getDragTarget();
|
|
30
30
|
const indent = ((_a = target === null || target === void 0 ? void 0 : target.item.getItemMeta().level) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
31
31
|
const treeBb = (_b = tree.getElement()) === null || _b === void 0 ? void 0 : _b.getBoundingClientRect();
|
|
32
|
-
if (!target || !treeBb || !(
|
|
32
|
+
if (!target || !treeBb || !(0, utils_1.isOrderedDragTarget)(target))
|
|
33
33
|
return null;
|
|
34
34
|
const leftOffset = target.dragLineLevel * ((_c = tree.getConfig().indent) !== null && _c !== void 0 ? _c : 1);
|
|
35
35
|
const targetItem = tree.getItems()[target.dragLineIndex];
|
|
@@ -157,7 +157,7 @@ exports.dragAndDropFeature = {
|
|
|
157
157
|
isDragTargetAbove: ({ tree, item }) => {
|
|
158
158
|
const target = tree.getDragTarget();
|
|
159
159
|
if (!target ||
|
|
160
|
-
!(
|
|
160
|
+
!(0, utils_1.isOrderedDragTarget)(target) ||
|
|
161
161
|
target.item !== item.getParent())
|
|
162
162
|
return false;
|
|
163
163
|
return target.childIndex === item.getItemMeta().posInSet;
|
|
@@ -165,7 +165,7 @@ exports.dragAndDropFeature = {
|
|
|
165
165
|
isDragTargetBelow: ({ tree, item }) => {
|
|
166
166
|
const target = tree.getDragTarget();
|
|
167
167
|
if (!target ||
|
|
168
|
-
!(
|
|
168
|
+
!(0, utils_1.isOrderedDragTarget)(target) ||
|
|
169
169
|
target.item !== item.getParent())
|
|
170
170
|
return false;
|
|
171
171
|
return target.childIndex - 1 === item.getItemMeta().posInSet;
|
|
@@ -5,6 +5,13 @@ export declare enum ItemDropCategory {
|
|
|
5
5
|
ExpandedFolder = 1,
|
|
6
6
|
LastInGroup = 2
|
|
7
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
|
+
};
|
|
8
15
|
export declare const canDrop: (dataTransfer: DataTransfer | null, target: DragTarget<any>, tree: TreeInstance<any>) => boolean;
|
|
9
16
|
export declare const getItemDropCategory: (item: ItemInstance<any>) => ItemDropCategory;
|
|
10
17
|
export declare const getInsertionIndex: <T>(children: ItemInstance<T>[], childIndex: number, draggedItems: ItemInstance<T>[] | undefined) => number;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getDragTarget = exports.getReparentTarget = exports.getDragCode = exports.getInsertionIndex = exports.getItemDropCategory = exports.canDrop = exports.ItemDropCategory = void 0;
|
|
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";
|
|
@@ -14,6 +14,8 @@ 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
20
|
var _a, _b, _c;
|
|
19
21
|
const draggedItems = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems;
|
|
@@ -18,8 +18,7 @@ const getNextDragTarget = (tree, isUp, dragTarget) => {
|
|
|
18
18
|
const direction = isUp ? 0 : 1;
|
|
19
19
|
const draggedItems = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems;
|
|
20
20
|
// currently hovering between items
|
|
21
|
-
if (
|
|
22
|
-
// TODO move check in reusable function
|
|
21
|
+
if ((0, utils_1.isOrderedDragTarget)(dragTarget)) {
|
|
23
22
|
const parent = dragTarget.item.getParent();
|
|
24
23
|
const targetedItem = tree.getItems()[dragTarget.dragLineIndex - 1]; // item above dragline
|
|
25
24
|
const targetCategory = targetedItem
|
|
@@ -77,7 +76,7 @@ const getNextValidDragTarget = (tree, isUp, previousTarget) => {
|
|
|
77
76
|
};
|
|
78
77
|
const updateScroll = (tree) => {
|
|
79
78
|
const state = tree.getState().dnd;
|
|
80
|
-
if (!(state === null || state === void 0 ? void 0 : state.dragTarget) ||
|
|
79
|
+
if (!(state === null || state === void 0 ? void 0 : state.dragTarget) || (0, utils_1.isOrderedDragTarget)(state.dragTarget))
|
|
81
80
|
return;
|
|
82
81
|
state.dragTarget.item.scrollTo({ block: "nearest", inline: "nearest" });
|
|
83
82
|
};
|
|
@@ -118,7 +117,7 @@ const moveDragPosition = (tree, isUp) => {
|
|
|
118
117
|
dragTarget,
|
|
119
118
|
});
|
|
120
119
|
tree.applySubStateUpdate("assistiveDndState", types_1.AssistiveDndState.Dragging);
|
|
121
|
-
if (!(
|
|
120
|
+
if (!(0, utils_1.isOrderedDragTarget)(dragTarget)) {
|
|
122
121
|
dragTarget.item.setFocused();
|
|
123
122
|
}
|
|
124
123
|
updateScroll(tree);
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.propMemoizationFeature = void 0;
|
|
4
|
-
const memoize = (props,
|
|
5
|
-
var _a;
|
|
6
|
-
(_a = dataRef.memoizedProps) !== null && _a !== void 0 ? _a : (dataRef.memoizedProps = {});
|
|
4
|
+
const memoize = (props, memoizedProps) => {
|
|
7
5
|
for (const key in props) {
|
|
8
6
|
if (typeof props[key] === "function") {
|
|
9
|
-
if (key in
|
|
10
|
-
props[key] =
|
|
7
|
+
if (memoizedProps && key in memoizedProps) {
|
|
8
|
+
props[key] = memoizedProps[key];
|
|
11
9
|
}
|
|
12
10
|
else {
|
|
13
|
-
|
|
11
|
+
memoizedProps[key] = props[key];
|
|
14
12
|
}
|
|
15
13
|
}
|
|
16
14
|
}
|
|
@@ -31,18 +29,42 @@ exports.propMemoizationFeature = {
|
|
|
31
29
|
],
|
|
32
30
|
treeInstance: {
|
|
33
31
|
getContainerProps: ({ tree, prev }, treeLabel) => {
|
|
34
|
-
var _a;
|
|
32
|
+
var _a, _b, _c;
|
|
33
|
+
var _d, _e;
|
|
35
34
|
const dataRef = tree.getDataRef();
|
|
36
35
|
const props = (_a = prev === null || prev === void 0 ? void 0 : prev(treeLabel)) !== null && _a !== void 0 ? _a : {};
|
|
37
|
-
|
|
36
|
+
(_b = (_d = dataRef.current).memo) !== null && _b !== void 0 ? _b : (_d.memo = {});
|
|
37
|
+
(_c = (_e = dataRef.current.memo).tree) !== null && _c !== void 0 ? _c : (_e.tree = {});
|
|
38
|
+
return memoize(props, dataRef.current.memo.tree);
|
|
39
|
+
},
|
|
40
|
+
getSearchInputElementProps: ({ tree, prev }) => {
|
|
41
|
+
var _a, _b, _c;
|
|
42
|
+
var _d, _e;
|
|
43
|
+
const dataRef = tree.getDataRef();
|
|
44
|
+
const props = (_a = prev === null || prev === void 0 ? void 0 : prev()) !== null && _a !== void 0 ? _a : {};
|
|
45
|
+
(_b = (_d = dataRef.current).memo) !== null && _b !== void 0 ? _b : (_d.memo = {});
|
|
46
|
+
(_c = (_e = dataRef.current.memo).search) !== null && _c !== void 0 ? _c : (_e.search = {});
|
|
47
|
+
return memoize(props, dataRef.current.memo.search);
|
|
38
48
|
},
|
|
39
49
|
},
|
|
40
50
|
itemInstance: {
|
|
41
51
|
getProps: ({ item, prev }) => {
|
|
42
|
-
var _a;
|
|
52
|
+
var _a, _b, _c;
|
|
53
|
+
var _d, _e;
|
|
54
|
+
const dataRef = item.getDataRef();
|
|
55
|
+
const props = (_a = prev === null || prev === void 0 ? void 0 : prev()) !== null && _a !== void 0 ? _a : {};
|
|
56
|
+
(_b = (_d = dataRef.current).memo) !== null && _b !== void 0 ? _b : (_d.memo = {});
|
|
57
|
+
(_c = (_e = dataRef.current.memo).item) !== null && _c !== void 0 ? _c : (_e.item = {});
|
|
58
|
+
return memoize(props, dataRef.current.memo.item);
|
|
59
|
+
},
|
|
60
|
+
getRenameInputProps: ({ item, prev }) => {
|
|
61
|
+
var _a, _b, _c;
|
|
62
|
+
var _d, _e;
|
|
43
63
|
const dataRef = item.getDataRef();
|
|
44
64
|
const props = (_a = prev === null || prev === void 0 ? void 0 : prev()) !== null && _a !== void 0 ? _a : {};
|
|
45
|
-
|
|
65
|
+
(_b = (_d = dataRef.current).memo) !== null && _b !== void 0 ? _b : (_d.memo = {});
|
|
66
|
+
(_c = (_e = dataRef.current.memo).rename) !== null && _c !== void 0 ? _c : (_e.rename = {});
|
|
67
|
+
return memoize(props, dataRef.current.memo.rename);
|
|
46
68
|
},
|
|
47
69
|
},
|
|
48
70
|
};
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
export interface PropMemoizationDataRef {
|
|
2
|
-
|
|
2
|
+
memo?: {
|
|
3
|
+
tree?: Record<string, any>;
|
|
4
|
+
item?: Record<string, any>;
|
|
5
|
+
search?: Record<string, any>;
|
|
6
|
+
rename?: Record<string, any>;
|
|
7
|
+
};
|
|
3
8
|
}
|
|
4
9
|
export type PropMemoizationFeatureDef = {
|
|
5
10
|
state: {};
|
|
@@ -50,7 +50,6 @@ exports.treeFeature = {
|
|
|
50
50
|
}
|
|
51
51
|
return flatItems;
|
|
52
52
|
},
|
|
53
|
-
// TODO memo
|
|
54
53
|
getFocusedItem: ({ tree }) => {
|
|
55
54
|
var _a, _b;
|
|
56
55
|
return ((_b = tree.getItemInstance((_a = tree.getState().focusedItem) !== null && _a !== void 0 ? _a : "")) !== null && _b !== void 0 ? _b : tree.getItems()[0]);
|
|
@@ -80,7 +79,6 @@ exports.treeFeature = {
|
|
|
80
79
|
focusedElement.focus();
|
|
81
80
|
}));
|
|
82
81
|
},
|
|
83
|
-
// TODO add label parameter
|
|
84
82
|
getContainerProps: ({ prev, tree }, treeLabel) => (Object.assign(Object.assign({}, prev === null || prev === void 0 ? void 0 : prev()), { role: "tree", "aria-label": treeLabel !== null && treeLabel !== void 0 ? treeLabel : "", ref: tree.registerElement })),
|
|
85
83
|
// relevant for hotkeys of this feature
|
|
86
84
|
isSearchOpen: () => false,
|
|
@@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import { canDrop, getDragCode, getDragTarget } from "./utils";
|
|
10
|
+
import { canDrop, getDragCode, getDragTarget, isOrderedDragTarget, } from "./utils";
|
|
11
11
|
import { makeStateUpdater } from "../../utils";
|
|
12
12
|
export const dragAndDropFeature = {
|
|
13
13
|
key: "drag-and-drop",
|
|
@@ -26,7 +26,7 @@ export const dragAndDropFeature = {
|
|
|
26
26
|
const target = tree.getDragTarget();
|
|
27
27
|
const indent = ((_a = target === null || target === void 0 ? void 0 : target.item.getItemMeta().level) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
28
28
|
const treeBb = (_b = tree.getElement()) === null || _b === void 0 ? void 0 : _b.getBoundingClientRect();
|
|
29
|
-
if (!target || !treeBb || !(
|
|
29
|
+
if (!target || !treeBb || !isOrderedDragTarget(target))
|
|
30
30
|
return null;
|
|
31
31
|
const leftOffset = target.dragLineLevel * ((_c = tree.getConfig().indent) !== null && _c !== void 0 ? _c : 1);
|
|
32
32
|
const targetItem = tree.getItems()[target.dragLineIndex];
|
|
@@ -154,7 +154,7 @@ export const dragAndDropFeature = {
|
|
|
154
154
|
isDragTargetAbove: ({ tree, item }) => {
|
|
155
155
|
const target = tree.getDragTarget();
|
|
156
156
|
if (!target ||
|
|
157
|
-
!(
|
|
157
|
+
!isOrderedDragTarget(target) ||
|
|
158
158
|
target.item !== item.getParent())
|
|
159
159
|
return false;
|
|
160
160
|
return target.childIndex === item.getItemMeta().posInSet;
|
|
@@ -162,7 +162,7 @@ export const dragAndDropFeature = {
|
|
|
162
162
|
isDragTargetBelow: ({ tree, item }) => {
|
|
163
163
|
const target = tree.getDragTarget();
|
|
164
164
|
if (!target ||
|
|
165
|
-
!(
|
|
165
|
+
!isOrderedDragTarget(target) ||
|
|
166
166
|
target.item !== item.getParent())
|
|
167
167
|
return false;
|
|
168
168
|
return target.childIndex - 1 === item.getItemMeta().posInSet;
|
|
@@ -5,6 +5,13 @@ export declare enum ItemDropCategory {
|
|
|
5
5
|
ExpandedFolder = 1,
|
|
6
6
|
LastInGroup = 2
|
|
7
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
|
+
};
|
|
8
15
|
export declare const canDrop: (dataTransfer: DataTransfer | null, target: DragTarget<any>, tree: TreeInstance<any>) => boolean;
|
|
9
16
|
export declare const getItemDropCategory: (item: ItemInstance<any>) => ItemDropCategory;
|
|
10
17
|
export declare const getInsertionIndex: <T>(children: ItemInstance<T>[], childIndex: number, draggedItems: ItemInstance<T>[] | undefined) => number;
|
|
@@ -11,6 +11,7 @@ var PlacementType;
|
|
|
11
11
|
PlacementType[PlacementType["MakeChild"] = 2] = "MakeChild";
|
|
12
12
|
PlacementType[PlacementType["Reparent"] = 3] = "Reparent";
|
|
13
13
|
})(PlacementType || (PlacementType = {}));
|
|
14
|
+
export const isOrderedDragTarget = (dragTarget) => "childIndex" in dragTarget;
|
|
14
15
|
export const canDrop = (dataTransfer, target, tree) => {
|
|
15
16
|
var _a, _b, _c;
|
|
16
17
|
const draggedItems = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems;
|
|
@@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import { ItemDropCategory, canDrop, getInsertionIndex, getItemDropCategory, getReparentTarget, } from "../drag-and-drop/utils";
|
|
10
|
+
import { ItemDropCategory, canDrop, getInsertionIndex, getItemDropCategory, getReparentTarget, isOrderedDragTarget, } from "../drag-and-drop/utils";
|
|
11
11
|
import { makeStateUpdater } from "../../utils";
|
|
12
12
|
import { AssistiveDndState } from "./types";
|
|
13
13
|
const getNextDragTarget = (tree, isUp, dragTarget) => {
|
|
@@ -15,8 +15,7 @@ const getNextDragTarget = (tree, isUp, dragTarget) => {
|
|
|
15
15
|
const direction = isUp ? 0 : 1;
|
|
16
16
|
const draggedItems = (_a = tree.getState().dnd) === null || _a === void 0 ? void 0 : _a.draggedItems;
|
|
17
17
|
// currently hovering between items
|
|
18
|
-
if (
|
|
19
|
-
// TODO move check in reusable function
|
|
18
|
+
if (isOrderedDragTarget(dragTarget)) {
|
|
20
19
|
const parent = dragTarget.item.getParent();
|
|
21
20
|
const targetedItem = tree.getItems()[dragTarget.dragLineIndex - 1]; // item above dragline
|
|
22
21
|
const targetCategory = targetedItem
|
|
@@ -74,7 +73,7 @@ const getNextValidDragTarget = (tree, isUp, previousTarget) => {
|
|
|
74
73
|
};
|
|
75
74
|
const updateScroll = (tree) => {
|
|
76
75
|
const state = tree.getState().dnd;
|
|
77
|
-
if (!(state === null || state === void 0 ? void 0 : state.dragTarget) ||
|
|
76
|
+
if (!(state === null || state === void 0 ? void 0 : state.dragTarget) || isOrderedDragTarget(state.dragTarget))
|
|
78
77
|
return;
|
|
79
78
|
state.dragTarget.item.scrollTo({ block: "nearest", inline: "nearest" });
|
|
80
79
|
};
|
|
@@ -115,7 +114,7 @@ const moveDragPosition = (tree, isUp) => {
|
|
|
115
114
|
dragTarget,
|
|
116
115
|
});
|
|
117
116
|
tree.applySubStateUpdate("assistiveDndState", AssistiveDndState.Dragging);
|
|
118
|
-
if (!(
|
|
117
|
+
if (!isOrderedDragTarget(dragTarget)) {
|
|
119
118
|
dragTarget.item.setFocused();
|
|
120
119
|
}
|
|
121
120
|
updateScroll(tree);
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
const memoize = (props,
|
|
2
|
-
var _a;
|
|
3
|
-
(_a = dataRef.memoizedProps) !== null && _a !== void 0 ? _a : (dataRef.memoizedProps = {});
|
|
1
|
+
const memoize = (props, memoizedProps) => {
|
|
4
2
|
for (const key in props) {
|
|
5
3
|
if (typeof props[key] === "function") {
|
|
6
|
-
if (key in
|
|
7
|
-
props[key] =
|
|
4
|
+
if (memoizedProps && key in memoizedProps) {
|
|
5
|
+
props[key] = memoizedProps[key];
|
|
8
6
|
}
|
|
9
7
|
else {
|
|
10
|
-
|
|
8
|
+
memoizedProps[key] = props[key];
|
|
11
9
|
}
|
|
12
10
|
}
|
|
13
11
|
}
|
|
@@ -28,18 +26,42 @@ export const propMemoizationFeature = {
|
|
|
28
26
|
],
|
|
29
27
|
treeInstance: {
|
|
30
28
|
getContainerProps: ({ tree, prev }, treeLabel) => {
|
|
31
|
-
var _a;
|
|
29
|
+
var _a, _b, _c;
|
|
30
|
+
var _d, _e;
|
|
32
31
|
const dataRef = tree.getDataRef();
|
|
33
32
|
const props = (_a = prev === null || prev === void 0 ? void 0 : prev(treeLabel)) !== null && _a !== void 0 ? _a : {};
|
|
34
|
-
|
|
33
|
+
(_b = (_d = dataRef.current).memo) !== null && _b !== void 0 ? _b : (_d.memo = {});
|
|
34
|
+
(_c = (_e = dataRef.current.memo).tree) !== null && _c !== void 0 ? _c : (_e.tree = {});
|
|
35
|
+
return memoize(props, dataRef.current.memo.tree);
|
|
36
|
+
},
|
|
37
|
+
getSearchInputElementProps: ({ tree, prev }) => {
|
|
38
|
+
var _a, _b, _c;
|
|
39
|
+
var _d, _e;
|
|
40
|
+
const dataRef = tree.getDataRef();
|
|
41
|
+
const props = (_a = prev === null || prev === void 0 ? void 0 : prev()) !== null && _a !== void 0 ? _a : {};
|
|
42
|
+
(_b = (_d = dataRef.current).memo) !== null && _b !== void 0 ? _b : (_d.memo = {});
|
|
43
|
+
(_c = (_e = dataRef.current.memo).search) !== null && _c !== void 0 ? _c : (_e.search = {});
|
|
44
|
+
return memoize(props, dataRef.current.memo.search);
|
|
35
45
|
},
|
|
36
46
|
},
|
|
37
47
|
itemInstance: {
|
|
38
48
|
getProps: ({ item, prev }) => {
|
|
39
|
-
var _a;
|
|
49
|
+
var _a, _b, _c;
|
|
50
|
+
var _d, _e;
|
|
51
|
+
const dataRef = item.getDataRef();
|
|
52
|
+
const props = (_a = prev === null || prev === void 0 ? void 0 : prev()) !== null && _a !== void 0 ? _a : {};
|
|
53
|
+
(_b = (_d = dataRef.current).memo) !== null && _b !== void 0 ? _b : (_d.memo = {});
|
|
54
|
+
(_c = (_e = dataRef.current.memo).item) !== null && _c !== void 0 ? _c : (_e.item = {});
|
|
55
|
+
return memoize(props, dataRef.current.memo.item);
|
|
56
|
+
},
|
|
57
|
+
getRenameInputProps: ({ item, prev }) => {
|
|
58
|
+
var _a, _b, _c;
|
|
59
|
+
var _d, _e;
|
|
40
60
|
const dataRef = item.getDataRef();
|
|
41
61
|
const props = (_a = prev === null || prev === void 0 ? void 0 : prev()) !== null && _a !== void 0 ? _a : {};
|
|
42
|
-
|
|
62
|
+
(_b = (_d = dataRef.current).memo) !== null && _b !== void 0 ? _b : (_d.memo = {});
|
|
63
|
+
(_c = (_e = dataRef.current.memo).rename) !== null && _c !== void 0 ? _c : (_e.rename = {});
|
|
64
|
+
return memoize(props, dataRef.current.memo.rename);
|
|
43
65
|
},
|
|
44
66
|
},
|
|
45
67
|
};
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
export interface PropMemoizationDataRef {
|
|
2
|
-
|
|
2
|
+
memo?: {
|
|
3
|
+
tree?: Record<string, any>;
|
|
4
|
+
item?: Record<string, any>;
|
|
5
|
+
search?: Record<string, any>;
|
|
6
|
+
rename?: Record<string, any>;
|
|
7
|
+
};
|
|
3
8
|
}
|
|
4
9
|
export type PropMemoizationFeatureDef = {
|
|
5
10
|
state: {};
|
|
@@ -47,7 +47,6 @@ export const treeFeature = {
|
|
|
47
47
|
}
|
|
48
48
|
return flatItems;
|
|
49
49
|
},
|
|
50
|
-
// TODO memo
|
|
51
50
|
getFocusedItem: ({ tree }) => {
|
|
52
51
|
var _a, _b;
|
|
53
52
|
return ((_b = tree.getItemInstance((_a = tree.getState().focusedItem) !== null && _a !== void 0 ? _a : "")) !== null && _b !== void 0 ? _b : tree.getItems()[0]);
|
|
@@ -77,7 +76,6 @@ export const treeFeature = {
|
|
|
77
76
|
focusedElement.focus();
|
|
78
77
|
}));
|
|
79
78
|
},
|
|
80
|
-
// TODO add label parameter
|
|
81
79
|
getContainerProps: ({ prev, tree }, treeLabel) => (Object.assign(Object.assign({}, prev === null || prev === void 0 ? void 0 : prev()), { role: "tree", "aria-label": treeLabel !== null && treeLabel !== void 0 ? treeLabel : "", ref: tree.registerElement })),
|
|
82
80
|
// relevant for hotkeys of this feature
|
|
83
81
|
isSearchOpen: () => false,
|
package/package.json
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { FeatureImplementation } from "../../types/core";
|
|
2
2
|
import { DndDataRef, DragLineData } from "./types";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
canDrop,
|
|
5
|
+
getDragCode,
|
|
6
|
+
getDragTarget,
|
|
7
|
+
isOrderedDragTarget,
|
|
8
|
+
} from "./utils";
|
|
4
9
|
import { makeStateUpdater } from "../../utils";
|
|
5
10
|
|
|
6
11
|
export const dragAndDropFeature: FeatureImplementation = {
|
|
@@ -30,7 +35,7 @@ export const dragAndDropFeature: FeatureImplementation = {
|
|
|
30
35
|
|
|
31
36
|
const treeBb = tree.getElement()?.getBoundingClientRect();
|
|
32
37
|
|
|
33
|
-
if (!target || !treeBb || !(
|
|
38
|
+
if (!target || !treeBb || !isOrderedDragTarget(target)) return null;
|
|
34
39
|
|
|
35
40
|
const leftOffset = target.dragLineLevel * (tree.getConfig().indent ?? 1);
|
|
36
41
|
const targetItem = tree.getItems()[target.dragLineIndex];
|
|
@@ -212,7 +217,7 @@ export const dragAndDropFeature: FeatureImplementation = {
|
|
|
212
217
|
|
|
213
218
|
if (
|
|
214
219
|
!target ||
|
|
215
|
-
!(
|
|
220
|
+
!isOrderedDragTarget(target) ||
|
|
216
221
|
target.item !== item.getParent()
|
|
217
222
|
)
|
|
218
223
|
return false;
|
|
@@ -224,7 +229,7 @@ export const dragAndDropFeature: FeatureImplementation = {
|
|
|
224
229
|
|
|
225
230
|
if (
|
|
226
231
|
!target ||
|
|
227
|
-
!(
|
|
232
|
+
!isOrderedDragTarget(target) ||
|
|
228
233
|
target.item !== item.getParent()
|
|
229
234
|
)
|
|
230
235
|
return false;
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
getInsertionIndex,
|
|
11
11
|
getItemDropCategory,
|
|
12
12
|
getReparentTarget,
|
|
13
|
+
isOrderedDragTarget,
|
|
13
14
|
} from "../drag-and-drop/utils";
|
|
14
15
|
import { makeStateUpdater } from "../../utils";
|
|
15
16
|
import { AssistiveDndState, KDndDataRef } from "./types";
|
|
@@ -23,8 +24,7 @@ const getNextDragTarget = <T>(
|
|
|
23
24
|
const draggedItems = tree.getState().dnd?.draggedItems;
|
|
24
25
|
|
|
25
26
|
// currently hovering between items
|
|
26
|
-
if (
|
|
27
|
-
// TODO move check in reusable function
|
|
27
|
+
if (isOrderedDragTarget(dragTarget)) {
|
|
28
28
|
const parent = dragTarget.item.getParent();
|
|
29
29
|
const targetedItem = tree.getItems()[dragTarget.dragLineIndex - 1]; // item above dragline
|
|
30
30
|
|
|
@@ -107,7 +107,7 @@ const getNextValidDragTarget = <T>(
|
|
|
107
107
|
|
|
108
108
|
const updateScroll = <T>(tree: TreeInstance<T>) => {
|
|
109
109
|
const state = tree.getState().dnd;
|
|
110
|
-
if (!state?.dragTarget ||
|
|
110
|
+
if (!state?.dragTarget || isOrderedDragTarget(state.dragTarget)) return;
|
|
111
111
|
state.dragTarget.item.scrollTo({ block: "nearest", inline: "nearest" });
|
|
112
112
|
};
|
|
113
113
|
|
|
@@ -152,7 +152,7 @@ const moveDragPosition = <T>(tree: TreeInstance<T>, isUp: boolean) => {
|
|
|
152
152
|
dragTarget,
|
|
153
153
|
});
|
|
154
154
|
tree.applySubStateUpdate("assistiveDndState", AssistiveDndState.Dragging);
|
|
155
|
-
if (!(
|
|
155
|
+
if (!isOrderedDragTarget(dragTarget)) {
|
|
156
156
|
dragTarget.item.setFocused();
|
|
157
157
|
}
|
|
158
158
|
updateScroll(tree);
|
|
@@ -6,6 +6,7 @@ import { propMemoizationFeature } from "../prop-memoization/feature";
|
|
|
6
6
|
import { keyboardDragAndDropFeature } from "./feature";
|
|
7
7
|
import { dragAndDropFeature } from "../drag-and-drop/feature";
|
|
8
8
|
import { AssistiveDndState } from "./types";
|
|
9
|
+
import { isOrderedDragTarget } from "../drag-and-drop/utils";
|
|
9
10
|
|
|
10
11
|
const isItem = (item: unknown): item is ItemInstance<any> =>
|
|
11
12
|
!!item && typeof item === "object" && "getId" in item;
|
|
@@ -318,7 +319,7 @@ describe("core-feature/keyboard-drag-and-drop", () => {
|
|
|
318
319
|
describe("drag restrictions", () => {
|
|
319
320
|
const expectChildIndex = (index: number) => {
|
|
320
321
|
const state = tree.instance.getState().dnd?.dragTarget;
|
|
321
|
-
if (!state || !(
|
|
322
|
+
if (!state || !isOrderedDragTarget(state))
|
|
322
323
|
throw new Error("No childIndex");
|
|
323
324
|
expect(state.childIndex).toEqual(index);
|
|
324
325
|
};
|
|
@@ -3,15 +3,14 @@ import { PropMemoizationDataRef } from "./types";
|
|
|
3
3
|
|
|
4
4
|
const memoize = (
|
|
5
5
|
props: Record<string, any>,
|
|
6
|
-
|
|
6
|
+
memoizedProps: Record<string, any>,
|
|
7
7
|
) => {
|
|
8
|
-
dataRef.memoizedProps ??= {};
|
|
9
8
|
for (const key in props) {
|
|
10
9
|
if (typeof props[key] === "function") {
|
|
11
|
-
if (key in
|
|
12
|
-
props[key] =
|
|
10
|
+
if (memoizedProps && key in memoizedProps) {
|
|
11
|
+
props[key] = memoizedProps[key];
|
|
13
12
|
} else {
|
|
14
|
-
|
|
13
|
+
memoizedProps[key] = props[key];
|
|
15
14
|
}
|
|
16
15
|
}
|
|
17
16
|
}
|
|
@@ -37,7 +36,17 @@ export const propMemoizationFeature: FeatureImplementation = {
|
|
|
37
36
|
getContainerProps: ({ tree, prev }, treeLabel) => {
|
|
38
37
|
const dataRef = tree.getDataRef<PropMemoizationDataRef>();
|
|
39
38
|
const props = prev?.(treeLabel) ?? {};
|
|
40
|
-
|
|
39
|
+
dataRef.current.memo ??= {};
|
|
40
|
+
dataRef.current.memo.tree ??= {};
|
|
41
|
+
return memoize(props, dataRef.current.memo.tree);
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
getSearchInputElementProps: ({ tree, prev }) => {
|
|
45
|
+
const dataRef = tree.getDataRef<PropMemoizationDataRef>();
|
|
46
|
+
const props = prev?.() ?? {};
|
|
47
|
+
dataRef.current.memo ??= {};
|
|
48
|
+
dataRef.current.memo.search ??= {};
|
|
49
|
+
return memoize(props, dataRef.current.memo.search);
|
|
41
50
|
},
|
|
42
51
|
},
|
|
43
52
|
|
|
@@ -45,7 +54,17 @@ export const propMemoizationFeature: FeatureImplementation = {
|
|
|
45
54
|
getProps: ({ item, prev }) => {
|
|
46
55
|
const dataRef = item.getDataRef<PropMemoizationDataRef>();
|
|
47
56
|
const props = prev?.() ?? {};
|
|
48
|
-
|
|
57
|
+
dataRef.current.memo ??= {};
|
|
58
|
+
dataRef.current.memo.item ??= {};
|
|
59
|
+
return memoize(props, dataRef.current.memo.item);
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
getRenameInputProps: ({ item, prev }) => {
|
|
63
|
+
const dataRef = item.getDataRef<PropMemoizationDataRef>();
|
|
64
|
+
const props = prev?.() ?? {};
|
|
65
|
+
dataRef.current.memo ??= {};
|
|
66
|
+
dataRef.current.memo.rename ??= {};
|
|
67
|
+
return memoize(props, dataRef.current.memo.rename);
|
|
49
68
|
},
|
|
50
69
|
},
|
|
51
70
|
};
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
export interface PropMemoizationDataRef {
|
|
2
|
-
|
|
2
|
+
memo?: {
|
|
3
|
+
tree?: Record<string, any>;
|
|
4
|
+
item?: Record<string, any>;
|
|
5
|
+
search?: Record<string, any>;
|
|
6
|
+
rename?: Record<string, any>;
|
|
7
|
+
};
|
|
3
8
|
}
|
|
4
9
|
|
|
5
10
|
export type PropMemoizationFeatureDef = {
|
|
@@ -63,7 +63,6 @@ export const treeFeature: FeatureImplementation<any> = {
|
|
|
63
63
|
return flatItems;
|
|
64
64
|
},
|
|
65
65
|
|
|
66
|
-
// TODO memo
|
|
67
66
|
getFocusedItem: ({ tree }) => {
|
|
68
67
|
return (
|
|
69
68
|
tree.getItemInstance(tree.getState().focusedItem ?? "") ??
|
|
@@ -95,7 +94,6 @@ export const treeFeature: FeatureImplementation<any> = {
|
|
|
95
94
|
});
|
|
96
95
|
},
|
|
97
96
|
|
|
98
|
-
// TODO add label parameter
|
|
99
97
|
getContainerProps: ({ prev, tree }, treeLabel) => ({
|
|
100
98
|
...prev?.(),
|
|
101
99
|
role: "tree",
|