@react-fabric/data 1.0.0-beta.25 → 1.0.0-beta.27
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/cjs/tree/TreeNode.js +24 -12
- package/dist/cjs/tree/TreePanel.js +26 -10
- package/dist/cjs/tree/useTree.js +85 -11
- package/dist/cjs/tree/utils.js +13 -4
- package/dist/esm/tree/TreeNode.js +25 -13
- package/dist/esm/tree/TreePanel.js +26 -10
- package/dist/esm/tree/useTree.js +87 -13
- package/dist/esm/tree/utils.js +13 -4
- package/dist/types/tree/TreeNode.d.ts +1 -1
- package/dist/types/tree/TreePanel.d.ts +1 -1
- package/dist/types/tree/types.d.ts +21 -5
- package/dist/types/tree/useTree.d.ts +2 -9
- package/dist/types/tree/utils.d.ts +4 -1
- package/package.json +8 -8
- package/src/tree/TreeNode.tsx +41 -18
- package/src/tree/TreePanel.tsx +21 -3
- package/src/tree/types.ts +28 -4
- package/src/tree/useTree.ts +93 -20
- package/src/tree/utils.ts +16 -8
package/dist/esm/tree/useTree.js
CHANGED
|
@@ -5,8 +5,8 @@ import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
|
|
|
5
5
|
import { useDebounce } from '@react-fabric/core';
|
|
6
6
|
import { EMPTY_ARRAY } from '@react-fabric/utilities';
|
|
7
7
|
import memoizeOne from 'memoize-one';
|
|
8
|
-
import { useRef, useReducer, useEffect
|
|
9
|
-
import { refactorTree, makeTreeMap, flattenTree,
|
|
8
|
+
import { useRef, useCallback, useReducer, useEffect } from 'react';
|
|
9
|
+
import { refactorTree, makeTreeMap, flattenTree, updateSelection, filterTree, updateChecked } from './utils.js';
|
|
10
10
|
|
|
11
11
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
12
12
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
@@ -19,39 +19,107 @@ var useTree = function useTree(_ref) {
|
|
|
19
19
|
_ref$checked = _ref.checked,
|
|
20
20
|
checked = _ref$checked === void 0 ? EMPTY_ARRAY : _ref$checked,
|
|
21
21
|
selected = _ref.selected,
|
|
22
|
+
sorter = _ref.sorter,
|
|
22
23
|
matcher = _ref.matcher,
|
|
24
|
+
onLoad = _ref.onLoad,
|
|
23
25
|
onSelect = _ref.onSelect,
|
|
24
|
-
onChecked = _ref.onChecked
|
|
26
|
+
onChecked = _ref.onChecked,
|
|
27
|
+
defaultExpanded = _ref.defaultExpanded,
|
|
28
|
+
onExpandToggle = _ref.onExpandToggle;
|
|
25
29
|
var componentEvents = useRef({
|
|
26
30
|
onSelect: onSelect,
|
|
27
31
|
onChecked: onChecked
|
|
28
32
|
});
|
|
33
|
+
var intialExpand = useRef(defaultExpanded !== null && defaultExpanded !== void 0 ? defaultExpanded : EMPTY_ARRAY);
|
|
29
34
|
var itemList = createItemList(items);
|
|
35
|
+
var fireExpandToggle = useCallback(function (itemMap) {
|
|
36
|
+
var expandedList = itemMap.filter(function (node) {
|
|
37
|
+
return node.open;
|
|
38
|
+
}).map(function (node) {
|
|
39
|
+
return node.id;
|
|
40
|
+
});
|
|
41
|
+
onExpandToggle === null || onExpandToggle === void 0 || onExpandToggle(expandedList);
|
|
42
|
+
}, [onExpandToggle]);
|
|
43
|
+
var loadChildren = useCallback(function (node) {
|
|
44
|
+
var _node$children;
|
|
45
|
+
if (node.open && !node.leaf && !((_node$children = node.children) !== null && _node$children !== void 0 && _node$children.length)) {
|
|
46
|
+
node.loading = true;
|
|
47
|
+
void Promise.resolve(onLoad === null || onLoad === void 0 ? void 0 : onLoad(node.id)).then(function () {
|
|
48
|
+
var resp = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : EMPTY_ARRAY;
|
|
49
|
+
node.children = refactorTree(resp, {
|
|
50
|
+
sorter: sorter,
|
|
51
|
+
defaultExpanded: defaultExpanded
|
|
52
|
+
}, {
|
|
53
|
+
level: node.level + 1,
|
|
54
|
+
parent: node.id
|
|
55
|
+
});
|
|
56
|
+
})["finally"](function () {
|
|
57
|
+
var _intialExpand$current;
|
|
58
|
+
node.loading = false;
|
|
59
|
+
dispatch({
|
|
60
|
+
type: "loaded"
|
|
61
|
+
});
|
|
62
|
+
((_intialExpand$current = intialExpand.current) === null || _intialExpand$current === void 0 ? void 0 : _intialExpand$current.length) > 0 && dispatch({
|
|
63
|
+
type: "expand",
|
|
64
|
+
id: intialExpand.current.shift()
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
} else {
|
|
68
|
+
var _intialExpand$current2;
|
|
69
|
+
dispatch({
|
|
70
|
+
type: "loaded"
|
|
71
|
+
});
|
|
72
|
+
((_intialExpand$current2 = intialExpand.current) === null || _intialExpand$current2 === void 0 ? void 0 : _intialExpand$current2.length) > 0 && dispatch({
|
|
73
|
+
type: "expand",
|
|
74
|
+
id: intialExpand.current.shift()
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}, [onLoad]);
|
|
30
78
|
var _useReducer = useReducer(function (state, action) {
|
|
31
79
|
if (action.type === "load") {
|
|
32
|
-
state.items = refactorTree(action.items
|
|
80
|
+
state.items = refactorTree(action.items, {
|
|
81
|
+
sorter: sorter,
|
|
82
|
+
defaultExpanded: defaultExpanded
|
|
83
|
+
});
|
|
33
84
|
state.itemMap = makeTreeMap(state.items);
|
|
34
85
|
state.tree = flattenTree(state.items);
|
|
35
86
|
return _objectSpread({}, state);
|
|
36
87
|
}
|
|
37
88
|
if (action.type === "toggleExpand") {
|
|
38
89
|
var node = state.itemMap.get(action.id);
|
|
39
|
-
|
|
90
|
+
if (node && !node.leaf) {
|
|
91
|
+
node && (node.open = !node.open);
|
|
92
|
+
loadChildren(node);
|
|
93
|
+
return _objectSpread({}, state);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (action.type === "loaded") {
|
|
97
|
+
state.itemMap = makeTreeMap(state.items);
|
|
98
|
+
fireExpandToggle(Array.from(state.itemMap.values()));
|
|
40
99
|
state.tree = flattenTree(state.items);
|
|
100
|
+
state.selected && updateSelection(state.itemMap, state.selected, true);
|
|
41
101
|
return _objectSpread({}, state);
|
|
42
102
|
}
|
|
43
103
|
if (action.type === "expand") {
|
|
44
|
-
// TODO: check if children available, if not call onLoad to fetch node children
|
|
45
104
|
var _node = state.itemMap.get(action.id);
|
|
46
|
-
_node &&
|
|
47
|
-
|
|
48
|
-
|
|
105
|
+
if (_node && !_node.leaf) {
|
|
106
|
+
_node.open = true;
|
|
107
|
+
var parentId = _node.parent;
|
|
108
|
+
while (parentId) {
|
|
109
|
+
var _node2 = state.itemMap.get(parentId);
|
|
110
|
+
_node2 && (_node2.open = true);
|
|
111
|
+
parentId = _node2 === null || _node2 === void 0 ? void 0 : _node2.parent;
|
|
112
|
+
}
|
|
113
|
+
loadChildren(_node);
|
|
114
|
+
return _objectSpread({}, state);
|
|
115
|
+
}
|
|
49
116
|
}
|
|
50
117
|
if (action.type === "expandAll") {
|
|
51
|
-
// TODO: prevent opening dynamic nodes that dont have children
|
|
52
118
|
state.itemMap.forEach(function (node) {
|
|
53
|
-
|
|
119
|
+
var _node$children2;
|
|
120
|
+
!node.leaf && ((_node$children2 = node.children) === null || _node$children2 === void 0 ? void 0 : _node$children2.length) && (node.open = true);
|
|
54
121
|
});
|
|
122
|
+
fireExpandToggle(Array.from(state.itemMap.values()));
|
|
55
123
|
state.tree = flattenTree(state.items);
|
|
56
124
|
return _objectSpread({}, state);
|
|
57
125
|
}
|
|
@@ -59,6 +127,7 @@ var useTree = function useTree(_ref) {
|
|
|
59
127
|
state.itemMap.forEach(function (node) {
|
|
60
128
|
!node.leaf && (node.open = false);
|
|
61
129
|
});
|
|
130
|
+
fireExpandToggle([]);
|
|
62
131
|
state.tree = flattenTree(state.items);
|
|
63
132
|
return _objectSpread({}, state);
|
|
64
133
|
}
|
|
@@ -68,13 +137,13 @@ var useTree = function useTree(_ref) {
|
|
|
68
137
|
return _objectSpread({}, state);
|
|
69
138
|
}
|
|
70
139
|
if (action.type === "select") {
|
|
71
|
-
var _componentEvents$curr, _componentEvents$curr2;
|
|
140
|
+
var _componentEvents$curr, _componentEvents$curr2, _state$itemMap$get;
|
|
72
141
|
if (state.selected) {
|
|
73
142
|
updateSelection(state.itemMap, state.selected);
|
|
74
143
|
}
|
|
75
144
|
updateSelection(state.itemMap, action.id, true);
|
|
76
145
|
state.tree = flattenTree(state.items);
|
|
77
|
-
(_componentEvents$curr = (_componentEvents$curr2 = componentEvents.current).onSelect) === null || _componentEvents$curr === void 0 || _componentEvents$curr.call(_componentEvents$curr2, action.id);
|
|
146
|
+
(_componentEvents$curr = (_componentEvents$curr2 = componentEvents.current).onSelect) === null || _componentEvents$curr === void 0 || _componentEvents$curr.call(_componentEvents$curr2, action.id, (_state$itemMap$get = state.itemMap.get(action.id)) === null || _state$itemMap$get === void 0 ? void 0 : _state$itemMap$get.data);
|
|
78
147
|
return _objectSpread(_objectSpread({}, state), {}, {
|
|
79
148
|
selected: action.id
|
|
80
149
|
});
|
|
@@ -116,10 +185,15 @@ var useTree = function useTree(_ref) {
|
|
|
116
185
|
};
|
|
117
186
|
}, [onSelect, onChecked]);
|
|
118
187
|
useEffect(function () {
|
|
188
|
+
var _intialExpand$current3;
|
|
119
189
|
dispatch({
|
|
120
190
|
type: "load",
|
|
121
191
|
items: itemList
|
|
122
192
|
});
|
|
193
|
+
((_intialExpand$current3 = intialExpand.current) === null || _intialExpand$current3 === void 0 ? void 0 : _intialExpand$current3.length) > 0 && dispatch({
|
|
194
|
+
type: "expand",
|
|
195
|
+
id: intialExpand.current.shift()
|
|
196
|
+
});
|
|
123
197
|
}, [itemList]);
|
|
124
198
|
useEffect(function () {
|
|
125
199
|
selected && dispatch({
|
package/dist/esm/tree/utils.js
CHANGED
|
@@ -6,7 +6,7 @@ import { isString, matchString, compareValues } from '@react-fabric/utilities';
|
|
|
6
6
|
|
|
7
7
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
8
8
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
9
|
-
var
|
|
9
|
+
var defaultSorter = function defaultSorter(a, b) {
|
|
10
10
|
if (!!a.leaf !== !!b.leaf) return a.leaf ? 1 : -1;
|
|
11
11
|
return compareValues()(a.label, b.label);
|
|
12
12
|
};
|
|
@@ -28,15 +28,21 @@ var getIntermediate = function getIntermediate() {
|
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
// convert node item to internal node used by the tree
|
|
31
|
-
var refactorTree = function refactorTree(nodes) {
|
|
32
|
-
var
|
|
31
|
+
var refactorTree = function refactorTree(nodes, _ref) {
|
|
32
|
+
var _ref$sorter = _ref.sorter,
|
|
33
|
+
sorter = _ref$sorter === void 0 ? defaultSorter : _ref$sorter,
|
|
34
|
+
_ref$defaultExpanded = _ref.defaultExpanded,
|
|
35
|
+
defaultExpanded = _ref$defaultExpanded === void 0 ? [] : _ref$defaultExpanded;
|
|
36
|
+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
|
|
33
37
|
level: 0,
|
|
34
38
|
parent: undefined
|
|
35
39
|
};
|
|
36
40
|
var list = [];
|
|
37
|
-
nodes.sort(sorter)
|
|
41
|
+
if (sorter !== false) nodes = nodes.sort(sorter);
|
|
42
|
+
nodes.forEach(function (node) {
|
|
38
43
|
list.push(_objectSpread(_objectSpread({
|
|
39
44
|
open: false,
|
|
45
|
+
// defaultExpanded.includes(node.id),
|
|
40
46
|
level: options.level,
|
|
41
47
|
parent: options.parent,
|
|
42
48
|
checked: 0,
|
|
@@ -47,6 +53,9 @@ var refactorTree = function refactorTree(nodes) {
|
|
|
47
53
|
}, node), {}, {
|
|
48
54
|
leaf: !!node.leaf,
|
|
49
55
|
children: node.children && refactorTree(node.children, {
|
|
56
|
+
sorter: sorter,
|
|
57
|
+
defaultExpanded: defaultExpanded
|
|
58
|
+
}, {
|
|
50
59
|
level: options.level + 1,
|
|
51
60
|
parent: node.id
|
|
52
61
|
})
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { type TreeNodeProps } from "./types";
|
|
2
|
-
export declare const TreeNode: ({ node, noLines, expanders, checkable, selectable, defaultLeafIcon, defaultNodeIcon, onToggle, onSelect, onChecked, children, }: TreeNodeProps) => import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare const TreeNode: ({ node, noLines, expanders, checkable, selectable, defaultLeafIcon, defaultNodeIcon, onToggle, onClick, onSelect, onChecked, children, leafClassName, nodeClassName, }: TreeNodeProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { type TreePanelProps } from "./types";
|
|
2
|
-
export declare const TreePanel: <T extends KeyValue<any>>({ ref, items, selected, checked, checkable, noLines, renderer, searchable, selectable, matcher, filterPlaceholder, defaultLeafIcon, defaultNodeIcon, expander, onChecked, onLoad, onSelect, ...aria }: TreePanelProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare const TreePanel: <T extends KeyValue<any>>({ ref, items, selected, checked, checkable, noLines, renderer, searchable, selectable, matcher, filterPlaceholder, defaultLeafIcon, defaultNodeIcon, expander, onChecked, onLoad, onSelect, onClick, sorter, makeLabel, makeIcon, defaultExpanded, onExpandToggle, leafClassName, nodeClassName, ...aria }: TreePanelProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
1
|
import { type BadgeType, type ChildProp, type CssProp, type Elements, type IconProps, type RefProp, type TestProps } from "@react-fabric/core/dist/types/types";
|
|
3
|
-
|
|
2
|
+
import { type ElementType } from "react";
|
|
3
|
+
interface TreeBaseNode<T> extends Omit<IconProps, "icon">, CssProp, TestProps {
|
|
4
4
|
id: string;
|
|
5
5
|
/**
|
|
6
6
|
* display label
|
|
@@ -23,17 +23,18 @@ interface TreeBaseNode<T> extends IconProps, CssProp, TestProps {
|
|
|
23
23
|
*/
|
|
24
24
|
disabled?: boolean;
|
|
25
25
|
data?: T;
|
|
26
|
+
icon?: ElementType<IconProps> | string;
|
|
26
27
|
}
|
|
27
28
|
export type TreeNodeType<T extends KeyValue = KeyValue> = TreeBaseNode<T> & ({
|
|
28
29
|
leaf: true;
|
|
29
30
|
children?: never;
|
|
30
31
|
} | {
|
|
31
|
-
leaf?:
|
|
32
|
+
leaf?: boolean;
|
|
32
33
|
children?: Array<TreeNodeType<T>>;
|
|
33
34
|
open?: boolean;
|
|
34
35
|
iconOpen?: string;
|
|
35
36
|
});
|
|
36
|
-
export interface InternalNode extends IconProps, CssProp, TestProps {
|
|
37
|
+
export interface InternalNode extends Omit<IconProps, "icon">, CssProp, TestProps {
|
|
37
38
|
id: string;
|
|
38
39
|
label: Elements<JSX.Element>;
|
|
39
40
|
queryable?: string;
|
|
@@ -50,6 +51,7 @@ export interface InternalNode extends IconProps, CssProp, TestProps {
|
|
|
50
51
|
loaded: boolean;
|
|
51
52
|
parent?: string;
|
|
52
53
|
empty?: boolean;
|
|
54
|
+
icon?: ElementType<IconProps> | string;
|
|
53
55
|
errored?: string;
|
|
54
56
|
selected?: true;
|
|
55
57
|
childSelected?: true;
|
|
@@ -66,9 +68,12 @@ export interface TreeNodeProps extends ChildProp {
|
|
|
66
68
|
noLines?: boolean;
|
|
67
69
|
selectable?: true | "leafOnly";
|
|
68
70
|
checkable?: true | "leafOnly";
|
|
71
|
+
leafClassName?: string;
|
|
72
|
+
nodeClassName?: string;
|
|
69
73
|
onToggle: (id: string) => void;
|
|
70
74
|
onSelect: (id: string) => void;
|
|
71
75
|
onChecked: (id: string) => void;
|
|
76
|
+
onClick?: (id: string, node: any) => void;
|
|
72
77
|
}
|
|
73
78
|
export interface TreeRef {
|
|
74
79
|
select: (id: string) => void;
|
|
@@ -120,10 +125,14 @@ export interface TreePanelProps<T extends KeyValue = KeyValue> extends TestProps
|
|
|
120
125
|
* callback for lazy loading tree items
|
|
121
126
|
*/
|
|
122
127
|
onLoad?: (id: string) => Promise<Array<TreeNodeType<T>> | undefined> | Array<TreeNodeType<T>> | undefined;
|
|
128
|
+
/**
|
|
129
|
+
* callback on click of tree node
|
|
130
|
+
*/
|
|
131
|
+
onClick?: (id: string, data: T) => void;
|
|
123
132
|
/**
|
|
124
133
|
* callback on selection of tree node
|
|
125
134
|
*/
|
|
126
|
-
onSelect?: (id: string) => void;
|
|
135
|
+
onSelect?: (id: string, data: T) => void;
|
|
127
136
|
/**
|
|
128
137
|
* callback on change of checked list
|
|
129
138
|
*/
|
|
@@ -136,6 +145,13 @@ export interface TreePanelProps<T extends KeyValue = KeyValue> extends TestProps
|
|
|
136
145
|
* item filter matcher
|
|
137
146
|
*/
|
|
138
147
|
matcher?: (data: T, query: string) => boolean;
|
|
148
|
+
sorter?: false | ((a: T, b: T) => number);
|
|
149
|
+
makeLabel?: (node: T) => string;
|
|
150
|
+
makeIcon?: (node: T) => string;
|
|
151
|
+
defaultExpanded?: string[];
|
|
152
|
+
onExpandToggle?: (id: string[]) => void;
|
|
153
|
+
leafClassName?: string;
|
|
154
|
+
nodeClassName?: string;
|
|
139
155
|
}
|
|
140
156
|
export declare const iconExpandAll = "M12.984 9v6h3l-3.984 3.984-3.984-3.984h3v-6h-3l3.984-3.984 3.984 3.984h-3zM3.984 2.016h16.031v1.969h-16.031v-1.969zM3.984 20.016h16.031v1.969h-16.031v-1.969z";
|
|
141
157
|
export declare const iconCollapseAll = "M3.984 11.016h16.031v1.969h-16.031v-1.969zM15.984 5.016l-3.984 3.984-3.984-3.984h3v-4.031h1.969v4.031h3zM8.016 18.984l3.984-3.984 3.984 3.984h-3v4.031h-1.969v-4.031h-3z";
|
|
@@ -1,12 +1,5 @@
|
|
|
1
|
-
import { type InternalNode, type
|
|
2
|
-
export declare const useTree: <T extends KeyValue<any>>({ items, checked, selected, matcher, onSelect, onChecked, }: {
|
|
3
|
-
items?: Array<TreeNodeType<T>>;
|
|
4
|
-
selected?: string;
|
|
5
|
-
checked?: string[];
|
|
6
|
-
onSelect?: (id: string) => void;
|
|
7
|
-
onChecked?: (leafs: string[], nodes: string[]) => void;
|
|
8
|
-
matcher?: (data: T, query: string) => boolean;
|
|
9
|
-
}) => {
|
|
1
|
+
import { type InternalNode, type TreePanelProps } from "./types";
|
|
2
|
+
export declare const useTree: <T extends KeyValue<any>>({ items, checked, selected, sorter, matcher, onLoad, onSelect, onChecked, defaultExpanded, onExpandToggle, }: Partial<TreePanelProps<T>>) => {
|
|
10
3
|
tree: InternalNode[];
|
|
11
4
|
toggleExpand: (id: string) => void;
|
|
12
5
|
expandAll: () => void;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { type InternalNode, type TreeNodeType } from "./types";
|
|
2
|
-
export declare const refactorTree: (nodes: TreeNodeType[],
|
|
2
|
+
export declare const refactorTree: (nodes: TreeNodeType[], { sorter, defaultExpanded, }: {
|
|
3
|
+
sorter?: any;
|
|
4
|
+
defaultExpanded?: string[];
|
|
5
|
+
}, options?: {
|
|
3
6
|
level: number;
|
|
4
7
|
parent?: string;
|
|
5
8
|
}) => InternalNode[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-fabric/data",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.27",
|
|
4
4
|
"description": "RUF: Data package",
|
|
5
5
|
"author": "Adarsh Pastakia <adarshpastakia@outlook.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
"watch": "npm-run-all -p watch:rollup watch:dts"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@react-fabric/core": "^1.0.0-beta.
|
|
37
|
-
"@react-fabric/date": "^1.0.0-beta.
|
|
38
|
-
"@react-fabric/form": "^1.0.0-beta.
|
|
39
|
-
"@react-fabric/utilities": "^1.0.0-beta.
|
|
36
|
+
"@react-fabric/core": "^1.0.0-beta.27",
|
|
37
|
+
"@react-fabric/date": "^1.0.0-beta.27",
|
|
38
|
+
"@react-fabric/form": "^1.0.0-beta.27",
|
|
39
|
+
"@react-fabric/utilities": "^1.0.0-beta.27",
|
|
40
40
|
"@tanstack/react-virtual": "^3.8.6",
|
|
41
41
|
"classnames": "^2.5.1",
|
|
42
42
|
"color": "^4.2.3",
|
|
@@ -44,13 +44,13 @@
|
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"i18next": "^23.15.1",
|
|
47
|
-
"react": "
|
|
48
|
-
"react-dom": "
|
|
47
|
+
"react": "^19.0.0",
|
|
48
|
+
"react-dom": "^19.0.0",
|
|
49
49
|
"react-i18next": "^15.0.2"
|
|
50
50
|
},
|
|
51
51
|
"engines": {
|
|
52
52
|
"node": ">=18.12.0",
|
|
53
53
|
"npm": ">=8.19.0"
|
|
54
54
|
},
|
|
55
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "02ddac152718fe86b6003f35ea5e1ef1581168f2"
|
|
56
56
|
}
|
package/src/tree/TreeNode.tsx
CHANGED
|
@@ -22,8 +22,9 @@
|
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
import { Badge, CoreIcons, getBadgeProps, Icon } from "@react-fabric/core";
|
|
25
|
+
import { isEmpty, isString } from "@react-fabric/utilities";
|
|
25
26
|
import classNames from "classnames";
|
|
26
|
-
import { useMemo } from "react";
|
|
27
|
+
import { isValidElement, useMemo } from "react";
|
|
27
28
|
import { type TreeNodeProps } from "./types";
|
|
28
29
|
|
|
29
30
|
export const TreeNode = ({
|
|
@@ -35,20 +36,26 @@ export const TreeNode = ({
|
|
|
35
36
|
defaultLeafIcon,
|
|
36
37
|
defaultNodeIcon,
|
|
37
38
|
onToggle,
|
|
39
|
+
onClick,
|
|
38
40
|
onSelect,
|
|
39
41
|
onChecked,
|
|
40
42
|
children,
|
|
43
|
+
leafClassName,
|
|
44
|
+
nodeClassName,
|
|
41
45
|
}: TreeNodeProps) => {
|
|
42
46
|
const badgeProps = useMemo(() => {
|
|
43
47
|
return getBadgeProps(node.badge);
|
|
44
48
|
}, [node.badge]);
|
|
45
49
|
|
|
46
50
|
const filler = useMemo(() => {
|
|
47
|
-
return node.lines.slice(
|
|
51
|
+
return node.lines.slice(1).map((line, idx) => (
|
|
48
52
|
<div
|
|
49
53
|
key={idx}
|
|
50
54
|
className={classNames(
|
|
51
|
-
"flex-initial self-stretch flex items-center w-6 relative
|
|
55
|
+
"flex-initial self-stretch flex items-center w-6 relative",
|
|
56
|
+
!noLines &&
|
|
57
|
+
line > 0 &&
|
|
58
|
+
"before:absolute before:top-0 before:start-[7px] before:bg-tint-200 before:min-h-[50%] before:w-[2px] before:scale-x-[.625]",
|
|
52
59
|
!noLines && line !== 2 && "before:h-full",
|
|
53
60
|
)}
|
|
54
61
|
>
|
|
@@ -88,12 +95,24 @@ export const TreeNode = ({
|
|
|
88
95
|
<div
|
|
89
96
|
role="treeitem"
|
|
90
97
|
aria-selected={node.selected}
|
|
91
|
-
className=
|
|
98
|
+
className={classNames(
|
|
99
|
+
"flex flex-nowrap items-center",
|
|
100
|
+
node.leaf ? leafClassName : nodeClassName,
|
|
101
|
+
)}
|
|
92
102
|
data-testid={node["data-testid"]}
|
|
93
103
|
data-test-value={node["data-test-value"]}
|
|
94
104
|
>
|
|
95
105
|
{filler}
|
|
96
|
-
{
|
|
106
|
+
{node.loading && (
|
|
107
|
+
<div className="flex-initial w-6">
|
|
108
|
+
<Icon
|
|
109
|
+
rtlFlip
|
|
110
|
+
icon={CoreIcons.spinner}
|
|
111
|
+
className="animate-spin text-muted"
|
|
112
|
+
/>
|
|
113
|
+
</div>
|
|
114
|
+
)}
|
|
115
|
+
{!node.leaf && !node.childFiltered && !node.loading && (
|
|
97
116
|
<div className="flex-initial w-6">
|
|
98
117
|
<Icon
|
|
99
118
|
rtlFlip
|
|
@@ -125,27 +144,31 @@ export const TreeNode = ({
|
|
|
125
144
|
<div
|
|
126
145
|
role="none"
|
|
127
146
|
className={classNames(
|
|
128
|
-
"group data-[selected]:bg-primary-100 flex flex-nowrap flex-1 overflow-hidden select-none",
|
|
147
|
+
"group/tool data-[selected]:bg-primary-100 flex flex-nowrap flex-1 overflow-hidden select-none",
|
|
129
148
|
node.childSelected && "font-medium",
|
|
130
|
-
canSelect && "hover:bg-primary-50 cursor-pointer",
|
|
149
|
+
(canSelect || onClick) && "hover:bg-primary-50 cursor-pointer",
|
|
131
150
|
)}
|
|
132
151
|
data-selected={node.selected}
|
|
133
|
-
onClick={() =>
|
|
152
|
+
onClick={() => {
|
|
153
|
+
onClick?.(node.id, node.data);
|
|
134
154
|
canSelect
|
|
135
155
|
? onSelect(node.id)
|
|
136
156
|
: canCheck
|
|
137
157
|
? onChecked(node.id)
|
|
138
|
-
: onToggle(node.id)
|
|
139
|
-
}
|
|
158
|
+
: onToggle(node.id);
|
|
159
|
+
}}
|
|
140
160
|
>
|
|
141
161
|
{nodeIcon && (
|
|
142
|
-
<div className="flex-content w-6">
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
162
|
+
<div className="flex-content w-6 self-center leading-none">
|
|
163
|
+
{isValidElement(nodeIcon) && nodeIcon}
|
|
164
|
+
{isString(nodeIcon) && (
|
|
165
|
+
<Icon
|
|
166
|
+
icon={nodeIcon}
|
|
167
|
+
bg={node.iconBg}
|
|
168
|
+
color={node.iconColor}
|
|
169
|
+
rtlFlip={node.rtlFlip}
|
|
170
|
+
/>
|
|
171
|
+
)}
|
|
149
172
|
</div>
|
|
150
173
|
)}
|
|
151
174
|
{node.childSelected && !node.open && (
|
|
@@ -154,7 +177,7 @@ export const TreeNode = ({
|
|
|
154
177
|
<div role="none" className="flex-1 truncate">
|
|
155
178
|
{children}
|
|
156
179
|
</div>
|
|
157
|
-
{node.badge && (
|
|
180
|
+
{!isEmpty(node.badge) && (
|
|
158
181
|
<Badge
|
|
159
182
|
{...badgeProps}
|
|
160
183
|
className={classNames(
|
package/src/tree/TreePanel.tsx
CHANGED
|
@@ -56,6 +56,14 @@ export const TreePanel = <T extends KeyValue>({
|
|
|
56
56
|
onChecked,
|
|
57
57
|
onLoad,
|
|
58
58
|
onSelect,
|
|
59
|
+
onClick,
|
|
60
|
+
sorter,
|
|
61
|
+
makeLabel,
|
|
62
|
+
makeIcon,
|
|
63
|
+
defaultExpanded,
|
|
64
|
+
onExpandToggle,
|
|
65
|
+
leafClassName,
|
|
66
|
+
nodeClassName,
|
|
59
67
|
...aria
|
|
60
68
|
}: TreePanelProps<T>) => {
|
|
61
69
|
const {
|
|
@@ -72,8 +80,12 @@ export const TreePanel = <T extends KeyValue>({
|
|
|
72
80
|
checked,
|
|
73
81
|
selected,
|
|
74
82
|
matcher,
|
|
83
|
+
sorter,
|
|
84
|
+
onLoad,
|
|
75
85
|
onSelect,
|
|
76
86
|
onChecked,
|
|
87
|
+
defaultExpanded,
|
|
88
|
+
onExpandToggle,
|
|
77
89
|
});
|
|
78
90
|
|
|
79
91
|
const scrollerRef = useRef<HTMLDivElement>(null);
|
|
@@ -99,7 +111,7 @@ export const TreePanel = <T extends KeyValue>({
|
|
|
99
111
|
ref,
|
|
100
112
|
() => ({
|
|
101
113
|
open: (id: string) => expand(id),
|
|
102
|
-
select: (id: string) =>
|
|
114
|
+
select: (id: string) => select(id),
|
|
103
115
|
}),
|
|
104
116
|
[],
|
|
105
117
|
);
|
|
@@ -151,12 +163,18 @@ export const TreePanel = <T extends KeyValue>({
|
|
|
151
163
|
checkable={checkable}
|
|
152
164
|
selectable={selectable}
|
|
153
165
|
defaultLeafIcon={defaultLeafIcon}
|
|
154
|
-
defaultNodeIcon={
|
|
166
|
+
defaultNodeIcon={
|
|
167
|
+
makeIcon?.(tree[index].data) ?? defaultNodeIcon
|
|
168
|
+
}
|
|
155
169
|
onToggle={toggleExpand}
|
|
156
170
|
onChecked={toggleCheck}
|
|
157
171
|
onSelect={select}
|
|
172
|
+
onClick={onClick}
|
|
173
|
+
leafClassName={leafClassName}
|
|
174
|
+
nodeClassName={nodeClassName}
|
|
158
175
|
>
|
|
159
|
-
{(tree[index].data && renderer?.(tree[index].data))
|
|
176
|
+
{(tree[index].data && renderer?.(tree[index].data)) ??
|
|
177
|
+
makeLabel?.(tree[index].data) ??
|
|
160
178
|
tree[index].label}
|
|
161
179
|
</TreeNode>
|
|
162
180
|
</div>
|
package/src/tree/types.ts
CHANGED
|
@@ -30,8 +30,9 @@ import {
|
|
|
30
30
|
type RefProp,
|
|
31
31
|
type TestProps,
|
|
32
32
|
} from "@react-fabric/core/dist/types/types";
|
|
33
|
+
import { type ElementType } from "react";
|
|
33
34
|
|
|
34
|
-
interface TreeBaseNode<T> extends IconProps, CssProp, TestProps {
|
|
35
|
+
interface TreeBaseNode<T> extends Omit<IconProps, "icon">, CssProp, TestProps {
|
|
35
36
|
id: string;
|
|
36
37
|
/**
|
|
37
38
|
* display label
|
|
@@ -54,20 +55,25 @@ interface TreeBaseNode<T> extends IconProps, CssProp, TestProps {
|
|
|
54
55
|
*/
|
|
55
56
|
disabled?: boolean;
|
|
56
57
|
data?: T;
|
|
58
|
+
|
|
59
|
+
icon?: ElementType<IconProps> | string;
|
|
57
60
|
}
|
|
58
61
|
|
|
59
62
|
export type TreeNodeType<T extends KeyValue = KeyValue> = TreeBaseNode<T> &
|
|
60
63
|
(
|
|
61
64
|
| { leaf: true; children?: never }
|
|
62
65
|
| {
|
|
63
|
-
leaf?:
|
|
66
|
+
leaf?: boolean;
|
|
64
67
|
children?: Array<TreeNodeType<T>>;
|
|
65
68
|
open?: boolean;
|
|
66
69
|
iconOpen?: string;
|
|
67
70
|
}
|
|
68
71
|
);
|
|
69
72
|
|
|
70
|
-
export interface InternalNode
|
|
73
|
+
export interface InternalNode
|
|
74
|
+
extends Omit<IconProps, "icon">,
|
|
75
|
+
CssProp,
|
|
76
|
+
TestProps {
|
|
71
77
|
id: string;
|
|
72
78
|
label: Elements<JSX.Element>;
|
|
73
79
|
queryable?: string;
|
|
@@ -84,6 +90,7 @@ export interface InternalNode extends IconProps, CssProp, TestProps {
|
|
|
84
90
|
loaded: boolean;
|
|
85
91
|
parent?: string;
|
|
86
92
|
empty?: boolean;
|
|
93
|
+
icon?: ElementType<IconProps> | string;
|
|
87
94
|
errored?: string;
|
|
88
95
|
selected?: true;
|
|
89
96
|
childSelected?: true;
|
|
@@ -101,9 +108,12 @@ export interface TreeNodeProps extends ChildProp {
|
|
|
101
108
|
noLines?: boolean;
|
|
102
109
|
selectable?: true | "leafOnly";
|
|
103
110
|
checkable?: true | "leafOnly";
|
|
111
|
+
leafClassName?: string;
|
|
112
|
+
nodeClassName?: string;
|
|
104
113
|
onToggle: (id: string) => void;
|
|
105
114
|
onSelect: (id: string) => void;
|
|
106
115
|
onChecked: (id: string) => void;
|
|
116
|
+
onClick?: (id: string, node: any) => void;
|
|
107
117
|
}
|
|
108
118
|
|
|
109
119
|
export interface TreeRef {
|
|
@@ -164,10 +174,14 @@ export interface TreePanelProps<T extends KeyValue = KeyValue>
|
|
|
164
174
|
| Promise<Array<TreeNodeType<T>> | undefined>
|
|
165
175
|
| Array<TreeNodeType<T>>
|
|
166
176
|
| undefined;
|
|
177
|
+
/**
|
|
178
|
+
* callback on click of tree node
|
|
179
|
+
*/
|
|
180
|
+
onClick?: (id: string, data: T) => void;
|
|
167
181
|
/**
|
|
168
182
|
* callback on selection of tree node
|
|
169
183
|
*/
|
|
170
|
-
onSelect?: (id: string) => void;
|
|
184
|
+
onSelect?: (id: string, data: T) => void;
|
|
171
185
|
/**
|
|
172
186
|
* callback on change of checked list
|
|
173
187
|
*/
|
|
@@ -180,6 +194,16 @@ export interface TreePanelProps<T extends KeyValue = KeyValue>
|
|
|
180
194
|
* item filter matcher
|
|
181
195
|
*/
|
|
182
196
|
matcher?: (data: T, query: string) => boolean;
|
|
197
|
+
|
|
198
|
+
sorter?: false | ((a: T, b: T) => number);
|
|
199
|
+
makeLabel?: (node: T) => string;
|
|
200
|
+
makeIcon?: (node: T) => string;
|
|
201
|
+
|
|
202
|
+
defaultExpanded?: string[];
|
|
203
|
+
onExpandToggle?: (id: string[]) => void;
|
|
204
|
+
|
|
205
|
+
leafClassName?: string;
|
|
206
|
+
nodeClassName?: string;
|
|
183
207
|
}
|
|
184
208
|
|
|
185
209
|
export const iconExpandAll =
|