@react-fabric/data 1.0.0-beta.6 → 1.0.0-beta.60
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/{src/histogram/Histogram.module.css → css/_histogram.css} +16 -13
- package/css/styles.css +24 -0
- package/dist/cjs/checklist/CheckList.js +23 -0
- package/dist/cjs/histogram/Histogram.js +37 -7
- package/dist/cjs/hooks/useFilteredList.js +88 -10
- package/dist/cjs/hooks/usePagination.js +27 -4
- package/dist/cjs/hooks/useSelectableList.js +29 -0
- package/dist/cjs/i18n/ar.json.js +8 -1
- package/dist/cjs/i18n/en.json.js +8 -1
- package/dist/cjs/json/JsonViewer.js +67 -27
- package/dist/cjs/pagination/Pagination.js +10 -0
- package/dist/cjs/table/AddColumn.js +1 -1
- package/dist/cjs/table/BodyCell.js +5 -4
- package/dist/cjs/table/BodyRow.js +2 -2
- package/dist/cjs/table/CheckboxCell.js +1 -1
- package/dist/cjs/table/ColumnFilters.js +97 -0
- package/dist/cjs/table/HeaderCell.js +71 -43
- package/dist/cjs/table/Table.js +58 -12
- package/dist/cjs/table/types.js +29 -0
- package/dist/cjs/table/useResizer.js +4 -4
- package/dist/cjs/table/useVirtualTable.js +127 -19
- package/dist/cjs/tree/TreeNode.js +48 -30
- package/dist/cjs/tree/TreePanel.js +45 -11
- package/dist/cjs/tree/useTree.js +199 -38
- package/dist/cjs/tree/utils.js +39 -12
- package/dist/cjs/virtual/Gallery.js +97 -45
- package/dist/cjs/virtual/List.js +93 -39
- package/dist/cjs/virtual/Scroller.js +16 -8
- package/dist/esm/checklist/CheckList.js +23 -0
- package/dist/esm/histogram/Histogram.js +38 -8
- package/dist/esm/hooks/useFilteredList.js +89 -11
- package/dist/esm/hooks/usePagination.js +27 -4
- package/dist/esm/hooks/useSelectableList.js +29 -0
- package/dist/esm/i18n/ar.json.js +8 -2
- package/dist/esm/i18n/en.json.js +8 -2
- package/dist/esm/json/JsonViewer.js +68 -28
- package/dist/esm/pagination/Pagination.js +10 -0
- package/dist/esm/table/AddColumn.js +1 -1
- package/dist/esm/table/BodyCell.js +5 -4
- package/dist/esm/table/BodyRow.js +2 -2
- package/dist/esm/table/CheckboxCell.js +1 -1
- package/dist/esm/table/ColumnFilters.js +97 -0
- package/dist/esm/table/HeaderCell.js +72 -44
- package/dist/esm/table/Table.js +59 -13
- package/dist/esm/table/types.js +29 -0
- package/dist/esm/table/useResizer.js +4 -4
- package/dist/esm/table/useVirtualTable.js +129 -21
- package/dist/esm/tree/TreeNode.js +51 -33
- package/dist/esm/tree/TreePanel.js +46 -12
- package/dist/esm/tree/useTree.js +202 -41
- package/dist/esm/tree/utils.js +40 -13
- package/dist/esm/virtual/Gallery.js +97 -45
- package/dist/esm/virtual/List.js +93 -39
- package/dist/esm/virtual/Scroller.js +16 -8
- package/dist/types/checklist/CheckList.d.ts +22 -0
- package/dist/types/histogram/Histogram.d.ts +28 -1
- package/dist/types/hooks/useFilteredList.d.ts +66 -5
- package/dist/types/hooks/usePagination.d.ts +19 -0
- package/dist/types/hooks/useSelectableList.d.ts +29 -0
- package/dist/types/json/JsonViewer.d.ts +27 -2
- package/dist/types/pagination/Pagination.d.ts +10 -1
- package/dist/types/table/ColumnFilters.d.ts +9 -0
- package/dist/types/table/HeaderCell.d.ts +1 -1
- package/dist/types/table/Table.d.ts +14 -1
- package/dist/types/table/types.d.ts +44 -5
- package/dist/types/table/useVirtualTable.d.ts +23 -9
- package/dist/types/tree/TreeNode.d.ts +1 -1
- package/dist/types/tree/TreePanel.d.ts +42 -1
- package/dist/types/tree/types.d.ts +65 -19
- package/dist/types/tree/useTree.d.ts +9 -10
- package/dist/types/tree/utils.d.ts +10 -3
- package/dist/types/virtual/Gallery.d.ts +42 -3
- package/dist/types/virtual/List.d.ts +42 -3
- package/package.json +16 -14
- package/src/checklist/CheckList.tsx +22 -0
- package/src/histogram/Histogram.tsx +40 -10
- package/src/hooks/useFilteredList.tsx +109 -9
- package/src/hooks/usePagination.tsx +32 -7
- package/src/hooks/useSelectableList.ts +29 -0
- package/src/i18n/ar.json +5 -0
- package/src/i18n/en.json +5 -0
- package/src/json/JsonViewer.tsx +71 -35
- package/src/pagination/Pagination.tsx +10 -0
- package/src/table/AddColumn.tsx +1 -1
- package/src/table/BodyCell.tsx +6 -4
- package/src/table/BodyRow.tsx +3 -2
- package/src/table/CheckboxCell.tsx +1 -1
- package/src/table/ColumnFilters.tsx +105 -0
- package/src/table/HeaderCell.tsx +72 -18
- package/src/table/Table.tsx +99 -11
- package/src/table/types.ts +46 -8
- package/src/table/useResizer.ts +5 -3
- package/src/table/useVirtualTable.ts +158 -27
- package/src/tree/TreeNode.tsx +98 -58
- package/src/tree/TreePanel.tsx +77 -6
- package/src/tree/types.ts +73 -18
- package/src/tree/useTree.ts +220 -44
- package/src/tree/utils.ts +58 -20
- package/src/virtual/Gallery.tsx +118 -54
- package/src/virtual/List.tsx +99 -39
- package/src/virtual/Scroller.tsx +16 -8
- package/dist/cjs/histogram/Histogram.module.css +0 -1
- package/dist/esm/histogram/Histogram.module.css +0 -1
package/src/tree/TreeNode.tsx
CHANGED
|
@@ -21,9 +21,17 @@
|
|
|
21
21
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
Badge,
|
|
26
|
+
CoreIcons,
|
|
27
|
+
getBadgeProps,
|
|
28
|
+
getIconProps,
|
|
29
|
+
Icon,
|
|
30
|
+
} from "@react-fabric/core";
|
|
31
|
+
import { isEmpty, isString } from "@react-fabric/utilities";
|
|
25
32
|
import classNames from "classnames";
|
|
26
|
-
import { useMemo } from "react";
|
|
33
|
+
import { isValidElement, useMemo } from "react";
|
|
34
|
+
import { useTranslation } from "react-i18next";
|
|
27
35
|
import { type TreeNodeProps } from "./types";
|
|
28
36
|
|
|
29
37
|
export const TreeNode = ({
|
|
@@ -35,36 +43,49 @@ export const TreeNode = ({
|
|
|
35
43
|
defaultLeafIcon,
|
|
36
44
|
defaultNodeIcon,
|
|
37
45
|
onToggle,
|
|
46
|
+
onClick,
|
|
38
47
|
onSelect,
|
|
39
48
|
onChecked,
|
|
40
49
|
children,
|
|
50
|
+
leafClassName,
|
|
51
|
+
nodeClassName,
|
|
41
52
|
}: TreeNodeProps) => {
|
|
53
|
+
const { t } = useTranslation("data");
|
|
42
54
|
const badgeProps = useMemo(() => {
|
|
43
55
|
return getBadgeProps(node.badge);
|
|
44
56
|
}, [node.badge]);
|
|
45
57
|
|
|
46
58
|
const filler = useMemo(() => {
|
|
47
|
-
return node.lines.slice(
|
|
48
|
-
<
|
|
59
|
+
return node.lines.slice(1).map((line, idx) => (
|
|
60
|
+
<div
|
|
49
61
|
key={idx}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
<path d="M14.989 12.389l0.161-0.389-0.161-0.389-0.389-0.161h-6.050v-13.55h-1.1v14.1l0.161 0.389 0.389 0.161h6.6z" />
|
|
57
|
-
)}
|
|
58
|
-
{!noLines && line === 3 && (
|
|
59
|
-
<path d="M8.55 12.55h6.050l0.389-0.161 0.161-0.389-0.161-0.389-0.389-0.161h-6.050v-13.55h-1.1v28.2h1.1z" />
|
|
62
|
+
className={classNames(
|
|
63
|
+
"flex-initial self-stretch flex items-center w-6 relative",
|
|
64
|
+
!noLines &&
|
|
65
|
+
line > 0 &&
|
|
66
|
+
"before:absolute before:top-0 before:start-[7px] before:bg-tint-200 before:min-h-[50%] before:w-0.5 before:scale-x-[.625]",
|
|
67
|
+
!noLines && line !== 2 && "before:h-full",
|
|
60
68
|
)}
|
|
61
|
-
|
|
69
|
+
>
|
|
70
|
+
<svg viewBox="0 0 24 24" className="fill-tint-200 rtl:-scale-x-100">
|
|
71
|
+
{line === 0 && <path d="" />}
|
|
72
|
+
{!noLines && line === 1 && (
|
|
73
|
+
<path d="M7.45 26.1v-28.2h1.1v28.2h-1.1z" />
|
|
74
|
+
)}
|
|
75
|
+
{!noLines && line === 2 && (
|
|
76
|
+
<path d="M14.989 12.389l0.161-0.389-0.161-0.389-0.389-0.161h-6.050v-13.55h-1.1v14.1l0.161 0.389 0.389 0.161h6.6z" />
|
|
77
|
+
)}
|
|
78
|
+
{!noLines && line === 3 && (
|
|
79
|
+
<path d="M8.55 12.55h6.050l0.389-0.161 0.161-0.389-0.161-0.389-0.389-0.161h-6.050v-13.55h-1.1v28.2h1.1z" />
|
|
80
|
+
)}
|
|
81
|
+
</svg>
|
|
82
|
+
</div>
|
|
62
83
|
));
|
|
63
84
|
}, [noLines, node.lines]);
|
|
64
85
|
|
|
65
86
|
const nodeIcon = useMemo(() => {
|
|
66
87
|
if (node.icon) return node.icon;
|
|
67
|
-
return node.leaf ? defaultLeafIcon : defaultNodeIcon;
|
|
88
|
+
return { icon: node.leaf ? defaultLeafIcon : defaultNodeIcon };
|
|
68
89
|
}, [defaultLeafIcon, defaultNodeIcon, node.icon]);
|
|
69
90
|
|
|
70
91
|
const canCheck = useMemo(() => {
|
|
@@ -82,12 +103,18 @@ export const TreeNode = ({
|
|
|
82
103
|
<div
|
|
83
104
|
role="treeitem"
|
|
84
105
|
aria-selected={node.selected}
|
|
85
|
-
className="flex flex-nowrap"
|
|
106
|
+
className={classNames("flex flex-nowrap items-center")}
|
|
86
107
|
data-testid={node["data-testid"]}
|
|
87
108
|
data-test-value={node["data-test-value"]}
|
|
109
|
+
data-id={node.id}
|
|
88
110
|
>
|
|
89
111
|
{filler}
|
|
90
|
-
{
|
|
112
|
+
{node.loading && (
|
|
113
|
+
<div className="flex-initial w-6">
|
|
114
|
+
<Icon icon={CoreIcons.spinner} className="animate-spin text-muted" />
|
|
115
|
+
</div>
|
|
116
|
+
)}
|
|
117
|
+
{!node.leaf && !node.childFiltered && !node.loading && (
|
|
91
118
|
<div className="flex-initial w-6">
|
|
92
119
|
<Icon
|
|
93
120
|
rtlFlip
|
|
@@ -116,48 +143,61 @@ export const TreeNode = ({
|
|
|
116
143
|
/>
|
|
117
144
|
</div>
|
|
118
145
|
)}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
146
|
+
{!node.empty && (
|
|
147
|
+
<div
|
|
148
|
+
role="none"
|
|
149
|
+
className={classNames(
|
|
150
|
+
"group/tool data-selected:bg-primary-100 flex flex-nowrap flex-1 overflow-hidden select-none",
|
|
151
|
+
node.childSelected && "font-medium",
|
|
152
|
+
node.disabled && "text-muted opacity-65",
|
|
153
|
+
node.className,
|
|
154
|
+
node.leaf ? leafClassName : nodeClassName,
|
|
155
|
+
!node.disabled &&
|
|
156
|
+
(canSelect || onClick) &&
|
|
157
|
+
"hover:bg-primary-50 cursor-pointer",
|
|
158
|
+
)}
|
|
159
|
+
data-selected={node.selected}
|
|
160
|
+
onClick={
|
|
161
|
+
node.disabled
|
|
162
|
+
? undefined
|
|
163
|
+
: (e) => {
|
|
164
|
+
onClick?.(node.id, node.data);
|
|
165
|
+
canSelect
|
|
166
|
+
? onSelect(node.id, e.shiftKey)
|
|
167
|
+
: canCheck
|
|
168
|
+
? onChecked(node.id)
|
|
169
|
+
: onToggle(node.id);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
>
|
|
173
|
+
{nodeIcon && (
|
|
174
|
+
<div className="flex-content max-w-6 me-1 self-center leading-none">
|
|
175
|
+
{isValidElement(nodeIcon) && nodeIcon}
|
|
176
|
+
{isString(nodeIcon) && <Icon {...getIconProps(nodeIcon)} />}
|
|
177
|
+
</div>
|
|
178
|
+
)}
|
|
179
|
+
{node.childSelected && !node.open && (
|
|
180
|
+
<span className=" flex-content text-primary-500">•</span>
|
|
181
|
+
)}
|
|
182
|
+
<div role="none" className="flex-1 truncate">
|
|
183
|
+
{children}
|
|
143
184
|
</div>
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
185
|
+
{!isEmpty(node.badge) && (
|
|
186
|
+
<Badge
|
|
187
|
+
{...badgeProps}
|
|
188
|
+
className={classNames(
|
|
189
|
+
"me-1 self-center flex-content bg-opacity-50",
|
|
190
|
+
badgeProps.className,
|
|
191
|
+
)}
|
|
192
|
+
/>
|
|
193
|
+
)}
|
|
150
194
|
</div>
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
)}
|
|
158
|
-
/>
|
|
159
|
-
)}
|
|
160
|
-
</div>
|
|
195
|
+
)}
|
|
196
|
+
{node.empty && (
|
|
197
|
+
<div className="text-muted text-sm select-none">
|
|
198
|
+
{t("tree.noItems")}
|
|
199
|
+
</div>
|
|
200
|
+
)}
|
|
161
201
|
</div>
|
|
162
202
|
);
|
|
163
203
|
};
|
package/src/tree/TreePanel.tsx
CHANGED
|
@@ -31,13 +31,54 @@ import {
|
|
|
31
31
|
} from "@react-fabric/core";
|
|
32
32
|
import { Search } from "@react-fabric/form";
|
|
33
33
|
import { useVirtualizer } from "@tanstack/react-virtual";
|
|
34
|
-
import { useImperativeHandle, useMemo, useRef } from "react";
|
|
34
|
+
import { useEffect, useImperativeHandle, useMemo, useRef } from "react";
|
|
35
35
|
import { TreeNode } from "./TreeNode";
|
|
36
36
|
import { iconCollapseAll, iconExpandAll, type TreePanelProps } from "./types";
|
|
37
37
|
import { useTree } from "./useTree";
|
|
38
38
|
|
|
39
39
|
// TODO: implement keyboard handler for navigating tree
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* TreePanel component renders a virtualized tree structure with support for
|
|
43
|
+
* selection, expansion, and filtering. It allows for custom rendering of tree
|
|
44
|
+
* nodes and supports checkable nodes.
|
|
45
|
+
*
|
|
46
|
+
* @param {TreePanelProps<T>} props - The properties for the TreePanel component.
|
|
47
|
+
* @returns {JSX.Element} The rendered TreePanel component.
|
|
48
|
+
* @template T - The type of items in the tree, extending KeyValue.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```jsx
|
|
52
|
+
* <TreePanel
|
|
53
|
+
* items={items}
|
|
54
|
+
* selected={selectedItem}
|
|
55
|
+
* checked={checkedItems}
|
|
56
|
+
* checkable={true}
|
|
57
|
+
* renderer={(item) => <span>{item.name}</span>}
|
|
58
|
+
* searchable={true}
|
|
59
|
+
* selectable={true}
|
|
60
|
+
* matcher={(item, query) => item.name.toLowerCase().includes(query.toLowerCase())}
|
|
61
|
+
* filterPlaceholder="Search..."
|
|
62
|
+
* defaultLeafIcon={<Icon icon={CoreIcons.file} />}
|
|
63
|
+
* defaultNodeIcon={<Icon icon={CoreIcons.folder} />}
|
|
64
|
+
* expander="caret"
|
|
65
|
+
* onChecked={(checkedItems) => console.log(checkedItems)}
|
|
66
|
+
* onLoad={(id) => console.log(`Load children for ${id}`)}
|
|
67
|
+
* onQuery={(query) => console.log(`Query: ${query}`)}
|
|
68
|
+
* onSelect={(selectedItem) => console.log(selectedItem)}
|
|
69
|
+
* onClick={(item) => console.log(`Clicked on ${item.id}`)}
|
|
70
|
+
* sorter={(a, b) => a.label.localeCompare(b.label)}
|
|
71
|
+
* makeLabel={(item) => item.name}
|
|
72
|
+
* makeIcon={(item) => item.icon ? <Icon icon={item.icon} /> : null}
|
|
73
|
+
* defaultExpanded={["root"]}
|
|
74
|
+
* onExpandToggle={(id, expanded) => console.log(`Toggle expand for ${id}: ${expanded}`)}
|
|
75
|
+
* leafClassName="leaf-node"
|
|
76
|
+
* nodeClassName="tree-node"
|
|
77
|
+
* />
|
|
78
|
+
* ```
|
|
79
|
+
*
|
|
80
|
+
* @see {@link https://adarshpastakia.github.io/react-fabric/?path=/docs/data-treepanel--docs}
|
|
81
|
+
*/
|
|
41
82
|
export const TreePanel = <T extends KeyValue>({
|
|
42
83
|
ref,
|
|
43
84
|
items,
|
|
@@ -45,9 +86,9 @@ export const TreePanel = <T extends KeyValue>({
|
|
|
45
86
|
checked,
|
|
46
87
|
checkable,
|
|
47
88
|
noLines,
|
|
48
|
-
renderer,
|
|
49
89
|
searchable,
|
|
50
90
|
selectable,
|
|
91
|
+
multiple,
|
|
51
92
|
matcher,
|
|
52
93
|
filterPlaceholder,
|
|
53
94
|
defaultLeafIcon,
|
|
@@ -55,15 +96,27 @@ export const TreePanel = <T extends KeyValue>({
|
|
|
55
96
|
expander = "box",
|
|
56
97
|
onChecked,
|
|
57
98
|
onLoad,
|
|
99
|
+
onQuery,
|
|
58
100
|
onSelect,
|
|
101
|
+
onClick,
|
|
102
|
+
sorter,
|
|
103
|
+
makeLabel,
|
|
104
|
+
makeIcon,
|
|
105
|
+
defaultExpanded,
|
|
106
|
+
onExpandToggle,
|
|
107
|
+
leafClassName,
|
|
108
|
+
nodeClassName,
|
|
59
109
|
...aria
|
|
60
110
|
}: TreePanelProps<T>) => {
|
|
61
111
|
const {
|
|
62
112
|
tree,
|
|
113
|
+
query,
|
|
114
|
+
selected: currentSelected,
|
|
63
115
|
toggleExpand,
|
|
64
116
|
toggleCheck,
|
|
65
117
|
expandAll,
|
|
66
118
|
collapseAll,
|
|
119
|
+
expandAndLoad,
|
|
67
120
|
select,
|
|
68
121
|
expand,
|
|
69
122
|
onFilter,
|
|
@@ -71,10 +124,16 @@ export const TreePanel = <T extends KeyValue>({
|
|
|
71
124
|
items,
|
|
72
125
|
checked,
|
|
73
126
|
selected,
|
|
127
|
+
multiple,
|
|
74
128
|
matcher,
|
|
129
|
+
sorter,
|
|
130
|
+
onLoad,
|
|
131
|
+
onQuery,
|
|
75
132
|
onSelect,
|
|
76
133
|
onChecked,
|
|
77
|
-
|
|
134
|
+
defaultExpanded,
|
|
135
|
+
onExpandToggle,
|
|
136
|
+
} as any);
|
|
78
137
|
|
|
79
138
|
const scrollerRef = useRef<HTMLDivElement>(null);
|
|
80
139
|
const virtualizer = useVirtualizer({
|
|
@@ -99,11 +158,17 @@ export const TreePanel = <T extends KeyValue>({
|
|
|
99
158
|
ref,
|
|
100
159
|
() => ({
|
|
101
160
|
open: (id: string) => expand(id),
|
|
102
|
-
|
|
161
|
+
openAndLoad: (list: string[]) => expandAndLoad(list),
|
|
162
|
+
select: (id: string) => select(id),
|
|
103
163
|
}),
|
|
104
164
|
[],
|
|
105
165
|
);
|
|
106
166
|
|
|
167
|
+
useEffect(() => {
|
|
168
|
+
const index = tree.findIndex((n) => n.id === currentSelected);
|
|
169
|
+
virtualizer.scrollToIndex(index, { align: "auto" });
|
|
170
|
+
}, [currentSelected]);
|
|
171
|
+
|
|
107
172
|
return (
|
|
108
173
|
<Section>
|
|
109
174
|
<Header
|
|
@@ -112,6 +177,7 @@ export const TreePanel = <T extends KeyValue>({
|
|
|
112
177
|
>
|
|
113
178
|
{searchable && (
|
|
114
179
|
<Search
|
|
180
|
+
value={query}
|
|
115
181
|
onSearch={onFilter}
|
|
116
182
|
allowClear
|
|
117
183
|
placeholder={filterPlaceholder}
|
|
@@ -151,12 +217,17 @@ export const TreePanel = <T extends KeyValue>({
|
|
|
151
217
|
checkable={checkable}
|
|
152
218
|
selectable={selectable}
|
|
153
219
|
defaultLeafIcon={defaultLeafIcon}
|
|
154
|
-
defaultNodeIcon={
|
|
220
|
+
defaultNodeIcon={
|
|
221
|
+
makeIcon?.(tree[index].data) ?? defaultNodeIcon
|
|
222
|
+
}
|
|
155
223
|
onToggle={toggleExpand}
|
|
156
224
|
onChecked={toggleCheck}
|
|
157
225
|
onSelect={select}
|
|
226
|
+
onClick={onClick}
|
|
227
|
+
leafClassName={leafClassName}
|
|
228
|
+
nodeClassName={nodeClassName}
|
|
158
229
|
>
|
|
159
|
-
{(tree[index].data &&
|
|
230
|
+
{(tree[index].data && makeLabel?.(tree[index].data)) ??
|
|
160
231
|
tree[index].label}
|
|
161
232
|
</TreeNode>
|
|
162
233
|
</div>
|
package/src/tree/types.ts
CHANGED
|
@@ -21,22 +21,26 @@
|
|
|
21
21
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
+
import { type IconProps } from "@react-fabric/core/dist/types/components/icon/Icon";
|
|
24
25
|
import {
|
|
25
26
|
type BadgeType,
|
|
26
27
|
type ChildProp,
|
|
27
28
|
type CssProp,
|
|
28
29
|
type Elements,
|
|
29
|
-
type IconProps,
|
|
30
30
|
type RefProp,
|
|
31
31
|
type TestProps,
|
|
32
32
|
} from "@react-fabric/core/dist/types/types";
|
|
33
33
|
|
|
34
|
-
interface TreeBaseNode<T> extends
|
|
34
|
+
interface TreeBaseNode<T> extends CssProp, TestProps {
|
|
35
35
|
id: string;
|
|
36
36
|
/**
|
|
37
37
|
* display label
|
|
38
38
|
*/
|
|
39
39
|
label: Elements<JSX.Element>;
|
|
40
|
+
/**
|
|
41
|
+
* icon path or props
|
|
42
|
+
*/
|
|
43
|
+
icon?: IconProps;
|
|
40
44
|
/**
|
|
41
45
|
* full text to be used for querying purposes
|
|
42
46
|
*/
|
|
@@ -60,14 +64,14 @@ export type TreeNodeType<T extends KeyValue = KeyValue> = TreeBaseNode<T> &
|
|
|
60
64
|
(
|
|
61
65
|
| { leaf: true; children?: never }
|
|
62
66
|
| {
|
|
63
|
-
leaf?:
|
|
67
|
+
leaf?: boolean;
|
|
64
68
|
children?: Array<TreeNodeType<T>>;
|
|
65
69
|
open?: boolean;
|
|
66
70
|
iconOpen?: string;
|
|
67
71
|
}
|
|
68
72
|
);
|
|
69
73
|
|
|
70
|
-
export interface InternalNode extends
|
|
74
|
+
export interface InternalNode extends CssProp, TestProps {
|
|
71
75
|
id: string;
|
|
72
76
|
label: Elements<JSX.Element>;
|
|
73
77
|
queryable?: string;
|
|
@@ -84,6 +88,7 @@ export interface InternalNode extends IconProps, CssProp, TestProps {
|
|
|
84
88
|
loaded: boolean;
|
|
85
89
|
parent?: string;
|
|
86
90
|
empty?: boolean;
|
|
91
|
+
icon?: IconProps;
|
|
87
92
|
errored?: string;
|
|
88
93
|
selected?: true;
|
|
89
94
|
childSelected?: true;
|
|
@@ -96,22 +101,59 @@ export interface InternalNode extends IconProps, CssProp, TestProps {
|
|
|
96
101
|
export interface TreeNodeProps extends ChildProp {
|
|
97
102
|
node: InternalNode;
|
|
98
103
|
expanders: [string, string];
|
|
99
|
-
defaultNodeIcon?:
|
|
100
|
-
defaultLeafIcon?:
|
|
104
|
+
defaultNodeIcon?: Elements<JSX.Element>;
|
|
105
|
+
defaultLeafIcon?: Elements<JSX.Element>;
|
|
101
106
|
noLines?: boolean;
|
|
102
107
|
selectable?: true | "leafOnly";
|
|
103
108
|
checkable?: true | "leafOnly";
|
|
109
|
+
leafClassName?: string;
|
|
110
|
+
nodeClassName?: string;
|
|
104
111
|
onToggle: (id: string) => void;
|
|
105
|
-
onSelect: (id: string) => void;
|
|
112
|
+
onSelect: (id: string, shiftKey?: boolean) => void;
|
|
106
113
|
onChecked: (id: string) => void;
|
|
114
|
+
onClick?: (id: string, node: any) => void;
|
|
107
115
|
}
|
|
108
116
|
|
|
109
117
|
export interface TreeRef {
|
|
110
118
|
select: (id: string) => void;
|
|
111
119
|
open: (id: string) => void;
|
|
120
|
+
openAndLoad: (list: string[]) => void;
|
|
112
121
|
}
|
|
113
122
|
|
|
114
|
-
export
|
|
123
|
+
export type TreePanelProps<T extends KeyValue = KeyValue> =
|
|
124
|
+
BaseTreePanelProps<T> &
|
|
125
|
+
(
|
|
126
|
+
| {
|
|
127
|
+
/**
|
|
128
|
+
* enable multi select
|
|
129
|
+
*/
|
|
130
|
+
multiple?: never | false;
|
|
131
|
+
/**
|
|
132
|
+
* selected item id
|
|
133
|
+
*/
|
|
134
|
+
selected?: string;
|
|
135
|
+
/**
|
|
136
|
+
* callback on selection of tree node
|
|
137
|
+
*/
|
|
138
|
+
onSelect?: (id: string, data: T) => void;
|
|
139
|
+
}
|
|
140
|
+
| {
|
|
141
|
+
/**
|
|
142
|
+
* enable multi select
|
|
143
|
+
*/
|
|
144
|
+
multiple: true;
|
|
145
|
+
/**
|
|
146
|
+
* selected item id
|
|
147
|
+
*/
|
|
148
|
+
selected?: string[];
|
|
149
|
+
/**
|
|
150
|
+
* callback on selection of tree node
|
|
151
|
+
*/
|
|
152
|
+
onSelect?: (id: string[], data: T) => void;
|
|
153
|
+
}
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
interface BaseTreePanelProps<T extends KeyValue = KeyValue>
|
|
115
157
|
extends TestProps,
|
|
116
158
|
RefProp<TreeRef> {
|
|
117
159
|
items?: Array<TreeNodeType<T>>;
|
|
@@ -128,13 +170,13 @@ export interface TreePanelProps<T extends KeyValue = KeyValue>
|
|
|
128
170
|
*/
|
|
129
171
|
selectable?: true | "leafOnly";
|
|
130
172
|
/**
|
|
131
|
-
* enable
|
|
173
|
+
* enable multi select
|
|
132
174
|
*/
|
|
133
|
-
|
|
175
|
+
multiple?: boolean;
|
|
134
176
|
/**
|
|
135
|
-
*
|
|
177
|
+
* enable checkable
|
|
136
178
|
*/
|
|
137
|
-
|
|
179
|
+
checkable?: true | "leafOnly";
|
|
138
180
|
/**
|
|
139
181
|
* checked items
|
|
140
182
|
*/
|
|
@@ -165,21 +207,34 @@ export interface TreePanelProps<T extends KeyValue = KeyValue>
|
|
|
165
207
|
| Array<TreeNodeType<T>>
|
|
166
208
|
| undefined;
|
|
167
209
|
/**
|
|
168
|
-
* callback
|
|
210
|
+
* callback to load tree using search query
|
|
169
211
|
*/
|
|
170
|
-
|
|
212
|
+
onQuery?: (query: string) => void;
|
|
171
213
|
/**
|
|
172
|
-
* callback on
|
|
214
|
+
* callback on click of tree node
|
|
173
215
|
*/
|
|
174
|
-
|
|
216
|
+
onClick?: (id: string, data: T) => void;
|
|
175
217
|
/**
|
|
176
|
-
*
|
|
218
|
+
* callback on change of checked list
|
|
219
|
+
* @param leafs - list of checked leaf nodes
|
|
220
|
+
* @param nodes - list of checked nodes
|
|
221
|
+
* @param partials - list of partially checked nodes
|
|
177
222
|
*/
|
|
178
|
-
|
|
223
|
+
onChecked?: (leafs: string[], nodes: string[], partials: string[]) => void;
|
|
179
224
|
/**
|
|
180
225
|
* item filter matcher
|
|
181
226
|
*/
|
|
182
227
|
matcher?: (data: T, query: string) => boolean;
|
|
228
|
+
|
|
229
|
+
sorter?: false | ((a: T, b: T) => number);
|
|
230
|
+
makeLabel?: (node: T) => Elements<JSX.Element>;
|
|
231
|
+
makeIcon?: (node: T) => Elements<JSX.Element>;
|
|
232
|
+
|
|
233
|
+
defaultExpanded?: string[];
|
|
234
|
+
onExpandToggle?: (id: string[]) => void;
|
|
235
|
+
|
|
236
|
+
leafClassName?: string;
|
|
237
|
+
nodeClassName?: string;
|
|
183
238
|
}
|
|
184
239
|
|
|
185
240
|
export const iconExpandAll =
|