@snack-uikit/tree 0.4.0 → 0.5.1

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 CHANGED
@@ -3,6 +3,29 @@
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.5.1 (2024-01-23)
7
+
8
+ ### Only dependencies have been changed
9
+ * [@snack-uikit/droplist@0.12.5](https://github.com/cloud-ru-tech/snack-uikit/blob/master/packages/droplist/CHANGELOG.md)
10
+ * [@snack-uikit/icons@0.20.0](https://github.com/cloud-ru-tech/snack-uikit/blob/master/packages/icons/CHANGELOG.md)
11
+ * [@snack-uikit/toggles@0.9.4](https://github.com/cloud-ru-tech/snack-uikit/blob/master/packages/toggles/CHANGELOG.md)
12
+ * [@snack-uikit/truncate-string@0.4.5](https://github.com/cloud-ru-tech/snack-uikit/blob/master/packages/truncate-string/CHANGELOG.md)
13
+
14
+
15
+
16
+
17
+
18
+ # 0.5.0 (2024-01-18)
19
+
20
+
21
+ ### Features
22
+
23
+ * **FF-4126:** selectionMode is optional, and tree may be unselectable ([1540e26](https://github.com/cloud-ru-tech/snack-uikit/commit/1540e266b9351a92f1619c399a904fd6bd25518f))
24
+
25
+
26
+
27
+
28
+
6
29
  # 0.4.0 (2024-01-11)
7
30
 
8
31
 
package/README.md CHANGED
@@ -43,7 +43,6 @@ const [selectedNodes, setSelected] = useState<TreeNodeId[]>([]);
43
43
  | name | type | default value | description |
44
44
  |------|------|---------------|-------------|
45
45
  | data* | `TreeNodeProps[]` | - | Данные для отрисовки |
46
- | selectionMode | "single" \| "multi" | - | Режим выбора элементов: <br> - `Single` - одиночный выбор <br> - `Multi` - множественный выбор |
47
46
  | onNodeClick | `OnNodeClick` | - | Обработчик клика по элементу дерева |
48
47
  | expandedNodes | `string[]` | - | Состояние для раскрытых элементов |
49
48
  | onExpand | `(expandedKeys: string[], nodeId: string) => void` | - | Колбэк при раскрытии/закрытии элементов |
@@ -53,6 +52,7 @@ const [selectedNodes, setSelected] = useState<TreeNodeId[]>([]);
53
52
  | showIcons | `boolean` | true | Флаг отвечающий за отображение иконок у элементов дерева |
54
53
  | showLines | `boolean` | true | Флаг отвечающий за отображение линий вложенности |
55
54
  | className | `string` | - | CSS-класс |
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
58
 
@@ -1,4 +1,4 @@
1
1
  import { WithSupportProps } from '@snack-uikit/utils';
2
2
  import { TreeBaseProps } from '../../types';
3
3
  export type TreeProps = WithSupportProps<TreeBaseProps>;
4
- export declare function Tree({ data, selected, selectionMode, onSelect, onNodeClick, onExpand, expandedNodes, nodeActions, parentActions, onDataLoad, showLines, showIcons, className, ...rest }: TreeProps): import("react/jsx-runtime").JSX.Element;
4
+ export declare function Tree({ data, onNodeClick, onExpand, expandedNodes, nodeActions, parentActions, onDataLoad, showLines, showIcons, className, ...rest }: TreeProps): import("react/jsx-runtime").JSX.Element;
@@ -15,13 +15,10 @@ import { extractSupportProps } from '@snack-uikit/utils';
15
15
  import { TreeContextProvider } from '../../contexts/TreeContext';
16
16
  import { TreeItem } from '../../helperComponents';
17
17
  import styles from './styles.module.css';
18
+ import { extractSelectableProps } from './utils';
18
19
  export function Tree(_a) {
19
- var { data, selected, selectionMode, onSelect, onNodeClick, onExpand, expandedNodes, nodeActions, parentActions, onDataLoad, showLines = true, showIcons = true, className } = _a, rest = __rest(_a, ["data", "selected", "selectionMode", "onSelect", "onNodeClick", "onExpand", "expandedNodes", "nodeActions", "parentActions", "onDataLoad", "showLines", "showIcons", "className"]);
20
- return (_jsx("div", Object.assign({ className: cn(styles.tree, className), role: 'tree' }, extractSupportProps(rest), { children: _jsx(TreeContextProvider, { value: {
21
- data,
22
- selected: selected,
23
- selectionMode: selectionMode,
24
- onSelect: onSelect,
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({ data,
25
22
  expandedNodes,
26
23
  onNodeClick,
27
24
  onExpand,
@@ -29,6 +26,5 @@ export function Tree(_a) {
29
26
  parentActions,
30
27
  onDataLoad,
31
28
  showLines,
32
- showIcons,
33
- }, children: data.map((node, index) => (_jsx(TreeItem, { node: node, tabIndexAvailable: index === 0 || index === data.length - 1 }, node.id))) }) })));
29
+ showIcons }, extractSelectableProps(rest)), children: data.map((node, index) => (_jsx(TreeItem, { node: node, tabIndexAvailable: index === 0 || index === data.length - 1 }, node.id))) }) })));
34
30
  }
@@ -0,0 +1,2 @@
1
+ import { TreeBaseProps, TreeMultiSelect, TreeSingleSelect, TreeView } from '../../types';
2
+ export declare function extractSelectableProps({ selectionMode, selected, onSelect, }: Pick<TreeBaseProps, 'selectionMode' | 'selected' | 'onSelect'>): Pick<TreeSingleSelect, "selected" | "selectionMode" | "onSelect"> | Pick<TreeMultiSelect, "selected" | "selectionMode" | "onSelect"> | Pick<TreeView, "selected" | "selectionMode" | "onSelect">;
@@ -0,0 +1,20 @@
1
+ import { SELECTION_MODE } from '../../constants';
2
+ export function extractSelectableProps({ selectionMode, selected, onSelect, }) {
3
+ switch (selectionMode) {
4
+ case SELECTION_MODE.Single:
5
+ return {
6
+ selectionMode,
7
+ selected,
8
+ onSelect,
9
+ };
10
+ case SELECTION_MODE.Multi:
11
+ return {
12
+ selectionMode,
13
+ selected,
14
+ onSelect,
15
+ };
16
+ case undefined:
17
+ default:
18
+ return {};
19
+ }
20
+ }
@@ -7,6 +7,7 @@ type TreeContextProps = Omit<TreeBaseProps, 'onSelect' | 'onExpand' | 'onNodeCli
7
7
  onNodeClick: OnNodeClick;
8
8
  isMultiSelect: boolean;
9
9
  isSingleSelect: boolean;
10
+ isSelectable: boolean;
10
11
  focusedNodeId?: TreeNodeId;
11
12
  setFocusPosition(id: TreeNodeId): void;
12
13
  resetFocusPosition(): void;
@@ -29,11 +29,13 @@ export const TreeContext = createContext({
29
29
  focusableNodeIds: [],
30
30
  isMultiSelect: false,
31
31
  isSingleSelect: false,
32
+ isSelectable: false,
32
33
  });
33
34
  export function TreeContextProvider({ children, value }) {
34
35
  const { onNodeClick: onNodeClickProp, onExpand: onExpandProp, onSelect: onSelectProp, selectionMode, data } = value, props = __rest(value, ["onNodeClick", "onExpand", "onSelect", "selectionMode", "data"]);
35
36
  const isMultiSelect = selectionMode === SELECTION_MODE.Multi;
36
37
  const isSingleSelect = selectionMode === SELECTION_MODE.Single;
38
+ const isSelectable = Boolean(selectionMode);
37
39
  const [expandedNodes, onExpandHandler] = useUncontrolledProp(value.expandedNodes, value.expandedNodes || [], onExpandProp);
38
40
  const onExpand = useCallback(node => {
39
41
  const isExpanded = expandedNodes.includes(node.id);
@@ -42,7 +44,7 @@ export function TreeContextProvider({ children, value }) {
42
44
  }, [expandedNodes, onExpandHandler]);
43
45
  const [selectedNodes, onSelectHandler] = useUncontrolledProp(value.selected, [], onSelectProp);
44
46
  const onSelect = useCallback((node, parentNode) => {
45
- if (node.disabled)
47
+ if (!isSelectable || node.disabled)
46
48
  return;
47
49
  if (isSingleSelect) {
48
50
  onSelectHandler(node.id, node);
@@ -52,7 +54,7 @@ export function TreeContextProvider({ children, value }) {
52
54
  const updatedSelectedNodes = lookupTreeForSelectedNodes({ node, parentNode, selectedNodes });
53
55
  onSelectHandler(updatedSelectedNodes, node);
54
56
  }
55
- }, [isSingleSelect, onSelectHandler, selectedNodes]);
57
+ }, [isSingleSelect, onSelectHandler, selectedNodes, isSelectable]);
56
58
  const focusableNodeIds = useMemo(() => {
57
59
  if (!(expandedNodes === null || expandedNodes === void 0 ? void 0 : expandedNodes.length)) {
58
60
  return data.map(node => node.id);
@@ -86,6 +88,7 @@ export function TreeContextProvider({ children, value }) {
86
88
  }, [isSingleSelect, onSelect, onNodeClickProp]);
87
89
  return (_jsx(TreeContext.Provider, { value: Object.assign(Object.assign({}, props), { data, selected: selectedNodes, isSingleSelect,
88
90
  isMultiSelect,
91
+ isSelectable,
89
92
  expandedNodes,
90
93
  onExpand,
91
94
  onSelect,
@@ -27,7 +27,7 @@ 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, onNodeClick, selected, expandedNodes, onSelect, nodeActions, parentActions, setFocusPosition, resetFocusPosition, focusedNodeId, setFocusIndex, focusableNodeIds, showLines, showIcons, } = useTreeContext();
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);
@@ -139,7 +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": isSelected, "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: {
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: {
143
143
  id,
144
144
  title,
145
145
  disabled,
package/dist/types.d.ts CHANGED
@@ -43,6 +43,7 @@ export type TreeCommonProps = {
43
43
  * Режим выбора элементов:
44
44
  * <br> - `Single` - одиночный выбор
45
45
  * <br> - `Multi` - множественный выбор
46
+ * <br> - `undefined` - без выбора
46
47
  */
47
48
  selectionMode?: SelectionMode;
48
49
  /** Обработчик клика по элементу дерева */
@@ -68,6 +69,11 @@ export type TreeCommonProps = {
68
69
  showLines?: boolean;
69
70
  className?: string;
70
71
  };
72
+ export type TreeView = Omit<TreeCommonProps, 'selected' | 'selectionMode'> & {
73
+ selectionMode?: never;
74
+ selected?: never;
75
+ onSelect?: never;
76
+ };
71
77
  export type TreeSingleSelect = Omit<TreeCommonProps, 'selected'> & {
72
78
  selectionMode: 'single';
73
79
  /** Состояние для выбраного элемента */
@@ -89,4 +95,4 @@ export type TreeMultiSelect = Omit<TreeCommonProps, 'selected'> & {
89
95
  */
90
96
  onSelect?(selectedKeys: TreeNodeId[], node: TreeNodeProps): void;
91
97
  };
92
- export type TreeBaseProps = TreeMultiSelect | TreeSingleSelect;
98
+ export type TreeBaseProps = TreeView | TreeMultiSelect | TreeSingleSelect;
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "access": "public"
5
5
  },
6
6
  "title": "Tree",
7
- "version": "0.4.0",
7
+ "version": "0.5.1",
8
8
  "sideEffects": [
9
9
  "*.css",
10
10
  "*.woff",
@@ -33,15 +33,15 @@
33
33
  "scripts": {},
34
34
  "dependencies": {
35
35
  "@snack-uikit/button": "0.15.1",
36
- "@snack-uikit/droplist": "0.12.4",
37
- "@snack-uikit/icons": "0.19.2",
38
- "@snack-uikit/toggles": "0.9.3",
39
- "@snack-uikit/truncate-string": "0.4.4",
36
+ "@snack-uikit/droplist": "0.12.5",
37
+ "@snack-uikit/icons": "0.20.0",
38
+ "@snack-uikit/toggles": "0.9.4",
39
+ "@snack-uikit/truncate-string": "0.4.5",
40
40
  "@snack-uikit/typography": "0.6.1",
41
41
  "@snack-uikit/utils": "3.2.0",
42
42
  "classnames": "2.3.2",
43
43
  "react-transition-state": "2.1.1",
44
44
  "uncontrollable": "8.0.4"
45
45
  },
46
- "gitHead": "ebf50540bc191ed0f01ce6f1246f1a3e1263a835"
46
+ "gitHead": "c292f4c45173928f57cc5c9f3cb02efb26887b64"
47
47
  }
@@ -2,19 +2,16 @@ import cn from 'classnames';
2
2
 
3
3
  import { extractSupportProps, WithSupportProps } from '@snack-uikit/utils';
4
4
 
5
- import { SELECTION_MODE } from '../../constants';
6
5
  import { TreeContextProvider } from '../../contexts/TreeContext';
7
6
  import { TreeItem } from '../../helperComponents';
8
- import { SelectionMode, TreeBaseProps, TreeMultiSelect, TreeNodeId, TreeSingleSelect } from '../../types';
7
+ import { TreeBaseProps } from '../../types';
9
8
  import styles from './styles.module.scss';
9
+ import { extractSelectableProps } from './utils';
10
10
 
11
11
  export type TreeProps = WithSupportProps<TreeBaseProps>;
12
12
 
13
13
  export function Tree({
14
14
  data,
15
- selected,
16
- selectionMode,
17
- onSelect,
18
15
  onNodeClick,
19
16
  onExpand,
20
17
  expandedNodes,
@@ -31,13 +28,6 @@ export function Tree({
31
28
  <TreeContextProvider
32
29
  value={{
33
30
  data,
34
- selected: selected as SelectionMode extends typeof SELECTION_MODE.Single ? TreeNodeId : TreeNodeId[],
35
- selectionMode: selectionMode as typeof selected extends string
36
- ? typeof SELECTION_MODE.Single
37
- : typeof SELECTION_MODE.Multi,
38
- onSelect: onSelect as SelectionMode extends typeof SELECTION_MODE.Single
39
- ? TreeSingleSelect['onSelect']
40
- : TreeMultiSelect['onSelect'],
41
31
  expandedNodes,
42
32
  onNodeClick,
43
33
  onExpand,
@@ -46,6 +36,7 @@ export function Tree({
46
36
  onDataLoad,
47
37
  showLines,
48
38
  showIcons,
39
+ ...extractSelectableProps(rest),
49
40
  }}
50
41
  >
51
42
  {data.map((node, index) => (
@@ -0,0 +1,26 @@
1
+ import { SELECTION_MODE } from '../../constants';
2
+ import { TreeBaseProps, TreeMultiSelect, TreeSingleSelect, TreeView } from '../../types';
3
+
4
+ export function extractSelectableProps({
5
+ selectionMode,
6
+ selected,
7
+ onSelect,
8
+ }: Pick<TreeBaseProps, 'selectionMode' | 'selected' | 'onSelect'>) {
9
+ switch (selectionMode) {
10
+ case SELECTION_MODE.Single:
11
+ return {
12
+ selectionMode,
13
+ selected,
14
+ onSelect,
15
+ } as Pick<TreeSingleSelect, 'selectionMode' | 'selected' | 'onSelect'>;
16
+ case SELECTION_MODE.Multi:
17
+ return {
18
+ selectionMode,
19
+ selected,
20
+ onSelect,
21
+ } as Pick<TreeMultiSelect, 'selectionMode' | 'selected' | 'onSelect'>;
22
+ case undefined:
23
+ default:
24
+ return {} as Pick<TreeView, 'selectionMode' | 'selected' | 'onSelect'>;
25
+ }
26
+ }
@@ -12,6 +12,7 @@ type TreeContextProps = Omit<TreeBaseProps, 'onSelect' | 'onExpand' | 'onNodeCli
12
12
  onNodeClick: OnNodeClick;
13
13
  isMultiSelect: boolean;
14
14
  isSingleSelect: boolean;
15
+ isSelectable: boolean;
15
16
  focusedNodeId?: TreeNodeId;
16
17
  setFocusPosition(id: TreeNodeId): void;
17
18
  resetFocusPosition(): void;
@@ -39,6 +40,7 @@ export const TreeContext = createContext<TreeContextProps>({
39
40
  focusableNodeIds: [],
40
41
  isMultiSelect: false,
41
42
  isSingleSelect: false,
43
+ isSelectable: false,
42
44
  });
43
45
 
44
46
  export function TreeContextProvider({ children, value }: TreeContextProviderProps) {
@@ -53,6 +55,7 @@ export function TreeContextProvider({ children, value }: TreeContextProviderProp
53
55
 
54
56
  const isMultiSelect = selectionMode === SELECTION_MODE.Multi;
55
57
  const isSingleSelect = selectionMode === SELECTION_MODE.Single;
58
+ const isSelectable = Boolean(selectionMode);
56
59
 
57
60
  const [expandedNodes, onExpandHandler] = useUncontrolledProp<TreeNodeId[]>(
58
61
  value.expandedNodes,
@@ -75,7 +78,7 @@ export function TreeContextProvider({ children, value }: TreeContextProviderProp
75
78
 
76
79
  const onSelect = useCallback<TreeContextProps['onSelect']>(
77
80
  (node, parentNode) => {
78
- if (node.disabled) return;
81
+ if (!isSelectable || node.disabled) return;
79
82
 
80
83
  if (isSingleSelect) {
81
84
  onSelectHandler(node.id, node);
@@ -88,7 +91,7 @@ export function TreeContextProvider({ children, value }: TreeContextProviderProp
88
91
  onSelectHandler(updatedSelectedNodes, node);
89
92
  }
90
93
  },
91
- [isSingleSelect, onSelectHandler, selectedNodes],
94
+ [isSingleSelect, onSelectHandler, selectedNodes, isSelectable],
92
95
  );
93
96
 
94
97
  const focusableNodeIds = useMemo(() => {
@@ -146,6 +149,7 @@ export function TreeContextProvider({ children, value }: TreeContextProviderProp
146
149
  selected: selectedNodes,
147
150
  isSingleSelect,
148
151
  isMultiSelect,
152
+ isSelectable,
149
153
  expandedNodes,
150
154
  onExpand,
151
155
  onSelect,
@@ -46,6 +46,7 @@ export function TreeNode({
46
46
  }: TreeNodeComponentProps) {
47
47
  const {
48
48
  isMultiSelect,
49
+ isSelectable,
49
50
  onNodeClick,
50
51
  selected,
51
52
  expandedNodes,
@@ -233,7 +234,7 @@ export function TreeNode({
233
234
  <div
234
235
  role='treeitem'
235
236
  aria-expanded={isExpanded}
236
- aria-selected={isSelected}
237
+ aria-selected={isSelectable ? isSelected : undefined}
237
238
  aria-disabled={disabled}
238
239
  data-multiselect={isMultiSelect || undefined}
239
240
  data-droplist-active={isDroplistOpen || isDroplistTriggerFocused || undefined}
package/src/types.ts CHANGED
@@ -52,6 +52,7 @@ export type TreeCommonProps = {
52
52
  * Режим выбора элементов:
53
53
  * <br> - `Single` - одиночный выбор
54
54
  * <br> - `Multi` - множественный выбор
55
+ * <br> - `undefined` - без выбора
55
56
  */
56
57
  selectionMode?: SelectionMode;
57
58
  /** Обработчик клика по элементу дерева */
@@ -78,6 +79,12 @@ export type TreeCommonProps = {
78
79
  className?: string;
79
80
  };
80
81
 
82
+ export type TreeView = Omit<TreeCommonProps, 'selected' | 'selectionMode'> & {
83
+ selectionMode?: never;
84
+ selected?: never;
85
+ onSelect?: never;
86
+ };
87
+
81
88
  export type TreeSingleSelect = Omit<TreeCommonProps, 'selected'> & {
82
89
  selectionMode: 'single';
83
90
  /** Состояние для выбраного элемента */
@@ -101,4 +108,4 @@ export type TreeMultiSelect = Omit<TreeCommonProps, 'selected'> & {
101
108
  onSelect?(selectedKeys: TreeNodeId[], node: TreeNodeProps): void;
102
109
  };
103
110
 
104
- export type TreeBaseProps = TreeMultiSelect | TreeSingleSelect;
111
+ export type TreeBaseProps = TreeView | TreeMultiSelect | TreeSingleSelect;