@snack-uikit/tree 0.8.19 → 0.8.20
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/CHANGELOG.md +11 -0
- package/dist/cjs/helperComponents/ExpandableTreeNode/ExpandableTreeNode.d.ts +1 -1
- package/dist/cjs/helperComponents/ExpandableTreeNode/ExpandableTreeNode.js +28 -11
- package/dist/cjs/helperComponents/ExpandableTreeNode/styles.module.css +4 -0
- package/dist/cjs/helperComponents/TreeItem/TreeItem.d.ts +1 -1
- package/dist/cjs/helperComponents/TreeItem/TreeItem.js +8 -5
- package/dist/cjs/helperComponents/TreeLine/TreeLine.d.ts +4 -3
- package/dist/cjs/helperComponents/TreeLine/TreeLine.js +10 -4
- package/dist/cjs/helperComponents/TreeLine/styles.module.css +3 -3
- package/dist/cjs/helperComponents/TreeNode/TreeNode.d.ts +1 -1
- package/dist/cjs/helperComponents/TreeNode/TreeNode.js +27 -20
- package/dist/cjs/helperComponents/TreeNode/styles.module.css +20 -6
- package/dist/esm/helperComponents/ExpandableTreeNode/ExpandableTreeNode.d.ts +1 -1
- package/dist/esm/helperComponents/ExpandableTreeNode/ExpandableTreeNode.js +22 -11
- package/dist/esm/helperComponents/ExpandableTreeNode/styles.module.css +4 -0
- package/dist/esm/helperComponents/TreeItem/TreeItem.d.ts +1 -1
- package/dist/esm/helperComponents/TreeItem/TreeItem.js +5 -4
- package/dist/esm/helperComponents/TreeLine/TreeLine.d.ts +4 -3
- package/dist/esm/helperComponents/TreeLine/TreeLine.js +3 -2
- package/dist/esm/helperComponents/TreeLine/styles.module.css +3 -3
- package/dist/esm/helperComponents/TreeNode/TreeNode.d.ts +1 -1
- package/dist/esm/helperComponents/TreeNode/TreeNode.js +13 -11
- package/dist/esm/helperComponents/TreeNode/styles.module.css +20 -6
- package/package.json +2 -2
- package/src/helperComponents/ExpandableTreeNode/ExpandableTreeNode.tsx +120 -97
- package/src/helperComponents/ExpandableTreeNode/styles.module.scss +6 -0
- package/src/helperComponents/TreeItem/TreeItem.tsx +8 -4
- package/src/helperComponents/TreeLine/TreeLine.tsx +8 -5
- package/src/helperComponents/TreeLine/styles.module.scss +9 -13
- package/src/helperComponents/TreeNode/TreeNode.tsx +266 -245
- package/src/helperComponents/TreeNode/styles.module.scss +36 -19
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## 0.8.20 (2025-01-31)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **PDS-1461:** fix height of tree node with custom content ([c53e1cc](https://github.com/cloud-ru-tech/snack-uikit/commit/c53e1cc2a90634bee4619c2b8f1d4690ef49d461))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
## 0.8.19 (2025-01-23)
|
|
7
18
|
|
|
8
19
|
### Only dependencies have been changed
|
|
@@ -7,5 +7,5 @@ type ExpandableTreeNodeProps = {
|
|
|
7
7
|
};
|
|
8
8
|
tabIndexAvailable?: boolean;
|
|
9
9
|
};
|
|
10
|
-
export declare
|
|
10
|
+
export declare const ExpandableTreeNode: import("react").ForwardRefExoticComponent<ExpandableTreeNodeProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
11
11
|
export {};
|
|
@@ -43,7 +43,7 @@ var __importDefault = void 0 && (void 0).__importDefault || function (mod) {
|
|
|
43
43
|
Object.defineProperty(exports, "__esModule", {
|
|
44
44
|
value: true
|
|
45
45
|
});
|
|
46
|
-
exports.ExpandableTreeNode =
|
|
46
|
+
exports.ExpandableTreeNode = void 0;
|
|
47
47
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
48
48
|
const react_1 = require("react");
|
|
49
49
|
const react_transition_state_1 = __importDefault(require("react-transition-state"));
|
|
@@ -53,7 +53,7 @@ const TreeItem_1 = require("../TreeItem");
|
|
|
53
53
|
const TreeLine_1 = require("../TreeLine");
|
|
54
54
|
const TreeNode_1 = require("../TreeNode");
|
|
55
55
|
const styles_module_scss_1 = __importDefault(require('./styles.module.css'));
|
|
56
|
-
|
|
56
|
+
exports.ExpandableTreeNode = (0, react_1.forwardRef)((_a, ref) => {
|
|
57
57
|
var _b = _a.node,
|
|
58
58
|
{
|
|
59
59
|
'data-test-id': dataTestId
|
|
@@ -78,18 +78,32 @@ function ExpandableTreeNode(_a) {
|
|
|
78
78
|
enter: isExpanded
|
|
79
79
|
});
|
|
80
80
|
const showContent = node.nested && node.nested.length > 0 && state.status !== 'exited';
|
|
81
|
-
const
|
|
81
|
+
const childrenRefs = (0, react_1.useRef)([]);
|
|
82
|
+
const [lastItemHeight, setLastItemHeight] = (0, react_1.useState)(0);
|
|
83
|
+
(0, react_1.useEffect)(() => {
|
|
82
84
|
var _a, _b;
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
85
|
+
const lastItem = (_a = childrenRefs.current) === null || _a === void 0 ? void 0 : _a.at(-1);
|
|
86
|
+
if (lastItem) {
|
|
87
|
+
const observer = new ResizeObserver(entities => entities.forEach(entity => {
|
|
88
|
+
if (entity.target === lastItem) {
|
|
89
|
+
const [{
|
|
90
|
+
blockSize: newHeight
|
|
91
|
+
}] = entity.contentBoxSize;
|
|
92
|
+
setLastItemHeight(newHeight);
|
|
93
|
+
}
|
|
94
|
+
}));
|
|
95
|
+
observer.observe(lastItem);
|
|
96
|
+
setLastItemHeight((_b = lastItem.scrollHeight) !== null && _b !== void 0 ? _b : 0);
|
|
97
|
+
return () => observer.disconnect();
|
|
98
|
+
}
|
|
99
|
+
}, [state.status]);
|
|
86
100
|
(0, react_1.useEffect)(() => {
|
|
87
101
|
var _a;
|
|
88
102
|
if (((_a = node.nested) === null || _a === void 0 ? void 0 : _a.length) && isExpanded && state.status === 'exited') {
|
|
89
103
|
toggle(true);
|
|
90
104
|
}
|
|
91
105
|
}, [isExpanded, node.nested, state.status]);
|
|
92
|
-
const toggleExpand = () => __awaiter(
|
|
106
|
+
const toggleExpand = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
93
107
|
if (node.nested && !node.nested.length && !isExpanded && onDataLoad) {
|
|
94
108
|
setLoading(true);
|
|
95
109
|
yield onDataLoad(node).finally(() => {
|
|
@@ -125,6 +139,7 @@ function ExpandableTreeNode(_a) {
|
|
|
125
139
|
"data-test-id": dataTestId,
|
|
126
140
|
"data-expandable": Boolean(node.nested) || undefined,
|
|
127
141
|
"data-disabled": node.disabled || undefined,
|
|
142
|
+
ref: ref,
|
|
128
143
|
children: [(0, jsx_runtime_1.jsx)(TreeNode_1.TreeNode, Object.assign({}, node, {
|
|
129
144
|
isLoading: isLoading,
|
|
130
145
|
parentNode: parentNode,
|
|
@@ -140,17 +155,19 @@ function ExpandableTreeNode(_a) {
|
|
|
140
155
|
"data-test-id": constants_1.TEST_IDS.expandableContent,
|
|
141
156
|
children: [(0, jsx_runtime_1.jsx)(TreeLine_1.TreeLine, {
|
|
142
157
|
visible: showLines,
|
|
143
|
-
|
|
144
|
-
|
|
158
|
+
"data-test-id": constants_1.TEST_IDS.line,
|
|
159
|
+
height: `calc(100% - ${lastItemHeight}px)`,
|
|
160
|
+
className: styles_module_scss_1.default.treeLine
|
|
145
161
|
}), (0, jsx_runtime_1.jsx)("div", {
|
|
146
162
|
className: styles_module_scss_1.default.expandableNested,
|
|
147
|
-
children: node.nested.map(nestedNode => {
|
|
163
|
+
children: node.nested.map((nestedNode, index) => {
|
|
148
164
|
const parent = {
|
|
149
165
|
id: node.id,
|
|
150
166
|
nested: node.nested,
|
|
151
167
|
parentNode
|
|
152
168
|
};
|
|
153
169
|
return (0, jsx_runtime_1.jsx)(TreeItem_1.TreeItem, {
|
|
170
|
+
ref: el => childrenRefs.current[index] = el,
|
|
154
171
|
node: Object.assign(Object.assign({}, nestedNode), {
|
|
155
172
|
disabled: node.disabled || nestedNode.disabled
|
|
156
173
|
}),
|
|
@@ -161,4 +178,4 @@ function ExpandableTreeNode(_a) {
|
|
|
161
178
|
})
|
|
162
179
|
})]
|
|
163
180
|
});
|
|
164
|
-
}
|
|
181
|
+
});
|
|
@@ -4,5 +4,5 @@ type TreeItemProps = {
|
|
|
4
4
|
parentNode?: ParentNode;
|
|
5
5
|
tabIndexAvailable?: boolean;
|
|
6
6
|
};
|
|
7
|
-
export declare
|
|
7
|
+
export declare const TreeItem: import("react").ForwardRefExoticComponent<TreeItemProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
8
8
|
export {};
|
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.TreeItem =
|
|
6
|
+
exports.TreeItem = void 0;
|
|
7
7
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const react_1 = require("react");
|
|
8
9
|
const constants_1 = require("../../constants");
|
|
9
10
|
const ExpandableTreeNode_1 = require("../ExpandableTreeNode");
|
|
10
11
|
const TreeNode_1 = require("../TreeNode");
|
|
11
|
-
|
|
12
|
+
exports.TreeItem = (0, react_1.forwardRef)((_ref, ref) => {
|
|
12
13
|
let {
|
|
13
14
|
node,
|
|
14
15
|
tabIndexAvailable,
|
|
@@ -22,11 +23,13 @@ function TreeItem(_ref) {
|
|
|
22
23
|
return (0, jsx_runtime_1.jsx)(ExpandableTreeNode_1.ExpandableTreeNode, {
|
|
23
24
|
node: nodeProps,
|
|
24
25
|
tabIndexAvailable: tabIndexAvailable,
|
|
25
|
-
parentNode: parentNode
|
|
26
|
+
parentNode: parentNode,
|
|
27
|
+
ref: ref
|
|
26
28
|
});
|
|
27
29
|
}
|
|
28
30
|
return (0, jsx_runtime_1.jsx)(TreeNode_1.TreeNode, Object.assign({}, nodeProps, {
|
|
29
31
|
tabIndexAvailable: tabIndexAvailable,
|
|
30
|
-
parentNode: parentNode
|
|
32
|
+
parentNode: parentNode,
|
|
33
|
+
ref: ref
|
|
31
34
|
}));
|
|
32
|
-
}
|
|
35
|
+
});
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { CSSProperties } from 'react';
|
|
1
2
|
export type TreeLineProps = {
|
|
3
|
+
className?: string;
|
|
2
4
|
halfWidth?: boolean;
|
|
3
|
-
halfHeight?: boolean;
|
|
4
5
|
visible?: boolean;
|
|
5
6
|
horizontal?: boolean;
|
|
6
|
-
}
|
|
7
|
-
export declare function TreeLine({
|
|
7
|
+
} & Pick<CSSProperties, 'height' | 'width'>;
|
|
8
|
+
export declare function TreeLine({ className, halfWidth, horizontal, visible, height, width }: TreeLineProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -10,20 +10,26 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
10
10
|
});
|
|
11
11
|
exports.TreeLine = TreeLine;
|
|
12
12
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
13
|
+
const classnames_1 = __importDefault(require("classnames"));
|
|
13
14
|
const constants_1 = require("../../constants");
|
|
14
15
|
const styles_module_scss_1 = __importDefault(require('./styles.module.css'));
|
|
15
16
|
function TreeLine(_ref) {
|
|
16
17
|
let {
|
|
18
|
+
className,
|
|
17
19
|
halfWidth,
|
|
18
|
-
halfHeight,
|
|
19
20
|
horizontal,
|
|
20
|
-
visible
|
|
21
|
+
visible,
|
|
22
|
+
height,
|
|
23
|
+
width
|
|
21
24
|
} = _ref;
|
|
22
25
|
return (0, jsx_runtime_1.jsx)("div", {
|
|
23
|
-
className: styles_module_scss_1.default.treeLine,
|
|
26
|
+
className: (0, classnames_1.default)(styles_module_scss_1.default.treeLine, className),
|
|
27
|
+
style: {
|
|
28
|
+
height,
|
|
29
|
+
width
|
|
30
|
+
},
|
|
24
31
|
"data-horizontal": horizontal || undefined,
|
|
25
32
|
"data-half-width": halfWidth || undefined,
|
|
26
|
-
"data-half-height": halfHeight || undefined,
|
|
27
33
|
"data-visible": visible || undefined,
|
|
28
34
|
"data-test-id": constants_1.TEST_IDS.line
|
|
29
35
|
});
|
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
left:50%;
|
|
16
16
|
transform:translateX(-50%);
|
|
17
17
|
width:1px;
|
|
18
|
-
height:
|
|
18
|
+
height:100%;
|
|
19
19
|
background:var(--sys-neutral-decor-default, #dde0ea);
|
|
20
20
|
}
|
|
21
|
-
.treeLine[data-
|
|
22
|
-
height:
|
|
21
|
+
.treeLine[data-horizontal]{
|
|
22
|
+
min-height:var(--size-tree-item-height, 32px);
|
|
23
23
|
}
|
|
24
24
|
.treeLine[data-horizontal]::after{
|
|
25
25
|
top:50%;
|
|
@@ -8,4 +8,4 @@ type TreeNodeComponentProps = TreeNodeProps & {
|
|
|
8
8
|
parentNode?: ParentNode;
|
|
9
9
|
tabIndexAvailable?: boolean;
|
|
10
10
|
};
|
|
11
|
-
export declare
|
|
11
|
+
export declare const TreeNode: import("react").ForwardRefExoticComponent<TreeNodeComponentProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -16,7 +16,7 @@ var __importDefault = void 0 && (void 0).__importDefault || function (mod) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", {
|
|
17
17
|
value: true
|
|
18
18
|
});
|
|
19
|
-
exports.TreeNode =
|
|
19
|
+
exports.TreeNode = void 0;
|
|
20
20
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
21
21
|
const classnames_1 = __importDefault(require("classnames"));
|
|
22
22
|
const react_1 = require("react");
|
|
@@ -33,7 +33,7 @@ const TreeLine_1 = require("../TreeLine");
|
|
|
33
33
|
const components_1 = require("./components");
|
|
34
34
|
const styles_module_scss_1 = __importDefault(require('./styles.module.css'));
|
|
35
35
|
const utils_2 = require("./utils");
|
|
36
|
-
|
|
36
|
+
exports.TreeNode = (0, react_1.forwardRef)((_a, ref) => {
|
|
37
37
|
var {
|
|
38
38
|
id,
|
|
39
39
|
title,
|
|
@@ -77,7 +77,7 @@ function TreeNode(_a) {
|
|
|
77
77
|
} = (0, TreeContext_1.useTreeContext)();
|
|
78
78
|
const [isDroplistOpen, setDroplistOpen] = (0, react_1.useState)(false);
|
|
79
79
|
const [isDroplistTriggerFocused, setFocusDroplistTrigger] = (0, react_1.useState)(false);
|
|
80
|
-
const
|
|
80
|
+
const contentRef = (0, react_1.useRef)(null);
|
|
81
81
|
const isExpandable = Array.isArray(nested);
|
|
82
82
|
const isExpanded = isExpandable ? expandedNodes === null || expandedNodes === void 0 ? void 0 : expandedNodes.includes(id) : undefined;
|
|
83
83
|
const nestedNodesSelection = (0, react_1.useMemo)(() => {
|
|
@@ -87,8 +87,8 @@ function TreeNode(_a) {
|
|
|
87
87
|
const isSelected = (Array.isArray(selected) ? selected.includes(id) || (nestedNodesSelection === null || nestedNodesSelection === void 0 ? void 0 : nestedNodesSelection.allSelected) : selected === id) || false;
|
|
88
88
|
const isFocused = focusedNodeId === id;
|
|
89
89
|
(0, react_1.useEffect)(() => {
|
|
90
|
-
if (
|
|
91
|
-
|
|
90
|
+
if (contentRef.current && isFocused) {
|
|
91
|
+
contentRef.current.focus();
|
|
92
92
|
}
|
|
93
93
|
}, [isFocused]);
|
|
94
94
|
const treeNodeIcon = (0, react_1.useMemo)(() => {
|
|
@@ -119,14 +119,14 @@ function TreeNode(_a) {
|
|
|
119
119
|
setFocusPosition(id);
|
|
120
120
|
if (!e) {
|
|
121
121
|
setFocusDroplistTrigger(false);
|
|
122
|
-
(_a =
|
|
122
|
+
(_a = contentRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
123
123
|
}
|
|
124
124
|
};
|
|
125
125
|
const handleBlurActions = () => {
|
|
126
126
|
var _a;
|
|
127
127
|
if (isDroplistTriggerFocused && !isDroplistOpen) {
|
|
128
128
|
setFocusDroplistTrigger(false);
|
|
129
|
-
(_a =
|
|
129
|
+
(_a = contentRef.current) === null || _a === void 0 ? void 0 : _a.blur();
|
|
130
130
|
}
|
|
131
131
|
};
|
|
132
132
|
const handleKeyDown = e => {
|
|
@@ -171,13 +171,13 @@ function TreeNode(_a) {
|
|
|
171
171
|
e.preventDefault();
|
|
172
172
|
if (isDroplistTriggerFocused) {
|
|
173
173
|
setFocusDroplistTrigger(false);
|
|
174
|
-
(_a =
|
|
174
|
+
(_a = contentRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
175
175
|
}
|
|
176
176
|
return;
|
|
177
177
|
}
|
|
178
178
|
case 'Escape':
|
|
179
179
|
{
|
|
180
|
-
(_b =
|
|
180
|
+
(_b = contentRef.current) === null || _b === void 0 ? void 0 : _b.blur();
|
|
181
181
|
return;
|
|
182
182
|
}
|
|
183
183
|
case ' ':
|
|
@@ -197,6 +197,7 @@ function TreeNode(_a) {
|
|
|
197
197
|
className: (0, classnames_1.default)(styles_module_scss_1.default.treeNode, className)
|
|
198
198
|
}, (0, utils_1.extractSupportProps)(rest), {
|
|
199
199
|
"data-node-id": id,
|
|
200
|
+
ref: ref,
|
|
200
201
|
children: [parentNode && (0, jsx_runtime_1.jsx)(TreeLine_1.TreeLine, {
|
|
201
202
|
halfWidth: Boolean(nested),
|
|
202
203
|
horizontal: true,
|
|
@@ -204,15 +205,21 @@ function TreeNode(_a) {
|
|
|
204
205
|
"data-test-id": constants_1.TEST_IDS.line
|
|
205
206
|
}), !parentNode && !nested && (0, jsx_runtime_1.jsx)(TreeLine_1.TreeLine, {
|
|
206
207
|
visible: false
|
|
207
|
-
}), isExpandable && (0, jsx_runtime_1.
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
208
|
+
}), isExpandable && (0, jsx_runtime_1.jsxs)("div", {
|
|
209
|
+
className: styles_module_scss_1.default.treeNodeExpandButtonWrapper,
|
|
210
|
+
children: [(0, jsx_runtime_1.jsx)(button_1.ButtonFunction, {
|
|
211
|
+
size: 'xs',
|
|
212
|
+
icon: (0, jsx_runtime_1.jsx)(icons_1.ChevronRightSVG, {}),
|
|
213
|
+
loading: isLoading,
|
|
214
|
+
onClick: onChevronClick,
|
|
215
|
+
"data-expanded": isExpanded || undefined,
|
|
216
|
+
className: styles_module_scss_1.default.treeNodeExpandButton,
|
|
217
|
+
tabIndex: -1,
|
|
218
|
+
"data-test-id": constants_1.TEST_IDS.chevron
|
|
219
|
+
}), (0, jsx_runtime_1.jsx)(TreeLine_1.TreeLine, {
|
|
220
|
+
visible: isExpanded && showLines,
|
|
221
|
+
height: '100%'
|
|
222
|
+
})]
|
|
216
223
|
}), (0, jsx_runtime_1.jsxs)("div", {
|
|
217
224
|
role: 'treeitem',
|
|
218
225
|
"aria-expanded": isExpanded,
|
|
@@ -227,7 +234,7 @@ function TreeNode(_a) {
|
|
|
227
234
|
tabIndex: tabIndexAvailable ? 0 : -1,
|
|
228
235
|
className: styles_module_scss_1.default.treeNodeContent,
|
|
229
236
|
"data-test-id": constants_1.TEST_IDS.item,
|
|
230
|
-
ref:
|
|
237
|
+
ref: contentRef,
|
|
231
238
|
children: [(isMultiSelect || showToggle) && (0, jsx_runtime_1.jsxs)("div", {
|
|
232
239
|
className: styles_module_scss_1.default.treeNodeCheckboxWrap,
|
|
233
240
|
children: [isMultiSelect && (0, jsx_runtime_1.jsx)(toggles_1.Checkbox, {
|
|
@@ -277,4 +284,4 @@ function TreeNode(_a) {
|
|
|
277
284
|
})]
|
|
278
285
|
})]
|
|
279
286
|
}));
|
|
280
|
-
}
|
|
287
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
.treeNode{
|
|
2
2
|
display:flex;
|
|
3
|
-
align-items:
|
|
3
|
+
align-items:flex-start;
|
|
4
4
|
box-sizing:border-box;
|
|
5
5
|
width:100%;
|
|
6
6
|
}
|
|
@@ -19,9 +19,12 @@
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
.treeNodeTitle{
|
|
22
|
+
min-height:var(--size-tree-item-wrap, 24px);
|
|
23
|
+
display:flex;
|
|
22
24
|
flex-grow:1;
|
|
25
|
+
align-items:center;
|
|
23
26
|
box-sizing:border-box;
|
|
24
|
-
min-width:var(--size-tree-item-
|
|
27
|
+
min-width:var(--size-tree-item-wrap, 24px);
|
|
25
28
|
color:var(--sys-neutral-text-main, #41424e);
|
|
26
29
|
}
|
|
27
30
|
|
|
@@ -34,15 +37,17 @@
|
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
.treeNodeContent{
|
|
37
|
-
height:var(--size-tree-item-height, 32px);
|
|
38
40
|
gap:var(--space-tree-item-content-layout-gap, 4px);
|
|
41
|
+
padding-top:var(--space-tree-item-content-layout-padding, 4px);
|
|
39
42
|
padding-right:var(--space-tree-item-content-layout-padding, 4px);
|
|
43
|
+
padding-bottom:var(--space-tree-item-content-layout-padding, 4px);
|
|
40
44
|
padding-left:var(--space-tree-item-content-layout-padding, 4px);
|
|
41
45
|
border-radius:var(--radius-tree-item-content-layout, 8px);
|
|
46
|
+
min-height:var(--size-tree-item-height, 32px);
|
|
42
47
|
cursor:pointer;
|
|
43
48
|
position:relative;
|
|
44
49
|
display:flex;
|
|
45
|
-
align-items:
|
|
50
|
+
align-items:flex-start;
|
|
46
51
|
box-sizing:border-box;
|
|
47
52
|
width:100%;
|
|
48
53
|
}
|
|
@@ -93,8 +98,8 @@
|
|
|
93
98
|
}
|
|
94
99
|
|
|
95
100
|
.treeNodeCheckboxWrap{
|
|
96
|
-
width:var(--size-tree-item-
|
|
97
|
-
height:var(--size-tree-item-
|
|
101
|
+
width:var(--size-tree-item-wrap, 24px);
|
|
102
|
+
height:var(--size-tree-item-wrap, 24px);
|
|
98
103
|
display:flex;
|
|
99
104
|
flex-shrink:0;
|
|
100
105
|
align-items:center;
|
|
@@ -103,6 +108,7 @@
|
|
|
103
108
|
}
|
|
104
109
|
|
|
105
110
|
.treeNodeExpandButton{
|
|
111
|
+
min-height:var(--size-tree-item-height, 32px);
|
|
106
112
|
box-sizing:border-box;
|
|
107
113
|
}
|
|
108
114
|
.treeNodeExpandButton svg{
|
|
@@ -110,4 +116,12 @@
|
|
|
110
116
|
}
|
|
111
117
|
.treeNodeExpandButton[data-expanded] svg{
|
|
112
118
|
transform:rotate(90deg);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.treeNodeExpandButtonWrapper{
|
|
122
|
+
overflow:hidden;
|
|
123
|
+
display:flex;
|
|
124
|
+
flex-direction:column;
|
|
125
|
+
align-self:stretch;
|
|
126
|
+
min-width:var(--size-button-xs, 24px);
|
|
113
127
|
}
|
|
@@ -7,5 +7,5 @@ type ExpandableTreeNodeProps = {
|
|
|
7
7
|
};
|
|
8
8
|
tabIndexAvailable?: boolean;
|
|
9
9
|
};
|
|
10
|
-
export declare
|
|
10
|
+
export declare const ExpandableTreeNode: import("react").ForwardRefExoticComponent<ExpandableTreeNodeProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
11
11
|
export {};
|
|
@@ -19,7 +19,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
19
19
|
return t;
|
|
20
20
|
};
|
|
21
21
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
22
|
-
import { useEffect,
|
|
22
|
+
import { forwardRef, useEffect, useRef, useState } from 'react';
|
|
23
23
|
import useTransition from 'react-transition-state';
|
|
24
24
|
import { TEST_IDS, TRANSITION_TIMING } from '../../constants';
|
|
25
25
|
import { useTreeContext } from '../../contexts/TreeContext';
|
|
@@ -27,7 +27,7 @@ import { TreeItem } from '../TreeItem';
|
|
|
27
27
|
import { TreeLine } from '../TreeLine';
|
|
28
28
|
import { TreeNode } from '../TreeNode';
|
|
29
29
|
import styles from './styles.module.css';
|
|
30
|
-
export
|
|
30
|
+
export const ExpandableTreeNode = forwardRef((_a, ref) => {
|
|
31
31
|
var _b = _a.node, { 'data-test-id': dataTestId } = _b, node = __rest(_b, ['data-test-id']), { parentNode, tabIndexAvailable } = _a;
|
|
32
32
|
const { expandedNodes, onExpand, onDataLoad, showLines } = useTreeContext();
|
|
33
33
|
const isExpandable = Boolean(node.nested);
|
|
@@ -39,19 +39,30 @@ export function ExpandableTreeNode(_a) {
|
|
|
39
39
|
enter: isExpanded,
|
|
40
40
|
});
|
|
41
41
|
const showContent = node.nested && node.nested.length > 0 && state.status !== 'exited';
|
|
42
|
-
const
|
|
42
|
+
const childrenRefs = useRef([]);
|
|
43
|
+
const [lastItemHeight, setLastItemHeight] = useState(0);
|
|
44
|
+
useEffect(() => {
|
|
43
45
|
var _a, _b;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
const lastItem = (_a = childrenRefs.current) === null || _a === void 0 ? void 0 : _a.at(-1);
|
|
47
|
+
if (lastItem) {
|
|
48
|
+
const observer = new ResizeObserver(entities => entities.forEach(entity => {
|
|
49
|
+
if (entity.target === lastItem) {
|
|
50
|
+
const [{ blockSize: newHeight }] = entity.contentBoxSize;
|
|
51
|
+
setLastItemHeight(newHeight);
|
|
52
|
+
}
|
|
53
|
+
}));
|
|
54
|
+
observer.observe(lastItem);
|
|
55
|
+
setLastItemHeight((_b = lastItem.scrollHeight) !== null && _b !== void 0 ? _b : 0);
|
|
56
|
+
return () => observer.disconnect();
|
|
57
|
+
}
|
|
58
|
+
}, [state.status]);
|
|
48
59
|
useEffect(() => {
|
|
49
60
|
var _a;
|
|
50
61
|
if (((_a = node.nested) === null || _a === void 0 ? void 0 : _a.length) && isExpanded && state.status === 'exited') {
|
|
51
62
|
toggle(true);
|
|
52
63
|
}
|
|
53
64
|
}, [isExpanded, node.nested, state.status]);
|
|
54
|
-
const toggleExpand = () => __awaiter(
|
|
65
|
+
const toggleExpand = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
55
66
|
if (node.nested && !node.nested.length && !isExpanded && onDataLoad) {
|
|
56
67
|
setLoading(true);
|
|
57
68
|
yield onDataLoad(node).finally(() => {
|
|
@@ -81,8 +92,8 @@ export function ExpandableTreeNode(_a) {
|
|
|
81
92
|
return;
|
|
82
93
|
}
|
|
83
94
|
};
|
|
84
|
-
return (_jsxs("div", { className: styles.expandableTreeNode, "data-test-id": dataTestId, "data-expandable": Boolean(node.nested) || undefined, "data-disabled": node.disabled || undefined, children: [_jsx(TreeNode, Object.assign({}, node, { isLoading: isLoading, parentNode: parentNode, onChevronClick: toggleExpand, onKeyDown: handleKeyDown, tabIndexAvailable: tabIndexAvailable })), node.nested && (_jsx("div", { className: styles.expandableWrap, "data-expanded": isExpanded || undefined, "data-test-id": TEST_IDS.expandable, children: showContent && (_jsxs("div", { className: styles.expandableContent, "data-test-id": TEST_IDS.expandableContent, children: [_jsx(TreeLine, { visible: showLines,
|
|
95
|
+
return (_jsxs("div", { className: styles.expandableTreeNode, "data-test-id": dataTestId, "data-expandable": Boolean(node.nested) || undefined, "data-disabled": node.disabled || undefined, ref: ref, children: [_jsx(TreeNode, Object.assign({}, node, { isLoading: isLoading, parentNode: parentNode, onChevronClick: toggleExpand, onKeyDown: handleKeyDown, tabIndexAvailable: tabIndexAvailable })), node.nested && (_jsx("div", { className: styles.expandableWrap, "data-expanded": isExpanded || undefined, "data-test-id": TEST_IDS.expandable, children: showContent && (_jsxs("div", { className: styles.expandableContent, "data-test-id": TEST_IDS.expandableContent, children: [_jsx(TreeLine, { visible: showLines, "data-test-id": TEST_IDS.line, height: `calc(100% - ${lastItemHeight}px)`, className: styles.treeLine }), _jsx("div", { className: styles.expandableNested, children: node.nested.map((nestedNode, index) => {
|
|
85
96
|
const parent = { id: node.id, nested: node.nested, parentNode };
|
|
86
|
-
return (_jsx(TreeItem, { node: Object.assign(Object.assign({}, nestedNode), { disabled: node.disabled || nestedNode.disabled }), parentNode: parent }, nestedNode.id));
|
|
97
|
+
return (_jsx(TreeItem, { ref: el => (childrenRefs.current[index] = el), node: Object.assign(Object.assign({}, nestedNode), { disabled: node.disabled || nestedNode.disabled }), parentNode: parent }, nestedNode.id));
|
|
87
98
|
}) })] })) }))] }));
|
|
88
|
-
}
|
|
99
|
+
});
|
|
@@ -4,5 +4,5 @@ type TreeItemProps = {
|
|
|
4
4
|
parentNode?: ParentNode;
|
|
5
5
|
tabIndexAvailable?: boolean;
|
|
6
6
|
};
|
|
7
|
-
export declare
|
|
7
|
+
export declare const TreeItem: import("react").ForwardRefExoticComponent<TreeItemProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
8
8
|
export {};
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from 'react';
|
|
2
3
|
import { TEST_IDS } from '../../constants';
|
|
3
4
|
import { ExpandableTreeNode } from '../ExpandableTreeNode';
|
|
4
5
|
import { TreeNode } from '../TreeNode';
|
|
5
|
-
export
|
|
6
|
+
export const TreeItem = forwardRef(({ node, tabIndexAvailable, parentNode }, ref) => {
|
|
6
7
|
const dataTestId = node['data-test-id'] || TEST_IDS.node;
|
|
7
8
|
const nodeProps = Object.assign(Object.assign({}, node), { 'data-test-id': dataTestId });
|
|
8
9
|
if (node.nested) {
|
|
9
|
-
return _jsx(ExpandableTreeNode, { node: nodeProps, tabIndexAvailable: tabIndexAvailable, parentNode: parentNode });
|
|
10
|
+
return (_jsx(ExpandableTreeNode, { node: nodeProps, tabIndexAvailable: tabIndexAvailable, parentNode: parentNode, ref: ref }));
|
|
10
11
|
}
|
|
11
|
-
return _jsx(TreeNode, Object.assign({}, nodeProps, { tabIndexAvailable: tabIndexAvailable, parentNode: parentNode }));
|
|
12
|
-
}
|
|
12
|
+
return _jsx(TreeNode, Object.assign({}, nodeProps, { tabIndexAvailable: tabIndexAvailable, parentNode: parentNode, ref: ref }));
|
|
13
|
+
});
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { CSSProperties } from 'react';
|
|
1
2
|
export type TreeLineProps = {
|
|
3
|
+
className?: string;
|
|
2
4
|
halfWidth?: boolean;
|
|
3
|
-
halfHeight?: boolean;
|
|
4
5
|
visible?: boolean;
|
|
5
6
|
horizontal?: boolean;
|
|
6
|
-
}
|
|
7
|
-
export declare function TreeLine({
|
|
7
|
+
} & Pick<CSSProperties, 'height' | 'width'>;
|
|
8
|
+
export declare function TreeLine({ className, halfWidth, horizontal, visible, height, width }: TreeLineProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import cn from 'classnames';
|
|
2
3
|
import { TEST_IDS } from '../../constants';
|
|
3
4
|
import styles from './styles.module.css';
|
|
4
|
-
export function TreeLine({
|
|
5
|
-
return (_jsx("div", { className: styles.treeLine,
|
|
5
|
+
export function TreeLine({ className, halfWidth, horizontal, visible, height, width }) {
|
|
6
|
+
return (_jsx("div", { className: cn(styles.treeLine, className), style: { height, width }, "data-horizontal": horizontal || undefined, "data-half-width": halfWidth || undefined, "data-visible": visible || undefined, "data-test-id": TEST_IDS.line }));
|
|
6
7
|
}
|
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
left:50%;
|
|
16
16
|
transform:translateX(-50%);
|
|
17
17
|
width:1px;
|
|
18
|
-
height:
|
|
18
|
+
height:100%;
|
|
19
19
|
background:var(--sys-neutral-decor-default, #dde0ea);
|
|
20
20
|
}
|
|
21
|
-
.treeLine[data-
|
|
22
|
-
height:
|
|
21
|
+
.treeLine[data-horizontal]{
|
|
22
|
+
min-height:var(--size-tree-item-height, 32px);
|
|
23
23
|
}
|
|
24
24
|
.treeLine[data-horizontal]::after{
|
|
25
25
|
top:50%;
|
|
@@ -8,4 +8,4 @@ type TreeNodeComponentProps = TreeNodeProps & {
|
|
|
8
8
|
parentNode?: ParentNode;
|
|
9
9
|
tabIndexAvailable?: boolean;
|
|
10
10
|
};
|
|
11
|
-
export declare
|
|
11
|
+
export declare const TreeNode: import("react").ForwardRefExoticComponent<TreeNodeComponentProps & import("react").RefAttributes<HTMLDivElement>>;
|