react-arborist 2.1.1 → 2.3.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 +4 -3
- package/dist/index.js +40 -38
- package/dist/index.js.map +1 -1
- package/dist/interfaces/tree-api.d.ts +1 -0
- package/dist/module.js +40 -38
- package/dist/module.js.map +1 -1
- package/dist/types/tree-props.d.ts +2 -0
- package/package.json +3 -2
- package/src/components/default-container.tsx +35 -38
- package/src/components/row-container.tsx +1 -2
- package/src/interfaces/node-api.ts +2 -2
- package/src/interfaces/tree-api.ts +5 -1
- package/src/types/tree-props.ts +2 -0
|
@@ -18,6 +18,7 @@ export interface TreeProps<T> {
|
|
|
18
18
|
renderCursor?: ElementType<renderers.CursorProps>;
|
|
19
19
|
renderContainer?: ElementType<{}>;
|
|
20
20
|
rowHeight?: number;
|
|
21
|
+
overscanCount?: number;
|
|
21
22
|
width?: number | string;
|
|
22
23
|
height?: number;
|
|
23
24
|
indent?: number;
|
|
@@ -26,6 +27,7 @@ export interface TreeProps<T> {
|
|
|
26
27
|
padding?: number;
|
|
27
28
|
openByDefault?: boolean;
|
|
28
29
|
selectionFollowsFocus?: boolean;
|
|
30
|
+
disableMultiSelection?: boolean;
|
|
29
31
|
disableDrag?: string | boolean | BoolFunc<T>;
|
|
30
32
|
disableDrop?: string | boolean | BoolFunc<T>;
|
|
31
33
|
childrenAccessor?: string | ((d: T) => T[] | null);
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-arborist",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.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
|
-
"repository": "
|
|
9
|
+
"repository": "github:brimdata/react-arborist",
|
|
10
10
|
"homepage": "https://react-arborist.netlify.app",
|
|
11
|
+
"bugs": "https://github.com/brimdata/react-arborist/issues",
|
|
11
12
|
"keywords": [
|
|
12
13
|
"react",
|
|
13
14
|
"arborist",
|
|
@@ -73,44 +73,47 @@ export function DefaultContainer() {
|
|
|
73
73
|
focusPrevElement(e.currentTarget);
|
|
74
74
|
return;
|
|
75
75
|
}
|
|
76
|
-
if (e.key === "ArrowDown"
|
|
76
|
+
if (e.key === "ArrowDown") {
|
|
77
77
|
e.preventDefault();
|
|
78
78
|
const next = tree.nextNode;
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
e.
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const current = tree.focusedNode;
|
|
87
|
-
if (!current) {
|
|
88
|
-
tree.focus(tree.firstNode);
|
|
89
|
-
} else if (current.isSelected) {
|
|
90
|
-
tree.selectContiguous(next);
|
|
79
|
+
if (e.metaKey) {
|
|
80
|
+
tree.select(tree.focusedNode);
|
|
81
|
+
tree.activate(tree.focusedNode);
|
|
82
|
+
return;
|
|
83
|
+
} else if (!e.shiftKey || tree.props.disableMultiSelection) {
|
|
84
|
+
tree.focus(next);
|
|
85
|
+
return;
|
|
91
86
|
} else {
|
|
92
|
-
|
|
87
|
+
if (!next) return;
|
|
88
|
+
const current = tree.focusedNode;
|
|
89
|
+
if (!current) {
|
|
90
|
+
tree.focus(tree.firstNode);
|
|
91
|
+
} else if (current.isSelected) {
|
|
92
|
+
tree.selectContiguous(next);
|
|
93
|
+
} else {
|
|
94
|
+
tree.selectMulti(next);
|
|
95
|
+
}
|
|
96
|
+
return;
|
|
93
97
|
}
|
|
94
|
-
return;
|
|
95
98
|
}
|
|
96
|
-
if (e.key === "ArrowUp"
|
|
97
|
-
e.preventDefault();
|
|
98
|
-
tree.focus(tree.prevNode);
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
if (e.key === "ArrowUp" && e.shiftKey) {
|
|
99
|
+
if (e.key === "ArrowUp") {
|
|
102
100
|
e.preventDefault();
|
|
103
101
|
const prev = tree.prevNode;
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
tree.focus(tree.lastNode); // ?
|
|
108
|
-
} else if (current.isSelected) {
|
|
109
|
-
tree.selectContiguous(prev);
|
|
102
|
+
if (!e.shiftKey || tree.props.disableMultiSelection) {
|
|
103
|
+
tree.focus(prev);
|
|
104
|
+
return;
|
|
110
105
|
} else {
|
|
111
|
-
|
|
106
|
+
if (!prev) return;
|
|
107
|
+
const current = tree.focusedNode;
|
|
108
|
+
if (!current) {
|
|
109
|
+
tree.focus(tree.lastNode); // ?
|
|
110
|
+
} else if (current.isSelected) {
|
|
111
|
+
tree.selectContiguous(prev);
|
|
112
|
+
} else {
|
|
113
|
+
tree.selectMulti(prev);
|
|
114
|
+
}
|
|
115
|
+
return;
|
|
112
116
|
}
|
|
113
|
-
return;
|
|
114
117
|
}
|
|
115
118
|
if (e.key === "ArrowRight") {
|
|
116
119
|
const node = tree.focusedNode;
|
|
@@ -129,13 +132,12 @@ export function DefaultContainer() {
|
|
|
129
132
|
}
|
|
130
133
|
return;
|
|
131
134
|
}
|
|
132
|
-
if (e.key === "a" && e.metaKey) {
|
|
135
|
+
if (e.key === "a" && e.metaKey && !tree.props.disableMultiSelection) {
|
|
133
136
|
e.preventDefault();
|
|
134
137
|
tree.selectAll();
|
|
135
138
|
return;
|
|
136
139
|
}
|
|
137
|
-
if (e.key === "a" && !e.metaKey) {
|
|
138
|
-
if (!tree.props.onCreate) return;
|
|
140
|
+
if (e.key === "a" && !e.metaKey && tree.props.onCreate) {
|
|
139
141
|
tree.createLeaf();
|
|
140
142
|
return;
|
|
141
143
|
}
|
|
@@ -182,12 +184,6 @@ export function DefaultContainer() {
|
|
|
182
184
|
tree.openSiblings(node);
|
|
183
185
|
return;
|
|
184
186
|
}
|
|
185
|
-
if (e.key === "ArrowDown" && e.metaKey) {
|
|
186
|
-
e.preventDefault();
|
|
187
|
-
tree.select(tree.focusedNode);
|
|
188
|
-
tree.activate(tree.focusedNode);
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
187
|
if (e.key === "PageUp") {
|
|
192
188
|
e.preventDefault();
|
|
193
189
|
tree.pageUp();
|
|
@@ -224,6 +220,7 @@ export function DefaultContainer() {
|
|
|
224
220
|
height={tree.height}
|
|
225
221
|
width={tree.width}
|
|
226
222
|
itemSize={tree.rowHeight}
|
|
223
|
+
overscanCount={tree.overscanCount}
|
|
227
224
|
itemKey={(index) => tree.visibleNodes[index]?.id || index}
|
|
228
225
|
outerElementType={ListOuterElement}
|
|
229
226
|
innerElementType={ListInnerElement}
|
|
@@ -2,7 +2,6 @@ import React, { useCallback, useEffect, useMemo, useRef } from "react";
|
|
|
2
2
|
import { useDataUpdates, useNodesContext, useTreeApi } from "../context";
|
|
3
3
|
import { useDragHook } from "../dnd/drag-hook";
|
|
4
4
|
import { useDropHook } from "../dnd/drop-hook";
|
|
5
|
-
import { IdObj } from "../types/utils";
|
|
6
5
|
import { useFreshNode } from "../hooks/use-fresh-node";
|
|
7
6
|
|
|
8
7
|
type Props = {
|
|
@@ -68,7 +67,7 @@ export const RowContainer = React.memo(function RowContainer<T>({
|
|
|
68
67
|
|
|
69
68
|
useEffect(() => {
|
|
70
69
|
if (!node.isEditing && node.isFocused) {
|
|
71
|
-
el.current?.focus();
|
|
70
|
+
el.current?.focus({ preventScroll: true });
|
|
72
71
|
}
|
|
73
72
|
}, [node.isEditing, node.isFocused, el.current]);
|
|
74
73
|
|
|
@@ -186,9 +186,9 @@ export class NodeApi<T = any> {
|
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
handleClick = (e: React.MouseEvent) => {
|
|
189
|
-
if (e.metaKey) {
|
|
189
|
+
if (e.metaKey && !this.tree.props.disableMultiSelection) {
|
|
190
190
|
this.isSelected ? this.deselect() : this.selectMulti();
|
|
191
|
-
} else if (e.shiftKey) {
|
|
191
|
+
} else if (e.shiftKey && !this.tree.props.disableMultiSelection) {
|
|
192
192
|
this.selectContiguous();
|
|
193
193
|
} else {
|
|
194
194
|
this.select();
|
|
@@ -83,6 +83,10 @@ export class TreeApi<T> {
|
|
|
83
83
|
return this.props.rowHeight ?? 24;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
+
get overscanCount() {
|
|
87
|
+
return this.props.overscanCount ?? 1;
|
|
88
|
+
}
|
|
89
|
+
|
|
86
90
|
get searchTerm() {
|
|
87
91
|
return (this.props.searchTerm || "").trim();
|
|
88
92
|
}
|
|
@@ -479,7 +483,7 @@ export class TreeApi<T> {
|
|
|
479
483
|
this.list.current?.scrollToItem(index, align);
|
|
480
484
|
})
|
|
481
485
|
.catch(() => {
|
|
482
|
-
|
|
486
|
+
// Id: ${id} never appeared in the list.
|
|
483
487
|
});
|
|
484
488
|
}
|
|
485
489
|
|
package/src/types/tree-props.ts
CHANGED
|
@@ -26,6 +26,7 @@ export interface TreeProps<T> {
|
|
|
26
26
|
|
|
27
27
|
/* Sizes */
|
|
28
28
|
rowHeight?: number;
|
|
29
|
+
overscanCount?: number;
|
|
29
30
|
width?: number | string;
|
|
30
31
|
height?: number;
|
|
31
32
|
indent?: number;
|
|
@@ -36,6 +37,7 @@ export interface TreeProps<T> {
|
|
|
36
37
|
/* Config */
|
|
37
38
|
openByDefault?: boolean;
|
|
38
39
|
selectionFollowsFocus?: boolean;
|
|
40
|
+
disableMultiSelection?: boolean;
|
|
39
41
|
disableDrag?: string | boolean | BoolFunc<T>;
|
|
40
42
|
disableDrop?: string | boolean | BoolFunc<T>;
|
|
41
43
|
childrenAccessor?: string | ((d: T) => T[] | null);
|