@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.
Files changed (31) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/cjs/helperComponents/ExpandableTreeNode/ExpandableTreeNode.d.ts +1 -1
  3. package/dist/cjs/helperComponents/ExpandableTreeNode/ExpandableTreeNode.js +28 -11
  4. package/dist/cjs/helperComponents/ExpandableTreeNode/styles.module.css +4 -0
  5. package/dist/cjs/helperComponents/TreeItem/TreeItem.d.ts +1 -1
  6. package/dist/cjs/helperComponents/TreeItem/TreeItem.js +8 -5
  7. package/dist/cjs/helperComponents/TreeLine/TreeLine.d.ts +4 -3
  8. package/dist/cjs/helperComponents/TreeLine/TreeLine.js +10 -4
  9. package/dist/cjs/helperComponents/TreeLine/styles.module.css +3 -3
  10. package/dist/cjs/helperComponents/TreeNode/TreeNode.d.ts +1 -1
  11. package/dist/cjs/helperComponents/TreeNode/TreeNode.js +27 -20
  12. package/dist/cjs/helperComponents/TreeNode/styles.module.css +20 -6
  13. package/dist/esm/helperComponents/ExpandableTreeNode/ExpandableTreeNode.d.ts +1 -1
  14. package/dist/esm/helperComponents/ExpandableTreeNode/ExpandableTreeNode.js +22 -11
  15. package/dist/esm/helperComponents/ExpandableTreeNode/styles.module.css +4 -0
  16. package/dist/esm/helperComponents/TreeItem/TreeItem.d.ts +1 -1
  17. package/dist/esm/helperComponents/TreeItem/TreeItem.js +5 -4
  18. package/dist/esm/helperComponents/TreeLine/TreeLine.d.ts +4 -3
  19. package/dist/esm/helperComponents/TreeLine/TreeLine.js +3 -2
  20. package/dist/esm/helperComponents/TreeLine/styles.module.css +3 -3
  21. package/dist/esm/helperComponents/TreeNode/TreeNode.d.ts +1 -1
  22. package/dist/esm/helperComponents/TreeNode/TreeNode.js +13 -11
  23. package/dist/esm/helperComponents/TreeNode/styles.module.css +20 -6
  24. package/package.json +2 -2
  25. package/src/helperComponents/ExpandableTreeNode/ExpandableTreeNode.tsx +120 -97
  26. package/src/helperComponents/ExpandableTreeNode/styles.module.scss +6 -0
  27. package/src/helperComponents/TreeItem/TreeItem.tsx +8 -4
  28. package/src/helperComponents/TreeLine/TreeLine.tsx +8 -5
  29. package/src/helperComponents/TreeLine/styles.module.scss +9 -13
  30. package/src/helperComponents/TreeNode/TreeNode.tsx +266 -245
  31. package/src/helperComponents/TreeNode/styles.module.scss +36 -19
@@ -1,5 +1,14 @@
1
1
  import cn from 'classnames';
2
- import { FocusEvent, KeyboardEventHandler, MouseEventHandler, useEffect, useMemo, useRef, useState } from 'react';
2
+ import {
3
+ FocusEvent,
4
+ forwardRef,
5
+ KeyboardEventHandler,
6
+ MouseEventHandler,
7
+ useEffect,
8
+ useMemo,
9
+ useRef,
10
+ useState,
11
+ } from 'react';
3
12
 
4
13
  import { ButtonFunction } from '@snack-uikit/button';
5
14
  import { ChevronRightSVG, FileSVG, FolderOpenSVG, FolderSVG } from '@snack-uikit/icons';
@@ -27,276 +36,288 @@ type TreeNodeComponentProps = TreeNodeProps & {
27
36
  tabIndexAvailable?: boolean;
28
37
  };
29
38
 
30
- export function TreeNode({
31
- id,
32
- title,
33
- icon = <FileSVG size={24} />,
34
- expandedIcon = <FolderOpenSVG size={24} />,
35
- collapsedIcon = <FolderSVG size={24} />,
36
- disabled,
37
- onClick,
38
- nested,
39
- className,
40
- onChevronClick,
41
- onKeyDown,
42
- isLoading,
43
- parentNode,
44
- tabIndexAvailable,
45
- ...rest
46
- }: TreeNodeComponentProps) {
47
- const {
48
- isMultiSelect,
49
- isSelectable,
50
- onNodeClick,
51
- selected,
52
- expandedNodes,
53
- onSelect,
54
- nodeActions,
55
- parentActions,
56
- setFocusPosition,
57
- resetFocusPosition,
58
- focusedNodeId,
59
- setFocusIndex,
60
- focusableNodeIds,
61
- showToggle,
62
- showLines,
63
- showIcons,
64
- } = useTreeContext();
65
-
66
- const [isDroplistOpen, setDroplistOpen] = useState(false);
67
- const [isDroplistTriggerFocused, setFocusDroplistTrigger] = useState(false);
68
-
69
- const ref = useRef<HTMLDivElement | null>(null);
70
-
71
- const isExpandable = Array.isArray(nested);
72
- const isExpanded = isExpandable ? expandedNodes?.includes(id) : undefined;
73
-
74
- const nestedNodesSelection = useMemo(() => {
75
- if (!nested || !selected) return undefined;
76
-
77
- return checkNestedNodesSelection(nested, Array.isArray(selected) ? selected : [selected]);
78
- }, [nested, selected]);
79
-
80
- const isSelected =
81
- (Array.isArray(selected) ? selected.includes(id) || nestedNodesSelection?.allSelected : selected === id) || false;
82
-
83
- const isFocused = focusedNodeId === id;
84
-
85
- useEffect(() => {
86
- if (ref.current && isFocused) {
87
- ref.current.focus();
88
- }
89
- }, [isFocused]);
90
-
91
- const treeNodeIcon = useMemo(() => {
92
- if (!showIcons) return undefined;
93
-
94
- if (isExpandable) {
95
- return isExpanded ? expandedIcon : collapsedIcon;
96
- }
97
-
98
- return icon;
99
- }, [showIcons, isExpandable, icon, isExpanded, expandedIcon, collapsedIcon]);
100
-
101
- const handleClick: TreeNodeProps['onClick'] = e => {
102
- onNodeClick(
103
- {
104
- id,
105
- title,
106
- disabled,
107
- nested,
108
- onClick,
109
- },
110
- e,
111
- );
112
- };
113
-
114
- const handleSelect = () => {
115
- onSelect(
116
- {
117
- id,
118
- disabled,
119
- nested,
120
- },
39
+ export const TreeNode = forwardRef<HTMLDivElement, TreeNodeComponentProps>(
40
+ (
41
+ {
42
+ id,
43
+ title,
44
+ icon = <FileSVG size={24} />,
45
+ expandedIcon = <FolderOpenSVG size={24} />,
46
+ collapsedIcon = <FolderSVG size={24} />,
47
+ disabled,
48
+ onClick,
49
+ nested,
50
+ className,
51
+ onChevronClick,
52
+ onKeyDown,
53
+ isLoading,
121
54
  parentNode,
122
- );
123
- };
55
+ tabIndexAvailable,
56
+ ...rest
57
+ },
58
+ ref,
59
+ ) => {
60
+ const {
61
+ isMultiSelect,
62
+ isSelectable,
63
+ onNodeClick,
64
+ selected,
65
+ expandedNodes,
66
+ onSelect,
67
+ nodeActions,
68
+ parentActions,
69
+ setFocusPosition,
70
+ resetFocusPosition,
71
+ focusedNodeId,
72
+ setFocusIndex,
73
+ focusableNodeIds,
74
+ showToggle,
75
+ showLines,
76
+ showIcons,
77
+ } = useTreeContext();
78
+
79
+ const [isDroplistOpen, setDroplistOpen] = useState(false);
80
+ const [isDroplistTriggerFocused, setFocusDroplistTrigger] = useState(false);
81
+
82
+ const contentRef = useRef<HTMLDivElement | null>(null);
83
+
84
+ const isExpandable = Array.isArray(nested);
85
+ const isExpanded = isExpandable ? expandedNodes?.includes(id) : undefined;
86
+
87
+ const nestedNodesSelection = useMemo(() => {
88
+ if (!nested || !selected) return undefined;
89
+
90
+ return checkNestedNodesSelection(nested, Array.isArray(selected) ? selected : [selected]);
91
+ }, [nested, selected]);
92
+
93
+ const isSelected =
94
+ (Array.isArray(selected) ? selected.includes(id) || nestedNodesSelection?.allSelected : selected === id) || false;
95
+
96
+ const isFocused = focusedNodeId === id;
97
+
98
+ useEffect(() => {
99
+ if (contentRef.current && isFocused) {
100
+ contentRef.current.focus();
101
+ }
102
+ }, [isFocused]);
124
103
 
125
- const handleFocus = (e?: FocusEvent) => {
126
- setFocusPosition(id);
104
+ const treeNodeIcon = useMemo(() => {
105
+ if (!showIcons) return undefined;
127
106
 
128
- if (!e) {
129
- setFocusDroplistTrigger(false);
130
- ref.current?.focus();
131
- }
132
- };
107
+ if (isExpandable) {
108
+ return isExpanded ? expandedIcon : collapsedIcon;
109
+ }
133
110
 
134
- const handleBlurActions = () => {
135
- if (isDroplistTriggerFocused && !isDroplistOpen) {
136
- setFocusDroplistTrigger(false);
111
+ return icon;
112
+ }, [showIcons, isExpandable, icon, isExpanded, expandedIcon, collapsedIcon]);
113
+
114
+ const handleClick: TreeNodeProps['onClick'] = e => {
115
+ onNodeClick(
116
+ {
117
+ id,
118
+ title,
119
+ disabled,
120
+ nested,
121
+ onClick,
122
+ },
123
+ e,
124
+ );
125
+ };
126
+
127
+ const handleSelect = () => {
128
+ onSelect(
129
+ {
130
+ id,
131
+ disabled,
132
+ nested,
133
+ },
134
+ parentNode,
135
+ );
136
+ };
137
+
138
+ const handleFocus = (e?: FocusEvent) => {
139
+ setFocusPosition(id);
140
+
141
+ if (!e) {
142
+ setFocusDroplistTrigger(false);
143
+ contentRef.current?.focus();
144
+ }
145
+ };
137
146
 
138
- ref.current?.blur();
139
- }
140
- };
147
+ const handleBlurActions = () => {
148
+ if (isDroplistTriggerFocused && !isDroplistOpen) {
149
+ setFocusDroplistTrigger(false);
141
150
 
142
- const handleKeyDown: KeyboardEventHandler<HTMLElement> = e => {
143
- onKeyDown?.(e);
151
+ contentRef.current?.blur();
152
+ }
153
+ };
144
154
 
145
- const focusableCount = focusableNodeIds.length;
155
+ const handleKeyDown: KeyboardEventHandler<HTMLElement> = e => {
156
+ onKeyDown?.(e);
146
157
 
147
- switch (e.key) {
148
- case 'ArrowDown': {
149
- e.preventDefault();
158
+ const focusableCount = focusableNodeIds.length;
150
159
 
151
- setFocusIndex((prev = 0) => {
152
- if (prev >= focusableCount - 1) {
153
- return focusableCount - 1;
154
- }
155
- return prev + 1;
156
- });
160
+ switch (e.key) {
161
+ case 'ArrowDown': {
162
+ e.preventDefault();
157
163
 
158
- return;
159
- }
160
- case 'ArrowUp': {
161
- e.preventDefault();
164
+ setFocusIndex((prev = 0) => {
165
+ if (prev >= focusableCount - 1) {
166
+ return focusableCount - 1;
167
+ }
168
+ return prev + 1;
169
+ });
162
170
 
163
- setFocusIndex((prev = 0) => {
164
- if (!prev) {
165
- return 0;
166
- }
167
- return prev - 1;
168
- });
171
+ return;
172
+ }
173
+ case 'ArrowUp': {
174
+ e.preventDefault();
169
175
 
170
- return;
171
- }
172
- case 'ArrowRight': {
173
- e.preventDefault();
176
+ setFocusIndex((prev = 0) => {
177
+ if (!prev) {
178
+ return 0;
179
+ }
180
+ return prev - 1;
181
+ });
174
182
 
175
- if (isExpanded || !isExpandable || disabled) {
176
- setFocusDroplistTrigger(true);
183
+ return;
177
184
  }
185
+ case 'ArrowRight': {
186
+ e.preventDefault();
178
187
 
179
- return;
180
- }
181
- case 'ArrowLeft': {
182
- e.preventDefault();
188
+ if (isExpanded || !isExpandable || disabled) {
189
+ setFocusDroplistTrigger(true);
190
+ }
183
191
 
184
- if (isDroplistTriggerFocused) {
185
- setFocusDroplistTrigger(false);
186
- ref.current?.focus();
192
+ return;
187
193
  }
194
+ case 'ArrowLeft': {
195
+ e.preventDefault();
188
196
 
189
- return;
190
- }
191
- case 'Escape': {
192
- ref.current?.blur();
193
- return;
194
- }
195
- case ' ':
196
- case 'Enter': {
197
- e.preventDefault();
198
- handleSelect();
199
- return;
197
+ if (isDroplistTriggerFocused) {
198
+ setFocusDroplistTrigger(false);
199
+ contentRef.current?.focus();
200
+ }
201
+
202
+ return;
203
+ }
204
+ case 'Escape': {
205
+ contentRef.current?.blur();
206
+ return;
207
+ }
208
+ case ' ':
209
+ case 'Enter': {
210
+ e.preventDefault();
211
+ handleSelect();
212
+ return;
213
+ }
214
+ default:
215
+ return;
200
216
  }
201
- default:
202
- return;
203
- }
204
- };
205
-
206
- const getNodeActions = nested ? parentActions : nodeActions;
207
-
208
- return (
209
- <div
210
- role='presentation'
211
- className={cn(styles.treeNode, className)}
212
- {...extractSupportProps(rest)}
213
- data-node-id={id}
214
- >
215
- {parentNode && (
216
- <TreeLine halfWidth={Boolean(nested)} horizontal visible={showLines} data-test-id={TEST_IDS.line} />
217
- )}
218
-
219
- {!parentNode && !nested && <TreeLine visible={false} />}
220
-
221
- {isExpandable && (
222
- <ButtonFunction
223
- size='xs'
224
- icon={<ChevronRightSVG />}
225
- loading={isLoading}
226
- onClick={onChevronClick}
227
- data-expanded={isExpanded || undefined}
228
- className={styles.treeNodeExpandButton}
229
- tabIndex={-1}
230
- data-test-id={TEST_IDS.chevron}
231
- />
232
- )}
217
+ };
233
218
 
219
+ const getNodeActions = nested ? parentActions : nodeActions;
220
+
221
+ return (
234
222
  <div
235
- role='treeitem'
236
- aria-expanded={isExpanded}
237
- aria-selected={
238
- isSelectable ? isSelected || (nestedNodesSelection?.someSelected && !isExpanded && !isMultiSelect) : undefined
239
- }
240
- aria-disabled={disabled}
241
- data-multiselect={isMultiSelect || undefined}
242
- data-droplist-active={isDroplistOpen || isDroplistTriggerFocused || undefined}
243
- onClick={handleClick}
244
- onKeyDown={handleKeyDown}
245
- onFocus={handleFocus}
246
- onBlur={resetFocusPosition}
247
- tabIndex={tabIndexAvailable ? 0 : -1}
248
- className={styles.treeNodeContent}
249
- data-test-id={TEST_IDS.item}
223
+ role='presentation'
224
+ className={cn(styles.treeNode, className)}
225
+ {...extractSupportProps(rest)}
226
+ data-node-id={id}
250
227
  ref={ref}
251
228
  >
252
- {(isMultiSelect || showToggle) && (
253
- <div className={styles.treeNodeCheckboxWrap}>
254
- {isMultiSelect && (
255
- <Checkbox
256
- size='s'
257
- disabled={disabled}
258
- checked={isSelected}
259
- indeterminate={!isSelected && nestedNodesSelection?.someSelected}
260
- onChange={handleSelect}
261
- onClick={stopPropagationClick}
262
- data-test-id={TEST_IDS.checkbox}
263
- tabIndex={-1}
264
- />
265
- )}
266
- {showToggle && (
267
- <Radio size='s' checked={isSelected} disabled={disabled} data-test-id={TEST_IDS.radio} tabIndex={-1} />
268
- )}
269
- </div>
229
+ {parentNode && (
230
+ <TreeLine halfWidth={Boolean(nested)} horizontal visible={showLines} data-test-id={TEST_IDS.line} />
270
231
  )}
271
232
 
272
- {treeNodeIcon && (
273
- <div className={styles.treeNodeIcon} data-test-id={TEST_IDS.icon}>
274
- {treeNodeIcon}
233
+ {!parentNode && !nested && <TreeLine visible={false} />}
234
+
235
+ {isExpandable && (
236
+ <div className={styles.treeNodeExpandButtonWrapper}>
237
+ <ButtonFunction
238
+ size='xs'
239
+ icon={<ChevronRightSVG />}
240
+ loading={isLoading}
241
+ onClick={onChevronClick}
242
+ data-expanded={isExpanded || undefined}
243
+ className={styles.treeNodeExpandButton}
244
+ tabIndex={-1}
245
+ data-test-id={TEST_IDS.chevron}
246
+ />
247
+
248
+ <TreeLine visible={isExpanded && showLines} height={'100%'} />
275
249
  </div>
276
250
  )}
277
251
 
278
- <Typography.SansBodyM tag='div' className={styles.treeNodeTitle}>
279
- {typeof title === 'string' && <TruncateString text={title} data-test-id={TEST_IDS.title} />}
280
- {typeof title !== 'string' && title({ id, disabled, nested } as TreeNodeProps)}
281
- </Typography.SansBodyM>
282
-
283
- {getNodeActions && (
284
- <TreeNodeActions
285
- getNodeActions={getNodeActions}
286
- node={{
287
- id,
288
- title,
289
- disabled,
290
- nested,
291
- }}
292
- focusNode={handleFocus}
293
- onBlurActions={handleBlurActions}
294
- isDroplistTriggerFocused={isDroplistTriggerFocused}
295
- isDroplistOpen={isDroplistOpen}
296
- setDroplistOpen={setDroplistOpen}
297
- />
298
- )}
252
+ <div
253
+ role='treeitem'
254
+ aria-expanded={isExpanded}
255
+ aria-selected={
256
+ isSelectable
257
+ ? isSelected || (nestedNodesSelection?.someSelected && !isExpanded && !isMultiSelect)
258
+ : undefined
259
+ }
260
+ aria-disabled={disabled}
261
+ data-multiselect={isMultiSelect || undefined}
262
+ data-droplist-active={isDroplistOpen || isDroplistTriggerFocused || undefined}
263
+ onClick={handleClick}
264
+ onKeyDown={handleKeyDown}
265
+ onFocus={handleFocus}
266
+ onBlur={resetFocusPosition}
267
+ tabIndex={tabIndexAvailable ? 0 : -1}
268
+ className={styles.treeNodeContent}
269
+ data-test-id={TEST_IDS.item}
270
+ ref={contentRef}
271
+ >
272
+ {(isMultiSelect || showToggle) && (
273
+ <div className={styles.treeNodeCheckboxWrap}>
274
+ {isMultiSelect && (
275
+ <Checkbox
276
+ size='s'
277
+ disabled={disabled}
278
+ checked={isSelected}
279
+ indeterminate={!isSelected && nestedNodesSelection?.someSelected}
280
+ onChange={handleSelect}
281
+ onClick={stopPropagationClick}
282
+ data-test-id={TEST_IDS.checkbox}
283
+ tabIndex={-1}
284
+ />
285
+ )}
286
+ {showToggle && (
287
+ <Radio size='s' checked={isSelected} disabled={disabled} data-test-id={TEST_IDS.radio} tabIndex={-1} />
288
+ )}
289
+ </div>
290
+ )}
291
+
292
+ {treeNodeIcon && (
293
+ <div className={styles.treeNodeIcon} data-test-id={TEST_IDS.icon}>
294
+ {treeNodeIcon}
295
+ </div>
296
+ )}
297
+
298
+ <Typography.SansBodyM tag='div' className={styles.treeNodeTitle}>
299
+ {typeof title === 'string' && <TruncateString text={title} data-test-id={TEST_IDS.title} />}
300
+ {typeof title !== 'string' && title({ id, disabled, nested } as TreeNodeProps)}
301
+ </Typography.SansBodyM>
302
+
303
+ {getNodeActions && (
304
+ <TreeNodeActions
305
+ getNodeActions={getNodeActions}
306
+ node={{
307
+ id,
308
+ title,
309
+ disabled,
310
+ nested,
311
+ }}
312
+ focusNode={handleFocus}
313
+ onBlurActions={handleBlurActions}
314
+ isDroplistTriggerFocused={isDroplistTriggerFocused}
315
+ isDroplistOpen={isDroplistOpen}
316
+ setDroplistOpen={setDroplistOpen}
317
+ />
318
+ )}
319
+ </div>
299
320
  </div>
300
- </div>
301
- );
302
- }
321
+ );
322
+ },
323
+ );
@@ -1,9 +1,9 @@
1
- @use '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-tree';
2
- @use '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-element';
1
+ @use '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-tree' as tree;
2
+ @use '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-element' as element;
3
3
 
4
4
  .treeNode {
5
5
  display: flex;
6
- align-items: center;
6
+ align-items: flex-start;
7
7
  box-sizing: border-box;
8
8
  width: 100%;
9
9
  }
@@ -16,19 +16,25 @@
16
16
 
17
17
  box-sizing: border-box;
18
18
 
19
- color: styles-tokens-tree.$sys-neutral-text-support;
19
+ color: tree.$sys-neutral-text-support;
20
20
 
21
21
  svg {
22
- width: styles-tokens-element.$icon-s !important; /* stylelint-disable-line declaration-no-important */
23
- height: styles-tokens-element.$icon-s !important; /* stylelint-disable-line declaration-no-important */
22
+ width: element.$icon-s !important; /* stylelint-disable-line declaration-no-important */
23
+ height: element.$icon-s !important; /* stylelint-disable-line declaration-no-important */
24
24
  }
25
25
  }
26
26
 
27
27
  .treeNodeTitle {
28
+ @include tree.composite-var(tree.$tree-item-content-wrap);
29
+
30
+ display: flex;
28
31
  flex-grow: 1;
32
+ align-items: center;
33
+
29
34
  box-sizing: border-box;
30
- min-width: styles-tokens-tree.$size-tree-item-checkbox-wrap;
31
- color: styles-tokens-tree.$sys-neutral-text-main;
35
+ min-width: tree.$size-tree-item-wrap;
36
+
37
+ color: tree.$sys-neutral-text-main;
32
38
  }
33
39
 
34
40
  .treeNodeActions {
@@ -41,14 +47,14 @@
41
47
  }
42
48
 
43
49
  .treeNodeContent {
44
- @include styles-tokens-tree.composite-var(styles-tokens-tree.$tree-item-content-layout);
50
+ @include tree.composite-var(tree.$tree-item-content-layout);
45
51
 
46
52
  cursor: pointer;
47
53
 
48
54
  position: relative;
49
55
 
50
56
  display: flex;
51
- align-items: center;
57
+ align-items: flex-start;
52
58
 
53
59
  box-sizing: border-box;
54
60
  width: 100%;
@@ -66,13 +72,13 @@
66
72
  height: 100%;
67
73
 
68
74
  opacity: 0;
69
- background-color: styles-tokens-tree.$sys-neutral-accent-default;
75
+ background-color: tree.$sys-neutral-accent-default;
70
76
  border-radius: inherit;
71
77
  }
72
78
 
73
79
  &:hover, &:focus-visible, &[data-droplist-active] {
74
80
  &::before {
75
- opacity: styles-tokens-tree.$opacity-a008;
81
+ opacity: tree.$opacity-a008;
76
82
  }
77
83
 
78
84
  .treeNodeActions {
@@ -81,9 +87,9 @@
81
87
  }
82
88
 
83
89
  &:focus-visible {
84
- @include styles-tokens-tree.outline-inside-var(styles-tokens-element.$container-focused-s);
90
+ @include tree.outline-inside-var(element.$container-focused-s);
85
91
 
86
- outline-color: styles-tokens-tree.$sys-available-complementary;
92
+ outline-color: tree.$sys-available-complementary;
87
93
  }
88
94
 
89
95
  &[data-multiselect] {
@@ -98,26 +104,26 @@
98
104
  }
99
105
 
100
106
  .treeNodeTitle, .treeNodeIcon {
101
- color: styles-tokens-tree.$sys-neutral-text-disabled;
107
+ color: tree.$sys-neutral-text-disabled;
102
108
  }
103
109
  }
104
110
 
105
111
  &[aria-selected='true']:not([data-multiselect]) {
106
112
  &::before {
107
- opacity: styles-tokens-tree.$opacity-a008;
108
- background-color: styles-tokens-tree.$sys-primary-accent-default;
113
+ opacity: tree.$opacity-a008;
114
+ background-color: tree.$sys-primary-accent-default;
109
115
  }
110
116
 
111
117
  &:hover {
112
118
  &::before {
113
- opacity: styles-tokens-tree.$opacity-a016;
119
+ opacity: tree.$opacity-a016;
114
120
  }
115
121
  }
116
122
  }
117
123
  }
118
124
 
119
125
  .treeNodeCheckboxWrap {
120
- @include styles-tokens-tree.composite-var(styles-tokens-tree.$tree-item-checkbox-wrap);
126
+ @include tree.composite-var(tree.$tree-item-toggle-wrap);
121
127
 
122
128
  display: flex;
123
129
  flex-shrink: 0;
@@ -128,6 +134,8 @@
128
134
  }
129
135
 
130
136
  .treeNodeExpandButton {
137
+ @include tree.composite-var(tree.$tree-item-expand-wrap);
138
+
131
139
  box-sizing: border-box;
132
140
 
133
141
  svg {
@@ -140,3 +148,12 @@
140
148
  }
141
149
  }
142
150
  }
151
+
152
+ .treeNodeExpandButtonWrapper {
153
+ overflow: hidden;
154
+ display: flex;
155
+ flex-direction: column;
156
+ align-self: stretch;
157
+
158
+ min-width: tree.$size-button-xs;
159
+ }