@snack-uikit/tree 0.6.26-preview-1b7c1817.0 → 0.6.26
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 +9 -0
- package/README.md +0 -1
- package/dist/components/Tree/Tree.js +1 -1
- package/dist/contexts/TreeContext.d.ts +2 -5
- package/dist/contexts/TreeContext.js +1 -1
- package/dist/helperComponents/TreeNode/TreeNode.js +4 -5
- package/dist/types.d.ts +1 -2
- package/package.json +3 -3
- package/src/components/Tree/Tree.tsx +0 -1
- package/src/contexts/TreeContext.tsx +3 -10
- package/src/helperComponents/TreeNode/TreeNode.tsx +17 -23
- package/src/types.ts +1 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,15 @@
|
|
|
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.6.26 (2024-10-14)
|
|
7
|
+
|
|
8
|
+
### Only dependencies have been changed
|
|
9
|
+
* [@snack-uikit/list@0.17.1](https://github.com/cloud-ru-tech/snack-uikit/blob/master/packages/list/CHANGELOG.md)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
6
15
|
## 0.6.25 (2024-09-27)
|
|
7
16
|
|
|
8
17
|
### Only dependencies have been changed
|
package/README.md
CHANGED
|
@@ -55,7 +55,6 @@ const [selectedNodes, setSelected] = useState<TreeNodeId[]>([]);
|
|
|
55
55
|
| selectionMode | "single" \| "multi" | - | Режим выбора элементов: <br> - `Single` - одиночный выбор <br> - `Multi` - множественный выбор <br> - `undefined` - без выбора |
|
|
56
56
|
| selected | `string \| string[]` | - | Состояние для выбраных элементов: <br> - При <strong>selectionMode</strong>=`Multi` - принимает массив строк <br> - При <strong>selectionMode</strong>=`Single` - принимает строку |
|
|
57
57
|
| onSelect | `((selectedKeys: string[], node: TreeNodeProps) => void) \| ((selectedKey: string, node: TreeNodeProps) => void)` | - | Колбэк при изменении выбраных элементов: <br> - При <strong>selectionMode</strong>=`Multi` - возвращает массив строк <br> - При <strong>selectionMode</strong>=`Single` - возвращает строку |
|
|
58
|
-
| showToggleInSingleMode | `boolean` | - | |
|
|
59
58
|
|
|
60
59
|
|
|
61
60
|
[//]: DOCUMENTATION_SECTION_END
|
|
@@ -18,7 +18,7 @@ import styles from './styles.module.css';
|
|
|
18
18
|
import { extractSelectableProps } from './utils';
|
|
19
19
|
export function Tree(_a) {
|
|
20
20
|
var { data, onNodeClick, onExpand, expandedNodes, nodeActions, parentActions, onDataLoad, showLines = true, showIcons = true, className } = _a, rest = __rest(_a, ["data", "onNodeClick", "onExpand", "expandedNodes", "nodeActions", "parentActions", "onDataLoad", "showLines", "showIcons", "className"]);
|
|
21
|
-
return (_jsx("div", Object.assign({ className: cn(styles.tree, className), role: 'tree' }, extractSupportProps(rest), { children: _jsx(TreeContextProvider, { value: Object.assign({
|
|
21
|
+
return (_jsx("div", Object.assign({ className: cn(styles.tree, className), role: 'tree' }, extractSupportProps(rest), { children: _jsx(TreeContextProvider, { value: Object.assign({ data,
|
|
22
22
|
expandedNodes,
|
|
23
23
|
onNodeClick,
|
|
24
24
|
onExpand,
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { Dispatch, ReactNode, SetStateAction } from 'react';
|
|
2
2
|
import { OnNodeClick, ParentNode, TreeBaseProps, TreeNodeId, TreeNodeProps } from '../types';
|
|
3
|
-
type
|
|
4
|
-
showToggleInSingleMode?: boolean;
|
|
5
|
-
};
|
|
6
|
-
type TreeContextProps = Omit<TreeContextBaseProps, 'onSelect' | 'onExpand' | 'onNodeClick' | 'selected' | 'selectionMode'> & {
|
|
3
|
+
type TreeContextProps = Omit<TreeBaseProps, 'onSelect' | 'onExpand' | 'onNodeClick' | 'selected' | 'selectionMode'> & {
|
|
7
4
|
onExpand(node: TreeNodeProps): void;
|
|
8
5
|
onSelect(node: Pick<TreeNodeProps, 'id' | 'nested' | 'disabled'>, parentNode?: ParentNode): void;
|
|
9
6
|
selected?: TreeNodeId[] | TreeNodeId;
|
|
@@ -19,7 +16,7 @@ type TreeContextProps = Omit<TreeContextBaseProps, 'onSelect' | 'onExpand' | 'on
|
|
|
19
16
|
};
|
|
20
17
|
type TreeContextProviderProps = {
|
|
21
18
|
children: ReactNode;
|
|
22
|
-
value:
|
|
19
|
+
value: TreeBaseProps;
|
|
23
20
|
};
|
|
24
21
|
export declare const TreeContext: import("react").Context<TreeContextProps>;
|
|
25
22
|
export declare function TreeContextProvider({ children, value }: TreeContextProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -47,7 +47,7 @@ export function TreeContextProvider({ children, value }) {
|
|
|
47
47
|
if (!isSelectable || node.disabled)
|
|
48
48
|
return;
|
|
49
49
|
if (isSingleSelect) {
|
|
50
|
-
onSelectHandler(node.id
|
|
50
|
+
onSelectHandler(node.id, node);
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
53
|
if (Array.isArray(selectedNodes)) {
|
|
@@ -27,16 +27,16 @@ import styles from './styles.module.css';
|
|
|
27
27
|
import { stopPropagationClick } from './utils';
|
|
28
28
|
export function TreeNode(_a) {
|
|
29
29
|
var { id, title, icon = _jsx(FileSVG, { size: 24 }), expandedIcon = _jsx(FolderOpenSVG, { size: 24 }), collapsedIcon = _jsx(FolderSVG, { size: 24 }), disabled, onClick, nested, className, onChevronClick, onKeyDown, isLoading, parentNode, tabIndexAvailable } = _a, rest = __rest(_a, ["id", "title", "icon", "expandedIcon", "collapsedIcon", "disabled", "onClick", "nested", "className", "onChevronClick", "onKeyDown", "isLoading", "parentNode", "tabIndexAvailable"]);
|
|
30
|
-
const { isMultiSelect, isSelectable, onNodeClick, selected, expandedNodes, onSelect, nodeActions, parentActions, setFocusPosition, resetFocusPosition, focusedNodeId, setFocusIndex, focusableNodeIds,
|
|
30
|
+
const { isMultiSelect, isSelectable, onNodeClick, selected, expandedNodes, onSelect, nodeActions, parentActions, setFocusPosition, resetFocusPosition, focusedNodeId, setFocusIndex, focusableNodeIds, showLines, showIcons, } = useTreeContext();
|
|
31
31
|
const [isDroplistOpen, setDroplistOpen] = useState(false);
|
|
32
32
|
const [isDroplistTriggerFocused, setFocusDroplistTrigger] = useState(false);
|
|
33
33
|
const ref = useRef(null);
|
|
34
34
|
const isExpandable = Array.isArray(nested);
|
|
35
35
|
const isExpanded = isExpandable ? expandedNodes === null || expandedNodes === void 0 ? void 0 : expandedNodes.includes(id) : undefined;
|
|
36
36
|
const nestedNodesSelection = useMemo(() => {
|
|
37
|
-
if (!nested || !selected)
|
|
37
|
+
if (!nested || !Array.isArray(selected) || !(selected === null || selected === void 0 ? void 0 : selected.length))
|
|
38
38
|
return undefined;
|
|
39
|
-
return checkNestedNodesSelection(nested,
|
|
39
|
+
return checkNestedNodesSelection(nested, selected);
|
|
40
40
|
}, [nested, selected]);
|
|
41
41
|
const isSelected = (Array.isArray(selected) ? selected.includes(id) || (nestedNodesSelection === null || nestedNodesSelection === void 0 ? void 0 : nestedNodesSelection.allSelected) : selected === id) || false;
|
|
42
42
|
const isFocused = focusedNodeId === id;
|
|
@@ -139,8 +139,7 @@ export function TreeNode(_a) {
|
|
|
139
139
|
}
|
|
140
140
|
};
|
|
141
141
|
const getNodeActions = Boolean(nested) ? parentActions : nodeActions;
|
|
142
|
-
return (_jsxs("div", Object.assign({ role: 'presentation', className: cn(styles.treeNode, className) }, extractSupportProps(rest), { "data-node-id": id, children: [parentNode && (_jsx(TreeLine, { halfWidth: Boolean(nested), horizontal: true, visible: showLines, "data-test-id": TEST_IDS.line })), !parentNode && !Boolean(nested) && _jsx(TreeLine, { visible: false }), isExpandable && (_jsx(ButtonFunction, { size: 'xs', icon: _jsx(ChevronRightSVG, {}), disabled: disabled, loading: isLoading, onClick: onChevronClick, "data-expanded": isExpanded || undefined, className: styles.treeNodeExpandButton, tabIndex: -1, "data-test-id": TEST_IDS.chevron })), _jsxs("div", { role: 'treeitem', "aria-expanded": isExpanded, "aria-selected": isSelectable ? isSelected : undefined, "aria-disabled": disabled, "data-multiselect": isMultiSelect || undefined, "data-droplist-active": isDroplistOpen || isDroplistTriggerFocused || undefined, onClick: handleClick, onKeyDown: handleKeyDown, onFocus: handleFocus, onBlur: resetFocusPosition, tabIndex: tabIndexAvailable ? 0 : -1, className: styles.treeNodeContent, "data-test-id": TEST_IDS.item, ref: ref, children: [isMultiSelect ||
|
|
143
|
-
(showToggleInSingleMode && (_jsx("div", { className: styles.treeNodeCheckboxWrap, children: _jsx(Checkbox, { size: 's', disabled: disabled, checked: isSelected, indeterminate: !isSelected && (nestedNodesSelection === null || nestedNodesSelection === void 0 ? void 0 : nestedNodesSelection.someSelected), onChange: handleSelect, onClick: stopPropagationClick, "data-test-id": TEST_IDS.checkbox, tabIndex: -1 }) }))), treeNodeIcon && (_jsx("div", { className: styles.treeNodeIcon, "data-test-id": TEST_IDS.icon, children: treeNodeIcon })), _jsx(Typography.SansBodyM, { tag: 'div', className: styles.treeNodeTitle, children: typeof title === 'string' ? (_jsx(TruncateString, { text: title, "data-test-id": TEST_IDS.title })) : (title(Object.assign({ id, title, onClick, className, disabled }, extractSupportProps(rest)))) }), getNodeActions && (_jsx(TreeNodeActions, { getNodeActions: getNodeActions, node: {
|
|
142
|
+
return (_jsxs("div", Object.assign({ role: 'presentation', className: cn(styles.treeNode, className) }, extractSupportProps(rest), { "data-node-id": id, children: [parentNode && (_jsx(TreeLine, { halfWidth: Boolean(nested), horizontal: true, visible: showLines, "data-test-id": TEST_IDS.line })), !parentNode && !Boolean(nested) && _jsx(TreeLine, { visible: false }), isExpandable && (_jsx(ButtonFunction, { size: 'xs', icon: _jsx(ChevronRightSVG, {}), disabled: disabled, loading: isLoading, onClick: onChevronClick, "data-expanded": isExpanded || undefined, className: styles.treeNodeExpandButton, tabIndex: -1, "data-test-id": TEST_IDS.chevron })), _jsxs("div", { role: 'treeitem', "aria-expanded": isExpanded, "aria-selected": isSelectable ? isSelected : undefined, "aria-disabled": disabled, "data-multiselect": isMultiSelect || undefined, "data-droplist-active": isDroplistOpen || isDroplistTriggerFocused || undefined, onClick: handleClick, onKeyDown: handleKeyDown, onFocus: handleFocus, onBlur: resetFocusPosition, tabIndex: tabIndexAvailable ? 0 : -1, className: styles.treeNodeContent, "data-test-id": TEST_IDS.item, ref: ref, children: [isMultiSelect && (_jsx("div", { className: styles.treeNodeCheckboxWrap, children: _jsx(Checkbox, { size: 's', disabled: disabled, checked: !disabled && isSelected, indeterminate: !disabled && !isSelected && (nestedNodesSelection === null || nestedNodesSelection === void 0 ? void 0 : nestedNodesSelection.someSelected), onChange: handleSelect, onClick: stopPropagationClick, "data-test-id": TEST_IDS.checkbox, tabIndex: -1 }) })), treeNodeIcon && (_jsx("div", { className: styles.treeNodeIcon, "data-test-id": TEST_IDS.icon, children: treeNodeIcon })), _jsx(Typography.SansBodyM, { tag: 'div', className: styles.treeNodeTitle, children: _jsx(TruncateString, { text: title, "data-test-id": TEST_IDS.title }) }), getNodeActions && (_jsx(TreeNodeActions, { getNodeActions: getNodeActions, node: {
|
|
144
143
|
id,
|
|
145
144
|
title,
|
|
146
145
|
disabled,
|
package/dist/types.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export type BaseTreeNode = WithSupportProps<{
|
|
|
8
8
|
/** Идентификатор элемента */
|
|
9
9
|
id: TreeNodeId;
|
|
10
10
|
/** Имя элемента */
|
|
11
|
-
title: string
|
|
11
|
+
title: string;
|
|
12
12
|
/** Является ли элемент деактивированным */
|
|
13
13
|
disabled?: boolean;
|
|
14
14
|
/** Обработчик клика по элементу */
|
|
@@ -81,7 +81,6 @@ export type TreeSingleSelect = Omit<TreeCommonProps, 'selected'> & {
|
|
|
81
81
|
selected?: TreeNodeId;
|
|
82
82
|
/** <br> - При <strong>selectionMode</strong>=`Single` - возвращает строку */
|
|
83
83
|
onSelect?(selectedKey: TreeNodeId, node: TreeNodeProps): void;
|
|
84
|
-
showToggleInSingleMode?: boolean;
|
|
85
84
|
};
|
|
86
85
|
export type TreeMultiSelect = Omit<TreeCommonProps, 'selected'> & {
|
|
87
86
|
selectionMode: 'multi';
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
6
|
"title": "Tree",
|
|
7
|
-
"version": "0.6.26
|
|
7
|
+
"version": "0.6.26",
|
|
8
8
|
"sideEffects": [
|
|
9
9
|
"*.css",
|
|
10
10
|
"*.woff",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@snack-uikit/button": "0.17.5",
|
|
36
36
|
"@snack-uikit/icons": "0.22.1",
|
|
37
|
-
"@snack-uikit/list": "0.17.
|
|
37
|
+
"@snack-uikit/list": "0.17.1",
|
|
38
38
|
"@snack-uikit/toggles": "0.10.4",
|
|
39
39
|
"@snack-uikit/truncate-string": "0.4.24",
|
|
40
40
|
"@snack-uikit/typography": "0.6.3",
|
|
@@ -43,5 +43,5 @@
|
|
|
43
43
|
"react-transition-state": "2.1.1",
|
|
44
44
|
"uncontrollable": "8.0.4"
|
|
45
45
|
},
|
|
46
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "c2ae92f1626a256a9a0505c2cd74136cba9700bb"
|
|
47
47
|
}
|
|
@@ -27,7 +27,6 @@ export function Tree({
|
|
|
27
27
|
<div className={cn(styles.tree, className)} role='tree' {...extractSupportProps(rest)}>
|
|
28
28
|
<TreeContextProvider
|
|
29
29
|
value={{
|
|
30
|
-
showToggleInSingleMode: rest.selectionMode === 'single' && rest.showToggleInSingleMode,
|
|
31
30
|
data,
|
|
32
31
|
expandedNodes,
|
|
33
32
|
onNodeClick,
|
|
@@ -5,14 +5,7 @@ import { SELECTION_MODE } from '../constants';
|
|
|
5
5
|
import { findAllExpandedChildNodeIds, lookupTreeForSelectedNodes } from '../helpers';
|
|
6
6
|
import { OnNodeClick, ParentNode, TreeBaseProps, TreeNodeId, TreeNodeProps } from '../types';
|
|
7
7
|
|
|
8
|
-
type
|
|
9
|
-
showToggleInSingleMode?: boolean;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
type TreeContextProps = Omit<
|
|
13
|
-
TreeContextBaseProps,
|
|
14
|
-
'onSelect' | 'onExpand' | 'onNodeClick' | 'selected' | 'selectionMode'
|
|
15
|
-
> & {
|
|
8
|
+
type TreeContextProps = Omit<TreeBaseProps, 'onSelect' | 'onExpand' | 'onNodeClick' | 'selected' | 'selectionMode'> & {
|
|
16
9
|
onExpand(node: TreeNodeProps): void;
|
|
17
10
|
onSelect(node: Pick<TreeNodeProps, 'id' | 'nested' | 'disabled'>, parentNode?: ParentNode): void;
|
|
18
11
|
selected?: TreeNodeId[] | TreeNodeId;
|
|
@@ -29,7 +22,7 @@ type TreeContextProps = Omit<
|
|
|
29
22
|
|
|
30
23
|
type TreeContextProviderProps = {
|
|
31
24
|
children: ReactNode;
|
|
32
|
-
value:
|
|
25
|
+
value: TreeBaseProps;
|
|
33
26
|
};
|
|
34
27
|
|
|
35
28
|
export const TreeContext = createContext<TreeContextProps>({
|
|
@@ -88,7 +81,7 @@ export function TreeContextProvider({ children, value }: TreeContextProviderProp
|
|
|
88
81
|
if (!isSelectable || node.disabled) return;
|
|
89
82
|
|
|
90
83
|
if (isSingleSelect) {
|
|
91
|
-
onSelectHandler(node.id
|
|
84
|
+
onSelectHandler(node.id, node);
|
|
92
85
|
return;
|
|
93
86
|
}
|
|
94
87
|
|
|
@@ -58,7 +58,6 @@ export function TreeNode({
|
|
|
58
58
|
focusedNodeId,
|
|
59
59
|
setFocusIndex,
|
|
60
60
|
focusableNodeIds,
|
|
61
|
-
showToggleInSingleMode,
|
|
62
61
|
showLines,
|
|
63
62
|
showIcons,
|
|
64
63
|
} = useTreeContext();
|
|
@@ -72,9 +71,9 @@ export function TreeNode({
|
|
|
72
71
|
const isExpanded = isExpandable ? expandedNodes?.includes(id) : undefined;
|
|
73
72
|
|
|
74
73
|
const nestedNodesSelection = useMemo(() => {
|
|
75
|
-
if (!nested || !selected) return undefined;
|
|
74
|
+
if (!nested || !Array.isArray(selected) || !selected?.length) return undefined;
|
|
76
75
|
|
|
77
|
-
return checkNestedNodesSelection(nested,
|
|
76
|
+
return checkNestedNodesSelection(nested, selected);
|
|
78
77
|
}, [nested, selected]);
|
|
79
78
|
|
|
80
79
|
const isSelected =
|
|
@@ -248,21 +247,20 @@ export function TreeNode({
|
|
|
248
247
|
data-test-id={TEST_IDS.item}
|
|
249
248
|
ref={ref}
|
|
250
249
|
>
|
|
251
|
-
{isMultiSelect
|
|
252
|
-
|
|
253
|
-
<
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
))}
|
|
250
|
+
{isMultiSelect && (
|
|
251
|
+
<div className={styles.treeNodeCheckboxWrap}>
|
|
252
|
+
<Checkbox
|
|
253
|
+
size='s'
|
|
254
|
+
disabled={disabled}
|
|
255
|
+
checked={!disabled && isSelected}
|
|
256
|
+
indeterminate={!disabled && !isSelected && nestedNodesSelection?.someSelected}
|
|
257
|
+
onChange={handleSelect}
|
|
258
|
+
onClick={stopPropagationClick}
|
|
259
|
+
data-test-id={TEST_IDS.checkbox}
|
|
260
|
+
tabIndex={-1}
|
|
261
|
+
/>
|
|
262
|
+
</div>
|
|
263
|
+
)}
|
|
266
264
|
|
|
267
265
|
{treeNodeIcon && (
|
|
268
266
|
<div className={styles.treeNodeIcon} data-test-id={TEST_IDS.icon}>
|
|
@@ -271,11 +269,7 @@ export function TreeNode({
|
|
|
271
269
|
)}
|
|
272
270
|
|
|
273
271
|
<Typography.SansBodyM tag='div' className={styles.treeNodeTitle}>
|
|
274
|
-
{
|
|
275
|
-
<TruncateString text={title} data-test-id={TEST_IDS.title} />
|
|
276
|
-
) : (
|
|
277
|
-
title({ id, title, onClick, className, disabled, ...extractSupportProps(rest) })
|
|
278
|
-
)}
|
|
272
|
+
<TruncateString text={title} data-test-id={TEST_IDS.title} />
|
|
279
273
|
</Typography.SansBodyM>
|
|
280
274
|
|
|
281
275
|
{getNodeActions && (
|
package/src/types.ts
CHANGED
|
@@ -13,7 +13,7 @@ export type BaseTreeNode = WithSupportProps<{
|
|
|
13
13
|
/** Идентификатор элемента */
|
|
14
14
|
id: TreeNodeId;
|
|
15
15
|
/** Имя элемента */
|
|
16
|
-
title: string
|
|
16
|
+
title: string;
|
|
17
17
|
/** Является ли элемент деактивированным */
|
|
18
18
|
disabled?: boolean;
|
|
19
19
|
/** Обработчик клика по элементу */
|
|
@@ -92,7 +92,6 @@ export type TreeSingleSelect = Omit<TreeCommonProps, 'selected'> & {
|
|
|
92
92
|
selected?: TreeNodeId;
|
|
93
93
|
/** <br> - При <strong>selectionMode</strong>=`Single` - возвращает строку */
|
|
94
94
|
onSelect?(selectedKey: TreeNodeId, node: TreeNodeProps): void;
|
|
95
|
-
showToggleInSingleMode?: boolean;
|
|
96
95
|
};
|
|
97
96
|
|
|
98
97
|
export type TreeMultiSelect = Omit<TreeCommonProps, 'selected'> & {
|