react-arborist 3.0.2 → 3.1.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/README.md +1 -0
- package/dist/index.js +26 -14
- package/dist/index.js.map +1 -1
- package/dist/interfaces/tree-api.d.ts +1 -0
- package/dist/module.js +26 -14
- package/dist/module.js.map +1 -1
- package/dist/types/tree-props.d.ts +2 -0
- package/package.json +3 -2
- package/src/components/provider.tsx +2 -1
- package/src/data/create-list.ts +23 -12
- package/src/interfaces/tree-api.ts +6 -3
- package/src/types/tree-props.ts +2 -0
|
@@ -5,6 +5,7 @@ import { ElementType, MouseEventHandler } from "react";
|
|
|
5
5
|
import { ListOnScrollProps } from "react-window";
|
|
6
6
|
import { NodeApi } from "../interfaces/node-api";
|
|
7
7
|
import { OpenMap } from "../state/open-slice";
|
|
8
|
+
import { useDragDropManager } from "react-dnd";
|
|
8
9
|
export interface TreeProps<T> {
|
|
9
10
|
data?: readonly T[];
|
|
10
11
|
initialData?: readonly T[];
|
|
@@ -51,4 +52,5 @@ export interface TreeProps<T> {
|
|
|
51
52
|
dndRootElement?: globalThis.Node | null;
|
|
52
53
|
onClick?: MouseEventHandler;
|
|
53
54
|
onContextMenu?: MouseEventHandler;
|
|
55
|
+
dndManager?: ReturnType<typeof useDragDropManager>;
|
|
54
56
|
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-arborist",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"source": "src/index.ts",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/module.js",
|
|
8
8
|
"types": "dist/index.d.ts",
|
|
9
|
+
"sideEffects": false,
|
|
9
10
|
"scripts": {
|
|
10
|
-
"start": "run-p '
|
|
11
|
+
"start": "run-p 'start:**'",
|
|
11
12
|
"build": "npm-run-all clean -p 'build:**'",
|
|
12
13
|
"test": "jest",
|
|
13
14
|
"build:js": "parcel build --target main --target module",
|
|
@@ -65,7 +65,7 @@ export function TreeProvider<T>({
|
|
|
65
65
|
/* Change selection based on props */
|
|
66
66
|
useEffect(() => {
|
|
67
67
|
if (api.props.selection) {
|
|
68
|
-
api.select(api.props.selection);
|
|
68
|
+
api.select(api.props.selection, { focus: false });
|
|
69
69
|
} else {
|
|
70
70
|
api.deselectAll();
|
|
71
71
|
}
|
|
@@ -86,6 +86,7 @@ export function TreeProvider<T>({
|
|
|
86
86
|
<DndProvider
|
|
87
87
|
backend={HTML5Backend}
|
|
88
88
|
options={{ rootElement: api.props.dndRootElement || undefined }}
|
|
89
|
+
{...(treeProps.dndManager && { manager: treeProps.dndManager })}
|
|
89
90
|
>
|
|
90
91
|
{children}
|
|
91
92
|
</DndProvider>
|
package/src/data/create-list.ts
CHANGED
|
@@ -29,24 +29,35 @@ function flattenAndFilterTree<T>(
|
|
|
29
29
|
root: NodeApi<T>,
|
|
30
30
|
isMatch: (n: NodeApi<T>) => boolean
|
|
31
31
|
): NodeApi<T>[] {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const yes = !node.isRoot && isMatch(node);
|
|
32
|
+
const matches: Record<string, boolean> = {};
|
|
33
|
+
const list: NodeApi<T>[] = [];
|
|
35
34
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
function markMatch(node: NodeApi<T>) {
|
|
36
|
+
const yes = !node.isRoot && isMatch(node);
|
|
37
|
+
if (yes) {
|
|
38
|
+
matches[node.id] = true;
|
|
39
|
+
let parent = node.parent;
|
|
40
|
+
while (parent) {
|
|
41
|
+
matches[parent.id] = true;
|
|
42
|
+
parent = parent.parent;
|
|
39
43
|
}
|
|
40
44
|
}
|
|
41
|
-
if (
|
|
42
|
-
|
|
43
|
-
return result;
|
|
45
|
+
if (node.children) {
|
|
46
|
+
for (let child of node.children) markMatch(child);
|
|
44
47
|
}
|
|
45
|
-
if (yes) return [node];
|
|
46
|
-
else return [];
|
|
47
48
|
}
|
|
48
49
|
|
|
49
|
-
|
|
50
|
+
function collect(node: NodeApi<T>) {
|
|
51
|
+
if (node.level >= 0 && matches[node.id]) {
|
|
52
|
+
list.push(node);
|
|
53
|
+
}
|
|
54
|
+
if (node.isOpen) {
|
|
55
|
+
node.children?.forEach(collect);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
markMatch(root);
|
|
60
|
+
collect(root);
|
|
50
61
|
list.forEach(assignRowIndex);
|
|
51
62
|
return list;
|
|
52
63
|
}
|
|
@@ -323,15 +323,18 @@ export class TreeApi<T> {
|
|
|
323
323
|
this.focus(this.at(index));
|
|
324
324
|
}
|
|
325
325
|
|
|
326
|
-
select(node: Identity, opts: { align?: Align } = {}) {
|
|
326
|
+
select(node: Identity, opts: { align?: Align; focus?: boolean } = {}) {
|
|
327
327
|
if (!node) return;
|
|
328
|
+
const changeFocus = opts.focus !== false;
|
|
328
329
|
const id = identify(node);
|
|
329
|
-
this.dispatch(focus(id));
|
|
330
|
+
if (changeFocus) this.dispatch(focus(id));
|
|
330
331
|
this.dispatch(selection.only(id));
|
|
331
332
|
this.dispatch(selection.anchor(id));
|
|
332
333
|
this.dispatch(selection.mostRecent(id));
|
|
333
334
|
this.scrollTo(id, opts.align);
|
|
334
|
-
if (this.focusedNode
|
|
335
|
+
if (this.focusedNode && changeFocus) {
|
|
336
|
+
safeRun(this.props.onFocus, this.focusedNode);
|
|
337
|
+
}
|
|
335
338
|
safeRun(this.props.onSelect, this.selectedNodes);
|
|
336
339
|
}
|
|
337
340
|
|
package/src/types/tree-props.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { ElementType, MouseEventHandler } from "react";
|
|
|
5
5
|
import { ListOnScrollProps } from "react-window";
|
|
6
6
|
import { NodeApi } from "../interfaces/node-api";
|
|
7
7
|
import { OpenMap } from "../state/open-slice";
|
|
8
|
+
import { useDragDropManager } from "react-dnd"
|
|
8
9
|
|
|
9
10
|
export interface TreeProps<T> {
|
|
10
11
|
/* Data Options */
|
|
@@ -75,4 +76,5 @@ export interface TreeProps<T> {
|
|
|
75
76
|
dndRootElement?: globalThis.Node | null;
|
|
76
77
|
onClick?: MouseEventHandler;
|
|
77
78
|
onContextMenu?: MouseEventHandler;
|
|
79
|
+
dndManager?: ReturnType<typeof useDragDropManager>
|
|
78
80
|
}
|