@react-fabric/data 1.0.0-beta.26 → 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 +9 -2
- package/dist/cjs/tree/TreePanel.js +4 -3
- package/dist/cjs/tree/useTree.js +64 -8
- package/dist/cjs/tree/utils.js +2 -1
- package/dist/esm/tree/TreeNode.js +9 -2
- package/dist/esm/tree/TreePanel.js +4 -3
- package/dist/esm/tree/useTree.js +65 -9
- package/dist/esm/tree/utils.js +2 -1
- package/dist/types/tree/useTree.d.ts +1 -1
- package/package.json +6 -6
- package/src/tree/TreeNode.tsx +11 -2
- package/src/tree/TreePanel.tsx +1 -0
- package/src/tree/useTree.ts +66 -10
- package/src/tree/utils.ts +1 -1
|
@@ -63,7 +63,14 @@ var TreeNode = function TreeNode(_ref) {
|
|
|
63
63
|
className: classNames("flex flex-nowrap items-center", node.leaf ? leafClassName : nodeClassName),
|
|
64
64
|
"data-testid": node["data-testid"],
|
|
65
65
|
"data-test-value": node["data-test-value"],
|
|
66
|
-
children: [filler,
|
|
66
|
+
children: [filler, node.loading && /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
67
|
+
className: "flex-initial w-6",
|
|
68
|
+
children: /*#__PURE__*/jsxRuntime.jsx(core.Icon, {
|
|
69
|
+
rtlFlip: true,
|
|
70
|
+
icon: core.CoreIcons.spinner,
|
|
71
|
+
className: "animate-spin text-muted"
|
|
72
|
+
})
|
|
73
|
+
}), !node.leaf && !node.childFiltered && !node.loading && /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
67
74
|
className: "flex-initial w-6",
|
|
68
75
|
children: /*#__PURE__*/jsxRuntime.jsx(core.Icon, {
|
|
69
76
|
rtlFlip: true,
|
|
@@ -84,7 +91,7 @@ var TreeNode = function TreeNode(_ref) {
|
|
|
84
91
|
})
|
|
85
92
|
}), /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
86
93
|
role: "none",
|
|
87
|
-
className: classNames("group data-[selected]:bg-primary-100 flex flex-nowrap flex-1 overflow-hidden select-none", node.childSelected && "font-medium", (canSelect || _onClick) && "hover:bg-primary-50 cursor-pointer"),
|
|
94
|
+
className: classNames("group/tool data-[selected]:bg-primary-100 flex flex-nowrap flex-1 overflow-hidden select-none", node.childSelected && "font-medium", (canSelect || _onClick) && "hover:bg-primary-50 cursor-pointer"),
|
|
88
95
|
"data-selected": node.selected,
|
|
89
96
|
onClick: function onClick() {
|
|
90
97
|
_onClick === null || _onClick === void 0 || _onClick(node.id, node.data);
|
|
@@ -31,9 +31,9 @@ var TreePanel = function TreePanel(_ref) {
|
|
|
31
31
|
defaultNodeIcon = _ref.defaultNodeIcon,
|
|
32
32
|
_ref$expander = _ref.expander,
|
|
33
33
|
expander = _ref$expander === void 0 ? "box" : _ref$expander,
|
|
34
|
-
onChecked = _ref.onChecked
|
|
35
|
-
_ref.onLoad
|
|
36
|
-
|
|
34
|
+
onChecked = _ref.onChecked,
|
|
35
|
+
onLoad = _ref.onLoad,
|
|
36
|
+
onSelect = _ref.onSelect,
|
|
37
37
|
onClick = _ref.onClick,
|
|
38
38
|
sorter = _ref.sorter,
|
|
39
39
|
makeLabel = _ref.makeLabel,
|
|
@@ -49,6 +49,7 @@ var TreePanel = function TreePanel(_ref) {
|
|
|
49
49
|
selected: selected,
|
|
50
50
|
matcher: matcher,
|
|
51
51
|
sorter: sorter,
|
|
52
|
+
onLoad: onLoad,
|
|
52
53
|
onSelect: onSelect,
|
|
53
54
|
onChecked: onChecked,
|
|
54
55
|
defaultExpanded: defaultExpanded,
|
package/dist/cjs/tree/useTree.js
CHANGED
|
@@ -21,6 +21,7 @@ var useTree = function useTree(_ref) {
|
|
|
21
21
|
selected = _ref.selected,
|
|
22
22
|
sorter = _ref.sorter,
|
|
23
23
|
matcher = _ref.matcher,
|
|
24
|
+
onLoad = _ref.onLoad,
|
|
24
25
|
onSelect = _ref.onSelect,
|
|
25
26
|
onChecked = _ref.onChecked,
|
|
26
27
|
defaultExpanded = _ref.defaultExpanded,
|
|
@@ -29,6 +30,7 @@ var useTree = function useTree(_ref) {
|
|
|
29
30
|
onSelect: onSelect,
|
|
30
31
|
onChecked: onChecked
|
|
31
32
|
});
|
|
33
|
+
var intialExpand = react.useRef(defaultExpanded !== null && defaultExpanded !== void 0 ? defaultExpanded : utilities.EMPTY_ARRAY);
|
|
32
34
|
var itemList = createItemList(items);
|
|
33
35
|
var fireExpandToggle = react.useCallback(function (itemMap) {
|
|
34
36
|
var expandedList = itemMap.filter(function (node) {
|
|
@@ -38,6 +40,41 @@ var useTree = function useTree(_ref) {
|
|
|
38
40
|
});
|
|
39
41
|
onExpandToggle === null || onExpandToggle === void 0 || onExpandToggle(expandedList);
|
|
40
42
|
}, [onExpandToggle]);
|
|
43
|
+
var loadChildren = react.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] : utilities.EMPTY_ARRAY;
|
|
49
|
+
node.children = utils.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]);
|
|
41
78
|
var _useReducer = react.useReducer(function (state, action) {
|
|
42
79
|
if (action.type === "load") {
|
|
43
80
|
state.items = utils.refactorTree(action.items, {
|
|
@@ -50,23 +87,37 @@ var useTree = function useTree(_ref) {
|
|
|
50
87
|
}
|
|
51
88
|
if (action.type === "toggleExpand") {
|
|
52
89
|
var node = state.itemMap.get(action.id);
|
|
53
|
-
|
|
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 = utils.makeTreeMap(state.items);
|
|
54
98
|
fireExpandToggle(Array.from(state.itemMap.values()));
|
|
55
99
|
state.tree = utils.flattenTree(state.items);
|
|
100
|
+
state.selected && utils.updateSelection(state.itemMap, state.selected, true);
|
|
56
101
|
return _objectSpread({}, state);
|
|
57
102
|
}
|
|
58
103
|
if (action.type === "expand") {
|
|
59
|
-
// TODO: check if children available, if not call onLoad to fetch node children
|
|
60
104
|
var _node = state.itemMap.get(action.id);
|
|
61
|
-
_node &&
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
+
}
|
|
65
116
|
}
|
|
66
117
|
if (action.type === "expandAll") {
|
|
67
|
-
// TODO: prevent opening dynamic nodes that dont have children
|
|
68
118
|
state.itemMap.forEach(function (node) {
|
|
69
|
-
|
|
119
|
+
var _node$children2;
|
|
120
|
+
!node.leaf && ((_node$children2 = node.children) === null || _node$children2 === void 0 ? void 0 : _node$children2.length) && (node.open = true);
|
|
70
121
|
});
|
|
71
122
|
fireExpandToggle(Array.from(state.itemMap.values()));
|
|
72
123
|
state.tree = utils.flattenTree(state.items);
|
|
@@ -134,10 +185,15 @@ var useTree = function useTree(_ref) {
|
|
|
134
185
|
};
|
|
135
186
|
}, [onSelect, onChecked]);
|
|
136
187
|
react.useEffect(function () {
|
|
188
|
+
var _intialExpand$current3;
|
|
137
189
|
dispatch({
|
|
138
190
|
type: "load",
|
|
139
191
|
items: itemList
|
|
140
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
|
+
});
|
|
141
197
|
}, [itemList]);
|
|
142
198
|
react.useEffect(function () {
|
|
143
199
|
selected && dispatch({
|
package/dist/cjs/tree/utils.js
CHANGED
|
@@ -41,7 +41,8 @@ var refactorTree = function refactorTree(nodes, _ref) {
|
|
|
41
41
|
if (sorter !== false) nodes = nodes.sort(sorter);
|
|
42
42
|
nodes.forEach(function (node) {
|
|
43
43
|
list.push(_objectSpread(_objectSpread({
|
|
44
|
-
open:
|
|
44
|
+
open: false,
|
|
45
|
+
// defaultExpanded.includes(node.id),
|
|
45
46
|
level: options.level,
|
|
46
47
|
parent: options.parent,
|
|
47
48
|
checked: 0,
|
|
@@ -63,7 +63,14 @@ var TreeNode = function TreeNode(_ref) {
|
|
|
63
63
|
className: classNames("flex flex-nowrap items-center", node.leaf ? leafClassName : nodeClassName),
|
|
64
64
|
"data-testid": node["data-testid"],
|
|
65
65
|
"data-test-value": node["data-test-value"],
|
|
66
|
-
children: [filler,
|
|
66
|
+
children: [filler, node.loading && /*#__PURE__*/jsx("div", {
|
|
67
|
+
className: "flex-initial w-6",
|
|
68
|
+
children: /*#__PURE__*/jsx(Icon, {
|
|
69
|
+
rtlFlip: true,
|
|
70
|
+
icon: CoreIcons.spinner,
|
|
71
|
+
className: "animate-spin text-muted"
|
|
72
|
+
})
|
|
73
|
+
}), !node.leaf && !node.childFiltered && !node.loading && /*#__PURE__*/jsx("div", {
|
|
67
74
|
className: "flex-initial w-6",
|
|
68
75
|
children: /*#__PURE__*/jsx(Icon, {
|
|
69
76
|
rtlFlip: true,
|
|
@@ -84,7 +91,7 @@ var TreeNode = function TreeNode(_ref) {
|
|
|
84
91
|
})
|
|
85
92
|
}), /*#__PURE__*/jsxs("div", {
|
|
86
93
|
role: "none",
|
|
87
|
-
className: classNames("group data-[selected]:bg-primary-100 flex flex-nowrap flex-1 overflow-hidden select-none", node.childSelected && "font-medium", (canSelect || _onClick) && "hover:bg-primary-50 cursor-pointer"),
|
|
94
|
+
className: classNames("group/tool data-[selected]:bg-primary-100 flex flex-nowrap flex-1 overflow-hidden select-none", node.childSelected && "font-medium", (canSelect || _onClick) && "hover:bg-primary-50 cursor-pointer"),
|
|
88
95
|
"data-selected": node.selected,
|
|
89
96
|
onClick: function onClick() {
|
|
90
97
|
_onClick === null || _onClick === void 0 || _onClick(node.id, node.data);
|
|
@@ -31,9 +31,9 @@ var TreePanel = function TreePanel(_ref) {
|
|
|
31
31
|
defaultNodeIcon = _ref.defaultNodeIcon,
|
|
32
32
|
_ref$expander = _ref.expander,
|
|
33
33
|
expander = _ref$expander === void 0 ? "box" : _ref$expander,
|
|
34
|
-
onChecked = _ref.onChecked
|
|
35
|
-
_ref.onLoad
|
|
36
|
-
|
|
34
|
+
onChecked = _ref.onChecked,
|
|
35
|
+
onLoad = _ref.onLoad,
|
|
36
|
+
onSelect = _ref.onSelect,
|
|
37
37
|
onClick = _ref.onClick,
|
|
38
38
|
sorter = _ref.sorter,
|
|
39
39
|
makeLabel = _ref.makeLabel,
|
|
@@ -49,6 +49,7 @@ var TreePanel = function TreePanel(_ref) {
|
|
|
49
49
|
selected: selected,
|
|
50
50
|
matcher: matcher,
|
|
51
51
|
sorter: sorter,
|
|
52
|
+
onLoad: onLoad,
|
|
52
53
|
onSelect: onSelect,
|
|
53
54
|
onChecked: onChecked,
|
|
54
55
|
defaultExpanded: defaultExpanded,
|
package/dist/esm/tree/useTree.js
CHANGED
|
@@ -6,7 +6,7 @@ import { useDebounce } from '@react-fabric/core';
|
|
|
6
6
|
import { EMPTY_ARRAY } from '@react-fabric/utilities';
|
|
7
7
|
import memoizeOne from 'memoize-one';
|
|
8
8
|
import { useRef, useCallback, useReducer, useEffect } from 'react';
|
|
9
|
-
import { refactorTree, makeTreeMap, flattenTree,
|
|
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; }
|
|
@@ -21,6 +21,7 @@ var useTree = function useTree(_ref) {
|
|
|
21
21
|
selected = _ref.selected,
|
|
22
22
|
sorter = _ref.sorter,
|
|
23
23
|
matcher = _ref.matcher,
|
|
24
|
+
onLoad = _ref.onLoad,
|
|
24
25
|
onSelect = _ref.onSelect,
|
|
25
26
|
onChecked = _ref.onChecked,
|
|
26
27
|
defaultExpanded = _ref.defaultExpanded,
|
|
@@ -29,6 +30,7 @@ var useTree = function useTree(_ref) {
|
|
|
29
30
|
onSelect: onSelect,
|
|
30
31
|
onChecked: onChecked
|
|
31
32
|
});
|
|
33
|
+
var intialExpand = useRef(defaultExpanded !== null && defaultExpanded !== void 0 ? defaultExpanded : EMPTY_ARRAY);
|
|
32
34
|
var itemList = createItemList(items);
|
|
33
35
|
var fireExpandToggle = useCallback(function (itemMap) {
|
|
34
36
|
var expandedList = itemMap.filter(function (node) {
|
|
@@ -38,6 +40,41 @@ var useTree = function useTree(_ref) {
|
|
|
38
40
|
});
|
|
39
41
|
onExpandToggle === null || onExpandToggle === void 0 || onExpandToggle(expandedList);
|
|
40
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]);
|
|
41
78
|
var _useReducer = useReducer(function (state, action) {
|
|
42
79
|
if (action.type === "load") {
|
|
43
80
|
state.items = refactorTree(action.items, {
|
|
@@ -50,23 +87,37 @@ var useTree = function useTree(_ref) {
|
|
|
50
87
|
}
|
|
51
88
|
if (action.type === "toggleExpand") {
|
|
52
89
|
var node = state.itemMap.get(action.id);
|
|
53
|
-
|
|
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);
|
|
54
98
|
fireExpandToggle(Array.from(state.itemMap.values()));
|
|
55
99
|
state.tree = flattenTree(state.items);
|
|
100
|
+
state.selected && updateSelection(state.itemMap, state.selected, true);
|
|
56
101
|
return _objectSpread({}, state);
|
|
57
102
|
}
|
|
58
103
|
if (action.type === "expand") {
|
|
59
|
-
// TODO: check if children available, if not call onLoad to fetch node children
|
|
60
104
|
var _node = state.itemMap.get(action.id);
|
|
61
|
-
_node &&
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
+
}
|
|
65
116
|
}
|
|
66
117
|
if (action.type === "expandAll") {
|
|
67
|
-
// TODO: prevent opening dynamic nodes that dont have children
|
|
68
118
|
state.itemMap.forEach(function (node) {
|
|
69
|
-
|
|
119
|
+
var _node$children2;
|
|
120
|
+
!node.leaf && ((_node$children2 = node.children) === null || _node$children2 === void 0 ? void 0 : _node$children2.length) && (node.open = true);
|
|
70
121
|
});
|
|
71
122
|
fireExpandToggle(Array.from(state.itemMap.values()));
|
|
72
123
|
state.tree = flattenTree(state.items);
|
|
@@ -134,10 +185,15 @@ var useTree = function useTree(_ref) {
|
|
|
134
185
|
};
|
|
135
186
|
}, [onSelect, onChecked]);
|
|
136
187
|
useEffect(function () {
|
|
188
|
+
var _intialExpand$current3;
|
|
137
189
|
dispatch({
|
|
138
190
|
type: "load",
|
|
139
191
|
items: itemList
|
|
140
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
|
+
});
|
|
141
197
|
}, [itemList]);
|
|
142
198
|
useEffect(function () {
|
|
143
199
|
selected && dispatch({
|
package/dist/esm/tree/utils.js
CHANGED
|
@@ -41,7 +41,8 @@ var refactorTree = function refactorTree(nodes, _ref) {
|
|
|
41
41
|
if (sorter !== false) nodes = nodes.sort(sorter);
|
|
42
42
|
nodes.forEach(function (node) {
|
|
43
43
|
list.push(_objectSpread(_objectSpread({
|
|
44
|
-
open:
|
|
44
|
+
open: false,
|
|
45
|
+
// defaultExpanded.includes(node.id),
|
|
45
46
|
level: options.level,
|
|
46
47
|
parent: options.parent,
|
|
47
48
|
checked: 0,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type InternalNode, type TreePanelProps } from "./types";
|
|
2
|
-
export declare const useTree: <T extends KeyValue<any>>({ items, checked, selected, sorter, matcher, onSelect, onChecked, defaultExpanded, onExpandToggle, }: Partial<TreePanelProps<T>>) => {
|
|
2
|
+
export declare const useTree: <T extends KeyValue<any>>({ items, checked, selected, sorter, matcher, onLoad, onSelect, onChecked, defaultExpanded, onExpandToggle, }: Partial<TreePanelProps<T>>) => {
|
|
3
3
|
tree: InternalNode[];
|
|
4
4
|
toggleExpand: (id: string) => void;
|
|
5
5
|
expandAll: () => void;
|
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",
|
|
@@ -52,5 +52,5 @@
|
|
|
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
|
@@ -103,7 +103,16 @@ export const TreeNode = ({
|
|
|
103
103
|
data-test-value={node["data-test-value"]}
|
|
104
104
|
>
|
|
105
105
|
{filler}
|
|
106
|
-
{
|
|
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 && (
|
|
107
116
|
<div className="flex-initial w-6">
|
|
108
117
|
<Icon
|
|
109
118
|
rtlFlip
|
|
@@ -135,7 +144,7 @@ export const TreeNode = ({
|
|
|
135
144
|
<div
|
|
136
145
|
role="none"
|
|
137
146
|
className={classNames(
|
|
138
|
-
"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",
|
|
139
148
|
node.childSelected && "font-medium",
|
|
140
149
|
(canSelect || onClick) && "hover:bg-primary-50 cursor-pointer",
|
|
141
150
|
)}
|
package/src/tree/TreePanel.tsx
CHANGED
package/src/tree/useTree.ts
CHANGED
|
@@ -75,7 +75,11 @@ type TreeActions =
|
|
|
75
75
|
/**
|
|
76
76
|
* collapse all nodes
|
|
77
77
|
*/
|
|
78
|
-
| { type: "collapseAll" }
|
|
78
|
+
| { type: "collapseAll" }
|
|
79
|
+
/**
|
|
80
|
+
* loaded dynamic nodes
|
|
81
|
+
*/
|
|
82
|
+
| { type: "loaded" };
|
|
79
83
|
|
|
80
84
|
interface TreeState {
|
|
81
85
|
items: InternalNode[];
|
|
@@ -93,13 +97,14 @@ export const useTree = <T extends KeyValue>({
|
|
|
93
97
|
selected,
|
|
94
98
|
sorter,
|
|
95
99
|
matcher,
|
|
100
|
+
onLoad,
|
|
96
101
|
onSelect,
|
|
97
102
|
onChecked,
|
|
98
103
|
defaultExpanded,
|
|
99
104
|
onExpandToggle,
|
|
100
105
|
}: Partial<TreePanelProps<T>>) => {
|
|
101
106
|
const componentEvents = useRef({ onSelect, onChecked });
|
|
102
|
-
|
|
107
|
+
const intialExpand = useRef(defaultExpanded ?? EMPTY_ARRAY);
|
|
103
108
|
const itemList = createItemList(items);
|
|
104
109
|
|
|
105
110
|
const fireExpandToggle = useCallback(
|
|
@@ -112,6 +117,39 @@ export const useTree = <T extends KeyValue>({
|
|
|
112
117
|
[onExpandToggle],
|
|
113
118
|
);
|
|
114
119
|
|
|
120
|
+
const loadChildren = useCallback(
|
|
121
|
+
(node: InternalNode) => {
|
|
122
|
+
if (node.open && !node.leaf && !node.children?.length) {
|
|
123
|
+
node.loading = true;
|
|
124
|
+
void Promise.resolve(onLoad?.(node.id))
|
|
125
|
+
.then((resp = EMPTY_ARRAY) => {
|
|
126
|
+
node.children = refactorTree(
|
|
127
|
+
resp,
|
|
128
|
+
{ sorter, defaultExpanded },
|
|
129
|
+
{ level: node.level + 1, parent: node.id },
|
|
130
|
+
);
|
|
131
|
+
})
|
|
132
|
+
.finally(() => {
|
|
133
|
+
node.loading = false;
|
|
134
|
+
dispatch({ type: "loaded" });
|
|
135
|
+
intialExpand.current?.length > 0 &&
|
|
136
|
+
dispatch({
|
|
137
|
+
type: "expand",
|
|
138
|
+
id: intialExpand.current.shift() as unknown as string,
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
} else {
|
|
142
|
+
dispatch({ type: "loaded" });
|
|
143
|
+
intialExpand.current?.length > 0 &&
|
|
144
|
+
dispatch({
|
|
145
|
+
type: "expand",
|
|
146
|
+
id: intialExpand.current.shift() as unknown as string,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
[onLoad],
|
|
151
|
+
);
|
|
152
|
+
|
|
115
153
|
const [state, dispatch] = useReducer(
|
|
116
154
|
(state: TreeState, action: TreeActions) => {
|
|
117
155
|
if (action.type === "load") {
|
|
@@ -122,23 +160,36 @@ export const useTree = <T extends KeyValue>({
|
|
|
122
160
|
}
|
|
123
161
|
if (action.type === "toggleExpand") {
|
|
124
162
|
const node = state.itemMap.get(action.id);
|
|
125
|
-
|
|
163
|
+
if (node && !node.leaf) {
|
|
164
|
+
node && (node.open = !node.open);
|
|
165
|
+
loadChildren(node);
|
|
166
|
+
return { ...state };
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (action.type === "loaded") {
|
|
170
|
+
state.itemMap = makeTreeMap(state.items);
|
|
126
171
|
fireExpandToggle(Array.from(state.itemMap.values()));
|
|
127
172
|
state.tree = flattenTree(state.items);
|
|
173
|
+
state.selected && updateSelection(state.itemMap, state.selected, true);
|
|
128
174
|
return { ...state };
|
|
129
175
|
}
|
|
130
176
|
if (action.type === "expand") {
|
|
131
|
-
// TODO: check if children available, if not call onLoad to fetch node children
|
|
132
177
|
const node = state.itemMap.get(action.id);
|
|
133
|
-
node &&
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
178
|
+
if (node && !node.leaf) {
|
|
179
|
+
node.open = true;
|
|
180
|
+
let parentId = node.parent;
|
|
181
|
+
while (parentId) {
|
|
182
|
+
const node = state.itemMap.get(parentId);
|
|
183
|
+
node && (node.open = true);
|
|
184
|
+
parentId = node?.parent;
|
|
185
|
+
}
|
|
186
|
+
loadChildren(node);
|
|
187
|
+
return { ...state };
|
|
188
|
+
}
|
|
137
189
|
}
|
|
138
190
|
if (action.type === "expandAll") {
|
|
139
|
-
// TODO: prevent opening dynamic nodes that dont have children
|
|
140
191
|
state.itemMap.forEach((node) => {
|
|
141
|
-
!node.leaf && (node.open = true);
|
|
192
|
+
!node.leaf && node.children?.length && (node.open = true);
|
|
142
193
|
});
|
|
143
194
|
fireExpandToggle(Array.from(state.itemMap.values()));
|
|
144
195
|
state.tree = flattenTree(state.items);
|
|
@@ -198,6 +249,11 @@ export const useTree = <T extends KeyValue>({
|
|
|
198
249
|
|
|
199
250
|
useEffect(() => {
|
|
200
251
|
dispatch({ type: "load", items: itemList });
|
|
252
|
+
intialExpand.current?.length > 0 &&
|
|
253
|
+
dispatch({
|
|
254
|
+
type: "expand",
|
|
255
|
+
id: intialExpand.current.shift() as unknown as string,
|
|
256
|
+
});
|
|
201
257
|
}, [itemList]);
|
|
202
258
|
|
|
203
259
|
useEffect(() => {
|
package/src/tree/utils.ts
CHANGED
|
@@ -58,7 +58,7 @@ export const refactorTree = (
|
|
|
58
58
|
if (sorter !== false) nodes = nodes.sort(sorter);
|
|
59
59
|
nodes.forEach((node) => {
|
|
60
60
|
list.push({
|
|
61
|
-
open: defaultExpanded.includes(node.id),
|
|
61
|
+
open: false, // defaultExpanded.includes(node.id),
|
|
62
62
|
level: options.level,
|
|
63
63
|
parent: options.parent,
|
|
64
64
|
checked: 0,
|