react-arborist 3.2.0 → 3.3.0-rc.1
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/dist/dnd/drop-hook.d.ts +1 -1
- package/dist/index.js +42 -23
- package/dist/index.js.map +1 -1
- package/dist/interfaces/node-api.d.ts +1 -0
- package/dist/interfaces/tree-api.d.ts +3 -0
- package/dist/module.js +42 -23
- package/dist/module.js.map +1 -1
- package/dist/state/dnd-slice.d.ts +3 -3
- package/dist/state/drag-slice.d.ts +3 -1
- package/dist/utils.d.ts +2 -2
- package/package.json +1 -1
- package/src/dnd/compute-drop.ts +6 -3
- package/src/dnd/drag-hook.ts +1 -1
- package/src/dnd/drop-hook.ts +1 -1
- package/src/interfaces/node-api.ts +10 -0
- package/src/interfaces/tree-api.ts +16 -3
- package/src/state/dnd-slice.ts +2 -2
- package/src/state/drag-slice.ts +27 -11
- package/src/state/initial.ts +6 -1
- package/src/utils.ts +2 -2
|
@@ -5,7 +5,7 @@ export declare type DndState = {
|
|
|
5
5
|
cursor: Cursor;
|
|
6
6
|
dragIds: string[];
|
|
7
7
|
parentId: null | string;
|
|
8
|
-
index: number;
|
|
8
|
+
index: number | null;
|
|
9
9
|
};
|
|
10
10
|
export declare const actions: {
|
|
11
11
|
cursor(cursor: Cursor): {
|
|
@@ -20,10 +20,10 @@ export declare const actions: {
|
|
|
20
20
|
dragEnd(): {
|
|
21
21
|
type: "DND_DRAG_END";
|
|
22
22
|
};
|
|
23
|
-
hovering(parentId: string | null, index: number): {
|
|
23
|
+
hovering(parentId: string | null, index: number | null): {
|
|
24
24
|
type: "DND_HOVERING";
|
|
25
25
|
parentId: string | null;
|
|
26
|
-
index: number;
|
|
26
|
+
index: number | null;
|
|
27
27
|
};
|
|
28
28
|
};
|
|
29
29
|
export declare function reducer(state: DndState | undefined, action: ActionTypes<typeof actions>): DndState;
|
|
@@ -2,6 +2,8 @@ import { ActionTypes } from "../types/utils";
|
|
|
2
2
|
import { actions as dnd } from "./dnd-slice";
|
|
3
3
|
export declare type DragSlice = {
|
|
4
4
|
id: string | null;
|
|
5
|
-
|
|
5
|
+
selectedIds: string[];
|
|
6
|
+
destinationParentId: string | null;
|
|
7
|
+
destinationIndex: number | null;
|
|
6
8
|
};
|
|
7
9
|
export declare function reducer(state: DragSlice | undefined, action: ActionTypes<typeof dnd>): DragSlice;
|
package/dist/utils.d.ts
CHANGED
|
@@ -5,9 +5,9 @@ export declare function bound(n: number, min: number, max: number): number;
|
|
|
5
5
|
export declare function isItem(node: NodeApi<any> | null): boolean | null;
|
|
6
6
|
export declare function isClosed(node: NodeApi<any> | null): boolean | null;
|
|
7
7
|
/**
|
|
8
|
-
* Is first param a
|
|
8
|
+
* Is first param a descendant of the second param
|
|
9
9
|
*/
|
|
10
|
-
export declare const
|
|
10
|
+
export declare const isDescendant: (a: NodeApi<any>, b: NodeApi<any>) => boolean;
|
|
11
11
|
export declare const indexOf: (node: NodeApi<any>) => number;
|
|
12
12
|
export declare function noop(): void;
|
|
13
13
|
export declare function dfs(node: NodeApi<any>, id: string): NodeApi<any> | null;
|
package/package.json
CHANGED
package/src/dnd/compute-drop.ts
CHANGED
|
@@ -26,7 +26,7 @@ function getNodesAroundCursor(
|
|
|
26
26
|
hover: HoverData
|
|
27
27
|
): [NodeApi | null, NodeApi | null] {
|
|
28
28
|
if (!node) {
|
|
29
|
-
// We're
|
|
29
|
+
// We're hovering over the empty part of the list, not over an item,
|
|
30
30
|
// Put the cursor below the last item which is "prev"
|
|
31
31
|
return [prev, null];
|
|
32
32
|
}
|
|
@@ -83,7 +83,10 @@ export type ComputedDrop = {
|
|
|
83
83
|
cursor: Cursor | null;
|
|
84
84
|
};
|
|
85
85
|
|
|
86
|
-
function dropAt(
|
|
86
|
+
function dropAt(
|
|
87
|
+
parentId: string | undefined,
|
|
88
|
+
index: number | null
|
|
89
|
+
): DropResult {
|
|
87
90
|
return { parentId: parentId || null, index };
|
|
88
91
|
}
|
|
89
92
|
|
|
@@ -135,7 +138,7 @@ export function computeDrop(args: Args): ComputedDrop {
|
|
|
135
138
|
/* Hovering over the middle of a folder */
|
|
136
139
|
if (node && node.isInternal && hover.inMiddle) {
|
|
137
140
|
return {
|
|
138
|
-
drop: dropAt(node.id,
|
|
141
|
+
drop: dropAt(node.id, null),
|
|
139
142
|
cursor: highlightCursor(node.id),
|
|
140
143
|
};
|
|
141
144
|
}
|
package/src/dnd/drag-hook.ts
CHANGED
|
@@ -31,7 +31,7 @@ export function useDragHook<T>(node: NodeApi<T>): ConnectDragSource {
|
|
|
31
31
|
safeRun(tree.props.onMove, {
|
|
32
32
|
dragIds,
|
|
33
33
|
parentId: parentId === ROOT_ID ? null : parentId,
|
|
34
|
-
index,
|
|
34
|
+
index: index === null ? 0 : index, // When it's null it was dropped over a folder
|
|
35
35
|
dragNodes: tree.dragNodes,
|
|
36
36
|
parentNode: tree.get(parentId),
|
|
37
37
|
});
|
package/src/dnd/drop-hook.ts
CHANGED
|
@@ -130,6 +130,16 @@ export class NodeApi<T = any> {
|
|
|
130
130
|
return this.parent?.children![i + 1] ?? null;
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
isAncestorOf(node: NodeApi<T> | null) {
|
|
134
|
+
if (!node) return false;
|
|
135
|
+
let ancestor: NodeApi<T> | null = node;
|
|
136
|
+
while (ancestor) {
|
|
137
|
+
if (ancestor.id === this.id) return true;
|
|
138
|
+
ancestor = ancestor.parent;
|
|
139
|
+
}
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
|
|
133
143
|
select() {
|
|
134
144
|
this.tree.select(this);
|
|
135
145
|
}
|
|
@@ -419,6 +419,18 @@ export class TreeApi<T> {
|
|
|
419
419
|
.filter((n) => !!n) as NodeApi<T>[];
|
|
420
420
|
}
|
|
421
421
|
|
|
422
|
+
get dragNode() {
|
|
423
|
+
return this.get(this.state.nodes.drag.id);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
get dragDestinationParent() {
|
|
427
|
+
return this.get(this.state.nodes.drag.destinationParentId);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
get dragDestinationIndex() {
|
|
431
|
+
return this.state.nodes.drag.destinationIndex;
|
|
432
|
+
}
|
|
433
|
+
|
|
422
434
|
canDrop() {
|
|
423
435
|
if (this.isFiltered) return false;
|
|
424
436
|
const parentNode = this.get(this.state.dnd.parentId) ?? this.root;
|
|
@@ -428,7 +440,7 @@ export class TreeApi<T> {
|
|
|
428
440
|
for (const drag of dragNodes) {
|
|
429
441
|
if (!drag) return false;
|
|
430
442
|
if (!parentNode) return false;
|
|
431
|
-
if (drag.isInternal && utils.
|
|
443
|
+
if (drag.isInternal && utils.isDescendant(parentNode, drag)) return false;
|
|
432
444
|
}
|
|
433
445
|
|
|
434
446
|
// Allow the user to insert their own logic
|
|
@@ -436,7 +448,7 @@ export class TreeApi<T> {
|
|
|
436
448
|
return !isDisabled({
|
|
437
449
|
parentNode,
|
|
438
450
|
dragNodes: this.dragNodes,
|
|
439
|
-
index: this.state.dnd.index,
|
|
451
|
+
index: this.state.dnd.index || 0,
|
|
440
452
|
});
|
|
441
453
|
} else if (typeof isDisabled == "string") {
|
|
442
454
|
// @ts-ignore
|
|
@@ -606,7 +618,8 @@ export class TreeApi<T> {
|
|
|
606
618
|
willReceiveDrop(node: string | IdObj | null) {
|
|
607
619
|
const id = identifyNull(node);
|
|
608
620
|
if (!id) return false;
|
|
609
|
-
|
|
621
|
+
const { destinationParentId, destinationIndex } = this.state.nodes.drag;
|
|
622
|
+
return id === destinationParentId && destinationIndex === null;
|
|
610
623
|
}
|
|
611
624
|
|
|
612
625
|
/* Tree Event Handlers */
|
package/src/state/dnd-slice.ts
CHANGED
|
@@ -8,7 +8,7 @@ export type DndState = {
|
|
|
8
8
|
cursor: Cursor;
|
|
9
9
|
dragIds: string[];
|
|
10
10
|
parentId: null | string;
|
|
11
|
-
index: number;
|
|
11
|
+
index: number | null;
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
/* Actions */
|
|
@@ -22,7 +22,7 @@ export const actions = {
|
|
|
22
22
|
dragEnd() {
|
|
23
23
|
return { type: "DND_DRAG_END" as const };
|
|
24
24
|
},
|
|
25
|
-
hovering(parentId: string | null, index: number) {
|
|
25
|
+
hovering(parentId: string | null, index: number | null) {
|
|
26
26
|
return { type: "DND_HOVERING" as const, parentId, index };
|
|
27
27
|
},
|
|
28
28
|
};
|
package/src/state/drag-slice.ts
CHANGED
|
@@ -1,27 +1,43 @@
|
|
|
1
1
|
import { ActionTypes } from "../types/utils";
|
|
2
2
|
import { actions as dnd } from "./dnd-slice";
|
|
3
|
+
import { initialState } from "./initial";
|
|
3
4
|
|
|
4
5
|
/* Types */
|
|
5
6
|
|
|
6
|
-
export type DragSlice = {
|
|
7
|
+
export type DragSlice = {
|
|
8
|
+
id: string | null;
|
|
9
|
+
selectedIds: string[];
|
|
10
|
+
destinationParentId: string | null;
|
|
11
|
+
destinationIndex: number | null;
|
|
12
|
+
};
|
|
7
13
|
|
|
8
14
|
/* Reducer */
|
|
9
15
|
|
|
10
16
|
export function reducer(
|
|
11
|
-
state: DragSlice =
|
|
17
|
+
state: DragSlice = initialState().nodes.drag,
|
|
12
18
|
action: ActionTypes<typeof dnd>
|
|
13
|
-
) {
|
|
19
|
+
): DragSlice {
|
|
14
20
|
switch (action.type) {
|
|
15
21
|
case "DND_DRAG_START":
|
|
16
|
-
return { ...state, id: action.id };
|
|
22
|
+
return { ...state, id: action.id, selectedIds: action.dragIds };
|
|
17
23
|
case "DND_DRAG_END":
|
|
18
|
-
return {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
return {
|
|
25
|
+
...state,
|
|
26
|
+
id: null,
|
|
27
|
+
destinationParentId: null,
|
|
28
|
+
destinationIndex: null,
|
|
29
|
+
selectedIds: [],
|
|
30
|
+
};
|
|
31
|
+
case "DND_HOVERING":
|
|
32
|
+
if (
|
|
33
|
+
action.parentId !== state.destinationParentId ||
|
|
34
|
+
action.index != state.destinationIndex
|
|
35
|
+
) {
|
|
36
|
+
return {
|
|
37
|
+
...state,
|
|
38
|
+
destinationParentId: action.parentId,
|
|
39
|
+
destinationIndex: action.index,
|
|
40
|
+
};
|
|
25
41
|
} else {
|
|
26
42
|
return state;
|
|
27
43
|
}
|
package/src/state/initial.ts
CHANGED
|
@@ -7,7 +7,12 @@ export const initialState = (props?: TreeProps<any>): RootState => ({
|
|
|
7
7
|
open: { filtered: {}, unfiltered: props?.initialOpenState ?? {} },
|
|
8
8
|
focus: { id: null, treeFocused: false },
|
|
9
9
|
edit: { id: null },
|
|
10
|
-
drag: {
|
|
10
|
+
drag: {
|
|
11
|
+
id: null,
|
|
12
|
+
selectedIds: [],
|
|
13
|
+
destinationParentId: null,
|
|
14
|
+
destinationIndex: null,
|
|
15
|
+
},
|
|
11
16
|
selection: { ids: new Set(), anchor: null, mostRecent: null },
|
|
12
17
|
},
|
|
13
18
|
dnd: {
|
package/src/utils.ts
CHANGED
|
@@ -15,9 +15,9 @@ export function isClosed(node: NodeApi<any> | null) {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
* Is first param a
|
|
18
|
+
* Is first param a descendant of the second param
|
|
19
19
|
*/
|
|
20
|
-
export const
|
|
20
|
+
export const isDescendant = (a: NodeApi<any>, b: NodeApi<any>) => {
|
|
21
21
|
let n: NodeApi<any> | null = a;
|
|
22
22
|
while (n) {
|
|
23
23
|
if (n.id === b.id) return true;
|