@cloud-ru/ds-tree 1.0.0

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 (231) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/LICENSE +201 -0
  3. package/README.md +341 -0
  4. package/dist/cjs/components/Tree/Tree.d.ts +4 -0
  5. package/dist/cjs/components/Tree/Tree.js +31 -0
  6. package/dist/cjs/components/Tree/index.d.ts +1 -0
  7. package/dist/cjs/components/Tree/index.js +17 -0
  8. package/dist/cjs/components/Tree/styles.module.css +17 -0
  9. package/dist/cjs/components/Tree/utils.d.ts +4 -0
  10. package/dist/cjs/components/Tree/utils.js +15 -0
  11. package/dist/cjs/components/index.d.ts +1 -0
  12. package/dist/cjs/components/index.js +17 -0
  13. package/dist/cjs/constants.d.ts +26 -0
  14. package/dist/cjs/constants.js +29 -0
  15. package/dist/cjs/contexts/TreeContext.d.ts +30 -0
  16. package/dist/cjs/contexts/TreeContext.js +108 -0
  17. package/dist/cjs/helperComponents/ExpandableTreeNode/ExpandableTreeNode.d.ts +11 -0
  18. package/dist/cjs/helperComponents/ExpandableTreeNode/ExpandableTreeNode.js +87 -0
  19. package/dist/cjs/helperComponents/ExpandableTreeNode/index.d.ts +1 -0
  20. package/dist/cjs/helperComponents/ExpandableTreeNode/index.js +17 -0
  21. package/dist/cjs/helperComponents/ExpandableTreeNode/styles.module.css +37 -0
  22. package/dist/cjs/helperComponents/TreeItem/TreeItem.d.ts +8 -0
  23. package/dist/cjs/helperComponents/TreeItem/TreeItem.js +16 -0
  24. package/dist/cjs/helperComponents/TreeItem/index.d.ts +1 -0
  25. package/dist/cjs/helperComponents/TreeItem/index.js +17 -0
  26. package/dist/cjs/helperComponents/TreeLine/TreeLine.d.ts +10 -0
  27. package/dist/cjs/helperComponents/TreeLine/TreeLine.js +13 -0
  28. package/dist/cjs/helperComponents/TreeLine/index.d.ts +1 -0
  29. package/dist/cjs/helperComponents/TreeLine/index.js +17 -0
  30. package/dist/cjs/helperComponents/TreeLine/styles.module.css +37 -0
  31. package/dist/cjs/helperComponents/TreeNode/TreeNode.d.ts +4 -0
  32. package/dist/cjs/helperComponents/TreeNode/TreeNode.js +187 -0
  33. package/dist/cjs/helperComponents/TreeNode/components/TreeNodeActions.d.ts +15 -0
  34. package/dist/cjs/helperComponents/TreeNode/components/TreeNodeActions.js +76 -0
  35. package/dist/cjs/helperComponents/TreeNode/components/TreeNodeHref.d.ts +7 -0
  36. package/dist/cjs/helperComponents/TreeNode/components/TreeNodeHref.js +12 -0
  37. package/dist/cjs/helperComponents/TreeNode/components/index.d.ts +2 -0
  38. package/dist/cjs/helperComponents/TreeNode/components/index.js +18 -0
  39. package/dist/cjs/helperComponents/TreeNode/constants.d.ts +5 -0
  40. package/dist/cjs/helperComponents/TreeNode/constants.js +10 -0
  41. package/dist/cjs/helperComponents/TreeNode/index.d.ts +1 -0
  42. package/dist/cjs/helperComponents/TreeNode/index.js +17 -0
  43. package/dist/cjs/helperComponents/TreeNode/styles.module.css +474 -0
  44. package/dist/cjs/helperComponents/TreeNode/types.d.ts +9 -0
  45. package/dist/cjs/helperComponents/TreeNode/types.js +2 -0
  46. package/dist/cjs/helperComponents/TreeNode/utils.d.ts +3 -0
  47. package/dist/cjs/helperComponents/TreeNode/utils.js +10 -0
  48. package/dist/cjs/helperComponents/index.d.ts +4 -0
  49. package/dist/cjs/helperComponents/index.js +20 -0
  50. package/dist/cjs/helpers/checkNestedNodesSelection.d.ts +9 -0
  51. package/dist/cjs/helpers/checkNestedNodesSelection.js +15 -0
  52. package/dist/cjs/helpers/collectEmptyNestedNodesInExpanded.d.ts +9 -0
  53. package/dist/cjs/helpers/collectEmptyNestedNodesInExpanded.js +21 -0
  54. package/dist/cjs/helpers/collectHierarchicalAncestors.d.ts +3 -0
  55. package/dist/cjs/helpers/collectHierarchicalAncestors.js +18 -0
  56. package/dist/cjs/helpers/collectIds.d.ts +9 -0
  57. package/dist/cjs/helpers/collectIds.js +16 -0
  58. package/dist/cjs/helpers/extractTreeNodeTitle.d.ts +6 -0
  59. package/dist/cjs/helpers/extractTreeNodeTitle.js +9 -0
  60. package/dist/cjs/helpers/findAllChildNodeIds.d.ts +9 -0
  61. package/dist/cjs/helpers/findAllChildNodeIds.js +24 -0
  62. package/dist/cjs/helpers/findAllExpandedChildNodeIds.d.ts +8 -0
  63. package/dist/cjs/helpers/findAllExpandedChildNodeIds.js +21 -0
  64. package/dist/cjs/helpers/getSearchedTreeItems.d.ts +23 -0
  65. package/dist/cjs/helpers/getSearchedTreeItems.js +41 -0
  66. package/dist/cjs/helpers/getSearchedTreeNodeById.d.ts +19 -0
  67. package/dist/cjs/helpers/getSearchedTreeNodeById.js +35 -0
  68. package/dist/cjs/helpers/index.d.ts +13 -0
  69. package/dist/cjs/helpers/index.js +29 -0
  70. package/dist/cjs/helpers/lookupTreeForSelectedNodes.d.ts +15 -0
  71. package/dist/cjs/helpers/lookupTreeForSelectedNodes.js +21 -0
  72. package/dist/cjs/helpers/sortTreeItemsByTitle.d.ts +13 -0
  73. package/dist/cjs/helpers/sortTreeItemsByTitle.js +14 -0
  74. package/dist/cjs/helpers/traverse.d.ts +11 -0
  75. package/dist/cjs/helpers/traverse.js +25 -0
  76. package/dist/cjs/helpers/traverseWithTarget.d.ts +14 -0
  77. package/dist/cjs/helpers/traverseWithTarget.js +30 -0
  78. package/dist/cjs/helpers/updateTreeNode.d.ts +13 -0
  79. package/dist/cjs/helpers/updateTreeNode.js +34 -0
  80. package/dist/cjs/hooks/index.d.ts +2 -0
  81. package/dist/cjs/hooks/index.js +18 -0
  82. package/dist/cjs/hooks/internalHooks.d.ts +4 -0
  83. package/dist/cjs/hooks/internalHooks.js +29 -0
  84. package/dist/cjs/hooks/useSearchableTree.d.ts +52 -0
  85. package/dist/cjs/hooks/useSearchableTree.js +113 -0
  86. package/dist/cjs/hooks/useTreeMultiSelection.d.ts +33 -0
  87. package/dist/cjs/hooks/useTreeMultiSelection.js +37 -0
  88. package/dist/cjs/index.d.ts +17 -0
  89. package/dist/cjs/index.js +47 -0
  90. package/dist/cjs/package.json +3 -0
  91. package/dist/cjs/style.css +565 -0
  92. package/dist/cjs/types.d.ts +151 -0
  93. package/dist/cjs/types.js +2 -0
  94. package/dist/esm/components/Tree/Tree.d.ts +4 -0
  95. package/dist/esm/components/Tree/Tree.js +25 -0
  96. package/dist/esm/components/Tree/index.d.ts +1 -0
  97. package/dist/esm/components/Tree/index.js +1 -0
  98. package/dist/esm/components/Tree/styles.module.css +17 -0
  99. package/dist/esm/components/Tree/utils.d.ts +4 -0
  100. package/dist/esm/components/Tree/utils.js +12 -0
  101. package/dist/esm/components/index.d.ts +1 -0
  102. package/dist/esm/components/index.js +1 -0
  103. package/dist/esm/constants.d.ts +26 -0
  104. package/dist/esm/constants.js +26 -0
  105. package/dist/esm/contexts/TreeContext.d.ts +30 -0
  106. package/dist/esm/contexts/TreeContext.js +103 -0
  107. package/dist/esm/helperComponents/ExpandableTreeNode/ExpandableTreeNode.d.ts +11 -0
  108. package/dist/esm/helperComponents/ExpandableTreeNode/ExpandableTreeNode.js +81 -0
  109. package/dist/esm/helperComponents/ExpandableTreeNode/index.d.ts +1 -0
  110. package/dist/esm/helperComponents/ExpandableTreeNode/index.js +1 -0
  111. package/dist/esm/helperComponents/ExpandableTreeNode/styles.module.css +37 -0
  112. package/dist/esm/helperComponents/TreeItem/TreeItem.d.ts +8 -0
  113. package/dist/esm/helperComponents/TreeItem/TreeItem.js +13 -0
  114. package/dist/esm/helperComponents/TreeItem/index.d.ts +1 -0
  115. package/dist/esm/helperComponents/TreeItem/index.js +1 -0
  116. package/dist/esm/helperComponents/TreeLine/TreeLine.d.ts +10 -0
  117. package/dist/esm/helperComponents/TreeLine/TreeLine.js +7 -0
  118. package/dist/esm/helperComponents/TreeLine/index.d.ts +1 -0
  119. package/dist/esm/helperComponents/TreeLine/index.js +1 -0
  120. package/dist/esm/helperComponents/TreeLine/styles.module.css +37 -0
  121. package/dist/esm/helperComponents/TreeNode/TreeNode.d.ts +4 -0
  122. package/dist/esm/helperComponents/TreeNode/TreeNode.js +181 -0
  123. package/dist/esm/helperComponents/TreeNode/components/TreeNodeActions.d.ts +15 -0
  124. package/dist/esm/helperComponents/TreeNode/components/TreeNodeActions.js +70 -0
  125. package/dist/esm/helperComponents/TreeNode/components/TreeNodeHref.d.ts +7 -0
  126. package/dist/esm/helperComponents/TreeNode/components/TreeNodeHref.js +6 -0
  127. package/dist/esm/helperComponents/TreeNode/components/index.d.ts +2 -0
  128. package/dist/esm/helperComponents/TreeNode/components/index.js +2 -0
  129. package/dist/esm/helperComponents/TreeNode/constants.d.ts +5 -0
  130. package/dist/esm/helperComponents/TreeNode/constants.js +7 -0
  131. package/dist/esm/helperComponents/TreeNode/index.d.ts +1 -0
  132. package/dist/esm/helperComponents/TreeNode/index.js +1 -0
  133. package/dist/esm/helperComponents/TreeNode/styles.module.css +474 -0
  134. package/dist/esm/helperComponents/TreeNode/types.d.ts +9 -0
  135. package/dist/esm/helperComponents/TreeNode/types.js +1 -0
  136. package/dist/esm/helperComponents/TreeNode/utils.d.ts +3 -0
  137. package/dist/esm/helperComponents/TreeNode/utils.js +6 -0
  138. package/dist/esm/helperComponents/index.d.ts +4 -0
  139. package/dist/esm/helperComponents/index.js +4 -0
  140. package/dist/esm/helpers/checkNestedNodesSelection.d.ts +9 -0
  141. package/dist/esm/helpers/checkNestedNodesSelection.js +12 -0
  142. package/dist/esm/helpers/collectEmptyNestedNodesInExpanded.d.ts +9 -0
  143. package/dist/esm/helpers/collectEmptyNestedNodesInExpanded.js +18 -0
  144. package/dist/esm/helpers/collectHierarchicalAncestors.d.ts +3 -0
  145. package/dist/esm/helpers/collectHierarchicalAncestors.js +15 -0
  146. package/dist/esm/helpers/collectIds.d.ts +9 -0
  147. package/dist/esm/helpers/collectIds.js +13 -0
  148. package/dist/esm/helpers/extractTreeNodeTitle.d.ts +6 -0
  149. package/dist/esm/helpers/extractTreeNodeTitle.js +5 -0
  150. package/dist/esm/helpers/findAllChildNodeIds.d.ts +9 -0
  151. package/dist/esm/helpers/findAllChildNodeIds.js +21 -0
  152. package/dist/esm/helpers/findAllExpandedChildNodeIds.d.ts +8 -0
  153. package/dist/esm/helpers/findAllExpandedChildNodeIds.js +18 -0
  154. package/dist/esm/helpers/getSearchedTreeItems.d.ts +23 -0
  155. package/dist/esm/helpers/getSearchedTreeItems.js +37 -0
  156. package/dist/esm/helpers/getSearchedTreeNodeById.d.ts +19 -0
  157. package/dist/esm/helpers/getSearchedTreeNodeById.js +31 -0
  158. package/dist/esm/helpers/index.d.ts +13 -0
  159. package/dist/esm/helpers/index.js +13 -0
  160. package/dist/esm/helpers/lookupTreeForSelectedNodes.d.ts +15 -0
  161. package/dist/esm/helpers/lookupTreeForSelectedNodes.js +18 -0
  162. package/dist/esm/helpers/sortTreeItemsByTitle.d.ts +13 -0
  163. package/dist/esm/helpers/sortTreeItemsByTitle.js +10 -0
  164. package/dist/esm/helpers/traverse.d.ts +11 -0
  165. package/dist/esm/helpers/traverse.js +21 -0
  166. package/dist/esm/helpers/traverseWithTarget.d.ts +14 -0
  167. package/dist/esm/helpers/traverseWithTarget.js +26 -0
  168. package/dist/esm/helpers/updateTreeNode.d.ts +13 -0
  169. package/dist/esm/helpers/updateTreeNode.js +30 -0
  170. package/dist/esm/hooks/index.d.ts +2 -0
  171. package/dist/esm/hooks/index.js +2 -0
  172. package/dist/esm/hooks/internalHooks.d.ts +4 -0
  173. package/dist/esm/hooks/internalHooks.js +24 -0
  174. package/dist/esm/hooks/useSearchableTree.d.ts +52 -0
  175. package/dist/esm/hooks/useSearchableTree.js +110 -0
  176. package/dist/esm/hooks/useTreeMultiSelection.d.ts +33 -0
  177. package/dist/esm/hooks/useTreeMultiSelection.js +34 -0
  178. package/dist/esm/index.d.ts +17 -0
  179. package/dist/esm/index.js +17 -0
  180. package/dist/esm/style.css +565 -0
  181. package/dist/esm/types.d.ts +151 -0
  182. package/dist/esm/types.js +1 -0
  183. package/dist/tsconfig.cjs.tsbuildinfo +1 -0
  184. package/dist/tsconfig.esm.tsbuildinfo +1 -0
  185. package/package.json +51 -0
  186. package/src/components/Tree/Tree.tsx +53 -0
  187. package/src/components/Tree/index.ts +1 -0
  188. package/src/components/Tree/styles.module.scss +22 -0
  189. package/src/components/Tree/utils.ts +16 -0
  190. package/src/components/index.ts +1 -0
  191. package/src/constants.ts +29 -0
  192. package/src/contexts/TreeContext.tsx +189 -0
  193. package/src/helperComponents/ExpandableTreeNode/ExpandableTreeNode.tsx +156 -0
  194. package/src/helperComponents/ExpandableTreeNode/index.ts +1 -0
  195. package/src/helperComponents/ExpandableTreeNode/styles.module.scss +55 -0
  196. package/src/helperComponents/TreeItem/TreeItem.tsx +26 -0
  197. package/src/helperComponents/TreeItem/index.ts +1 -0
  198. package/src/helperComponents/TreeLine/TreeLine.tsx +27 -0
  199. package/src/helperComponents/TreeLine/index.ts +1 -0
  200. package/src/helperComponents/TreeLine/styles.module.scss +58 -0
  201. package/src/helperComponents/TreeNode/TreeNode.tsx +389 -0
  202. package/src/helperComponents/TreeNode/components/TreeNodeActions.tsx +129 -0
  203. package/src/helperComponents/TreeNode/components/TreeNodeHref.tsx +29 -0
  204. package/src/helperComponents/TreeNode/components/index.ts +2 -0
  205. package/src/helperComponents/TreeNode/constants.ts +7 -0
  206. package/src/helperComponents/TreeNode/index.ts +1 -0
  207. package/src/helperComponents/TreeNode/styles.module.scss +300 -0
  208. package/src/helperComponents/TreeNode/types.ts +11 -0
  209. package/src/helperComponents/TreeNode/utils.ts +9 -0
  210. package/src/helperComponents/index.ts +4 -0
  211. package/src/helpers/checkNestedNodesSelection.ts +15 -0
  212. package/src/helpers/collectEmptyNestedNodesInExpanded.ts +23 -0
  213. package/src/helpers/collectHierarchicalAncestors.ts +22 -0
  214. package/src/helpers/collectIds.ts +17 -0
  215. package/src/helpers/extractTreeNodeTitle.ts +8 -0
  216. package/src/helpers/findAllChildNodeIds.ts +27 -0
  217. package/src/helpers/findAllExpandedChildNodeIds.ts +24 -0
  218. package/src/helpers/getSearchedTreeItems.ts +63 -0
  219. package/src/helpers/getSearchedTreeNodeById.ts +54 -0
  220. package/src/helpers/index.ts +13 -0
  221. package/src/helpers/lookupTreeForSelectedNodes.ts +33 -0
  222. package/src/helpers/sortTreeItemsByTitle.ts +26 -0
  223. package/src/helpers/traverse.ts +28 -0
  224. package/src/helpers/traverseWithTarget.ts +41 -0
  225. package/src/helpers/updateTreeNode.ts +46 -0
  226. package/src/hooks/index.ts +2 -0
  227. package/src/hooks/internalHooks.ts +30 -0
  228. package/src/hooks/useSearchableTree.ts +190 -0
  229. package/src/hooks/useTreeMultiSelection.ts +67 -0
  230. package/src/index.ts +17 -0
  231. package/src/types.ts +162 -0
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./Tree"), exports);
@@ -0,0 +1,26 @@
1
+ export declare const SELECTION_MODE: {
2
+ readonly Single: "single";
3
+ readonly Multiple: "multiple";
4
+ };
5
+ export declare const SIZE: {
6
+ readonly S: "s";
7
+ readonly M: "m";
8
+ readonly L: "l";
9
+ };
10
+ export declare const TRANSITION_TIMING: {
11
+ readonly accordionFolding: 200;
12
+ };
13
+ export declare const TEST_IDS: {
14
+ readonly node: "tree__node";
15
+ readonly line: "tree__node__line";
16
+ readonly item: "tree__node__item";
17
+ readonly chevron: "tree__node__chevron";
18
+ readonly checkbox: "tree__node__checkbox";
19
+ readonly radio: "tree__node__radio";
20
+ readonly icon: "tree__node__icon";
21
+ readonly title: "tree__node__title";
22
+ readonly droplistTrigger: "tree__node__droplist-trigger";
23
+ readonly expandable: "tree__node__expandable";
24
+ readonly expandableContent: "tree__node__expandable-content";
25
+ readonly link: "tree__node__link";
26
+ };
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TEST_IDS = exports.TRANSITION_TIMING = exports.SIZE = exports.SELECTION_MODE = void 0;
4
+ exports.SELECTION_MODE = {
5
+ Single: 'single',
6
+ Multiple: 'multiple',
7
+ };
8
+ exports.SIZE = {
9
+ S: 's',
10
+ M: 'm',
11
+ L: 'l',
12
+ };
13
+ exports.TRANSITION_TIMING = {
14
+ accordionFolding: 200,
15
+ };
16
+ exports.TEST_IDS = {
17
+ node: 'tree__node',
18
+ line: 'tree__node__line',
19
+ item: 'tree__node__item',
20
+ chevron: 'tree__node__chevron',
21
+ checkbox: 'tree__node__checkbox',
22
+ radio: 'tree__node__radio',
23
+ icon: 'tree__node__icon',
24
+ title: 'tree__node__title',
25
+ droplistTrigger: 'tree__node__droplist-trigger',
26
+ expandable: 'tree__node__expandable',
27
+ expandableContent: 'tree__node__expandable-content',
28
+ link: 'tree__node__link',
29
+ };
@@ -0,0 +1,30 @@
1
+ import { HierarchicalSelectionHandlers } from '@cloud-ru/ds-utils';
2
+ import { Dispatch, ReactNode, SetStateAction } from 'react';
3
+ import { OnNodeClick, ParentNode, TreeBaseProps, TreeNodeId, TreeNodeProps } from '../types';
4
+ type TreeContextBaseProps = TreeBaseProps & {
5
+ showToggle?: boolean;
6
+ };
7
+ type TreeContextProps = Omit<TreeContextBaseProps, 'onSelect' | 'onExpand' | 'onNodeClick' | 'selected' | 'selectionMode'> & {
8
+ onExpand(node: TreeNodeProps): void;
9
+ onSelect(node: Pick<TreeNodeProps, 'id' | 'nested' | 'disabled'>, parentNode?: ParentNode): void;
10
+ selected?: TreeNodeId[] | TreeNodeId;
11
+ onNodeClick: OnNodeClick;
12
+ isMultiSelect: boolean;
13
+ isSingleSelect: boolean;
14
+ isSelectable: boolean;
15
+ focusedNodeId?: TreeNodeId;
16
+ setFocusPosition(id: TreeNodeId): void;
17
+ resetFocusPosition(): void;
18
+ setFocusIndex: Dispatch<SetStateAction<number | undefined>>;
19
+ focusableNodeIds: TreeNodeId[];
20
+ getSelectionState: HierarchicalSelectionHandlers['getSelectionState'];
21
+ toggleSelection: HierarchicalSelectionHandlers['toggleSelection'];
22
+ };
23
+ type TreeContextProviderProps = {
24
+ children: ReactNode;
25
+ value: TreeContextBaseProps;
26
+ };
27
+ export declare const TreeContext: import("react").Context<TreeContextProps>;
28
+ export declare function TreeContextProvider({ children, value }: TreeContextProviderProps): import("react/jsx-runtime").JSX.Element;
29
+ export declare const useTreeContext: () => TreeContextProps;
30
+ export {};
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useTreeContext = exports.TreeContext = void 0;
4
+ exports.TreeContextProvider = TreeContextProvider;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const utils_1 = require("@cloud-ru/ds-utils");
7
+ const react_1 = require("react");
8
+ const constants_1 = require("../constants");
9
+ const helpers_1 = require("../helpers");
10
+ const EMPTY_EXPANDED = [];
11
+ exports.TreeContext = (0, react_1.createContext)({
12
+ data: [],
13
+ selected: undefined,
14
+ onSelect() { },
15
+ expandedNodes: [],
16
+ onExpand() { },
17
+ onNodeClick() { },
18
+ setFocusPosition() { },
19
+ setFocusIndex() { },
20
+ resetFocusPosition() { },
21
+ focusableNodeIds: [],
22
+ isMultiSelect: false,
23
+ isSingleSelect: false,
24
+ isSelectable: false,
25
+ getSelectionState: () => ({ checked: false, indeterminate: false }),
26
+ toggleSelection: ({ selectedIds }) => selectedIds,
27
+ });
28
+ function TreeContextProvider({ children, value }) {
29
+ const { onNodeClick: onNodeClickProp, onExpand: onExpandProp, onSelect: onSelectProp, selectionMode, data, ...props } = value;
30
+ const isMultiSelect = selectionMode === constants_1.SELECTION_MODE.Multiple;
31
+ const isSingleSelect = selectionMode === constants_1.SELECTION_MODE.Single;
32
+ const isSelectable = Boolean(selectionMode);
33
+ const { getSelectionState, toggleSelection } = (0, utils_1.useHierarchicalSelection)({ includeParentsInValue: true });
34
+ const [expandedNodes, onExpandHandler] = (0, utils_1.useUncontrolledProp)(value.expandedNodes, value.expandedNodes ?? EMPTY_EXPANDED, onExpandProp);
35
+ const onExpand = (0, react_1.useCallback)(node => {
36
+ const isExpanded = expandedNodes.includes(node.id);
37
+ const nodes = isExpanded ? expandedNodes.filter(id => id !== node.id) : expandedNodes.concat(node.id);
38
+ onExpandHandler(nodes, node);
39
+ }, [expandedNodes, onExpandHandler]);
40
+ const [selectedNodes, onSelectHandler] = (0, utils_1.useUncontrolledProp)(value.selected, [], onSelectProp);
41
+ const onSelect = (0, react_1.useCallback)((node, parentNode) => {
42
+ if (!isSelectable || node.disabled)
43
+ return;
44
+ if (isSingleSelect) {
45
+ onSelectHandler(node.id === selectedNodes ? undefined : node.id, node);
46
+ return;
47
+ }
48
+ if (Array.isArray(selectedNodes)) {
49
+ const updatedSelectedNodes = (0, helpers_1.lookupTreeForSelectedNodes)({
50
+ node,
51
+ parentNode,
52
+ selectedNodes,
53
+ toggleSelection,
54
+ });
55
+ onSelectHandler(updatedSelectedNodes, node);
56
+ }
57
+ }, [isSingleSelect, onSelectHandler, selectedNodes, isSelectable, toggleSelection]);
58
+ const focusableNodeIds = (0, react_1.useMemo)(() => {
59
+ if (!expandedNodes?.length) {
60
+ return data.map(node => node.id);
61
+ }
62
+ return data.reduce((acc, cur) => {
63
+ acc.push(cur.id);
64
+ const isExpanded = expandedNodes.includes(cur.id);
65
+ if (isExpanded && cur.nested?.length) {
66
+ acc.push(...(0, helpers_1.findAllExpandedChildNodeIds)(cur.nested, expandedNodes));
67
+ }
68
+ return acc;
69
+ }, []);
70
+ }, [data, expandedNodes]);
71
+ const [focusIndex, setFocusIndex] = (0, react_1.useState)();
72
+ const focusedNodeId = focusIndex !== undefined ? focusableNodeIds[focusIndex] : undefined;
73
+ const setFocusPosition = (0, react_1.useCallback)((nodeId) => {
74
+ const newFocusIndex = focusableNodeIds.indexOf(nodeId);
75
+ setFocusIndex(newFocusIndex >= 0 ? newFocusIndex : undefined);
76
+ }, [focusableNodeIds]);
77
+ const resetFocusPosition = (0, react_1.useCallback)(() => setFocusIndex(undefined), []);
78
+ const onNodeClick = (0, react_1.useCallback)((node, e) => {
79
+ if (node.disabled) {
80
+ return;
81
+ }
82
+ if (isSingleSelect) {
83
+ onSelect(node);
84
+ }
85
+ node.onClick?.(e) || onNodeClickProp?.(node, e);
86
+ }, [isSingleSelect, onSelect, onNodeClickProp]);
87
+ return ((0, jsx_runtime_1.jsx)(exports.TreeContext.Provider, { value: {
88
+ ...props,
89
+ data,
90
+ selected: selectedNodes,
91
+ isSingleSelect,
92
+ isMultiSelect,
93
+ isSelectable,
94
+ expandedNodes,
95
+ onExpand,
96
+ onSelect,
97
+ onNodeClick,
98
+ focusedNodeId,
99
+ setFocusPosition,
100
+ resetFocusPosition,
101
+ setFocusIndex,
102
+ focusableNodeIds,
103
+ getSelectionState,
104
+ toggleSelection,
105
+ }, children: children }));
106
+ }
107
+ const useTreeContext = () => (0, react_1.useContext)(exports.TreeContext);
108
+ exports.useTreeContext = useTreeContext;
@@ -0,0 +1,11 @@
1
+ import { ParentNode } from '../../types';
2
+ import { TreeNodeProps } from '../TreeNode';
3
+ type ExpandableTreeNodeProps = {
4
+ node: TreeNodeProps;
5
+ parentNode?: ParentNode & {
6
+ parentNode?: ParentNode;
7
+ };
8
+ tabIndexAvailable?: boolean;
9
+ };
10
+ export declare const ExpandableTreeNode: import("react").ForwardRefExoticComponent<ExpandableTreeNodeProps & import("react").RefAttributes<HTMLDivElement>>;
11
+ export {};
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ExpandableTreeNode = void 0;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const react_1 = require("react");
9
+ const react_transition_state_1 = __importDefault(require("react-transition-state"));
10
+ const constants_1 = require("../../constants");
11
+ const TreeContext_1 = require("../../contexts/TreeContext");
12
+ const TreeItem_1 = require("../TreeItem");
13
+ const TreeLine_1 = require("../TreeLine");
14
+ const TreeNode_1 = require("../TreeNode");
15
+ const styles_module_scss_1 = __importDefault(require('./styles.module.css'));
16
+ exports.ExpandableTreeNode = (0, react_1.forwardRef)(({ node: { 'data-test-id': dataTestId, ...node }, parentNode, tabIndexAvailable }, ref) => {
17
+ const { expandedNodes, onExpand, onDataLoad, showLines } = (0, TreeContext_1.useTreeContext)();
18
+ const isExpandable = Boolean(node.nested);
19
+ const isExpanded = expandedNodes?.includes(node.id) || false;
20
+ const [loading, setLoading] = (0, react_1.useState)(false);
21
+ const [state, toggle] = (0, react_transition_state_1.default)({
22
+ timeout: constants_1.TRANSITION_TIMING.accordionFolding,
23
+ initialEntered: isExpanded || undefined,
24
+ enter: isExpanded,
25
+ });
26
+ const showContent = node.nested && node.nested.length > 0 && state.status !== 'exited';
27
+ const childrenRefs = (0, react_1.useRef)([]);
28
+ const [lastItemHeight, setLastItemHeight] = (0, react_1.useState)(0);
29
+ (0, react_1.useEffect)(() => {
30
+ const lastItem = childrenRefs.current?.at(-1);
31
+ if (lastItem) {
32
+ // Trunk обрывается L-bend'ом на середине СТРОКИ последнего ребёнка, не его поддерева.
33
+ // Укорачиваем на (wrapperHeight - rowHeight/2); для листа == rowHeight/2.
34
+ const lastRow = (lastItem.hasAttribute('data-node-id') ? lastItem : lastItem.querySelector('[data-node-id]')) ?? lastItem;
35
+ const recompute = () => {
36
+ const wrapperHeight = lastItem.getBoundingClientRect().height;
37
+ const rowHeight = lastRow.getBoundingClientRect().height;
38
+ setLastItemHeight(wrapperHeight - rowHeight / 2);
39
+ };
40
+ const observer = new ResizeObserver(() => recompute());
41
+ observer.observe(lastItem);
42
+ if (lastRow !== lastItem)
43
+ observer.observe(lastRow);
44
+ recompute();
45
+ return () => observer.disconnect();
46
+ }
47
+ }, [state.status]);
48
+ (0, react_1.useEffect)(() => {
49
+ if (node.nested?.length && isExpanded && state.status === 'exited') {
50
+ toggle(true);
51
+ }
52
+ }, [isExpanded, node.nested, state.status]);
53
+ const toggleExpand = async () => {
54
+ if (node.nested && !node.nested.length && !isExpanded && onDataLoad) {
55
+ setLoading(true);
56
+ await onDataLoad(node).finally(() => {
57
+ setLoading(false);
58
+ });
59
+ }
60
+ onExpand(node);
61
+ toggle();
62
+ };
63
+ const handleKeyDown = e => {
64
+ if (!isExpandable)
65
+ return;
66
+ switch (e.key) {
67
+ case 'ArrowRight': {
68
+ if (!isExpanded) {
69
+ toggleExpand();
70
+ }
71
+ return;
72
+ }
73
+ case 'ArrowLeft': {
74
+ if (isExpanded) {
75
+ toggleExpand();
76
+ }
77
+ return;
78
+ }
79
+ default:
80
+ return;
81
+ }
82
+ };
83
+ return ((0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.expandableTreeNode, "data-test-id": dataTestId, "data-expandable": Boolean(node.nested) || undefined, "data-disabled": node.disabled || undefined, ref: ref, children: [(0, jsx_runtime_1.jsx)(TreeNode_1.TreeNode, { ...node, loading: loading, parentNode: parentNode, onChevronClick: toggleExpand, onKeyDown: handleKeyDown, tabIndexAvailable: tabIndexAvailable }), node.nested && ((0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.expandableWrap, "data-expanded": isExpanded || undefined, "data-test-id": constants_1.TEST_IDS.expandable, children: showContent && ((0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.expandableContent, "data-test-id": constants_1.TEST_IDS.expandableContent, children: [(0, jsx_runtime_1.jsx)(TreeLine_1.TreeLine, { visible: showLines, "data-test-id": constants_1.TEST_IDS.line, style: { height: `calc(100% - ${lastItemHeight}px)` } }), (0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.expandableNested, children: node.nested.map((nestedNode, index) => {
84
+ const parent = { id: node.id, nested: node.nested, parentNode };
85
+ return ((0, jsx_runtime_1.jsx)(TreeItem_1.TreeItem, { ref: el => (childrenRefs.current[index] = el), node: { ...nestedNode, disabled: node.disabled || nestedNode.disabled }, parentNode: parent }, nestedNode.id));
86
+ }) })] })) }))] }));
87
+ });
@@ -0,0 +1 @@
1
+ export * from './ExpandableTreeNode';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./ExpandableTreeNode"), exports);
@@ -0,0 +1,37 @@
1
+ .expandableTreeNode{
2
+ position:relative;
3
+ width:100%;
4
+ }
5
+
6
+ .expandableContent{
7
+ overflow:visible hidden;
8
+ display:flex;
9
+ gap:var(--tree-item-gap);
10
+ box-sizing:border-box;
11
+ min-width:0;
12
+ min-height:0;
13
+ visibility:hidden;
14
+ transition:visibility 200ms;
15
+ }
16
+
17
+ .expandableWrap{
18
+ overflow:visible hidden;
19
+ display:grid;
20
+ grid-template-rows:0fr;
21
+ box-sizing:border-box;
22
+ width:100%;
23
+ transition:grid-template-rows 200ms;
24
+ }
25
+ .expandableWrap[data-expanded=true]{
26
+ overflow:unset;
27
+ grid-template-rows:1fr;
28
+ }
29
+ .expandableWrap[data-expanded=true] .expandableContent{
30
+ overflow:unset;
31
+ visibility:visible;
32
+ }
33
+
34
+ .expandableNested{
35
+ width:100%;
36
+ min-width:0;
37
+ }
@@ -0,0 +1,8 @@
1
+ import { ParentNode, TreeNodeProps } from '../../types';
2
+ type TreeItemProps = {
3
+ node: TreeNodeProps;
4
+ parentNode?: ParentNode;
5
+ tabIndexAvailable?: boolean;
6
+ };
7
+ export declare const TreeItem: import("react").ForwardRefExoticComponent<TreeItemProps & import("react").RefAttributes<HTMLDivElement>>;
8
+ export {};
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TreeItem = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const constants_1 = require("../../constants");
7
+ const ExpandableTreeNode_1 = require("../ExpandableTreeNode");
8
+ const TreeNode_1 = require("../TreeNode");
9
+ exports.TreeItem = (0, react_1.forwardRef)(({ node, tabIndexAvailable, parentNode }, ref) => {
10
+ const dataTestId = node['data-test-id'] || constants_1.TEST_IDS.node;
11
+ const nodeProps = { ...node, 'data-test-id': dataTestId };
12
+ if (node.nested) {
13
+ return ((0, jsx_runtime_1.jsx)(ExpandableTreeNode_1.ExpandableTreeNode, { node: nodeProps, tabIndexAvailable: tabIndexAvailable, parentNode: parentNode, ref: ref }));
14
+ }
15
+ return (0, jsx_runtime_1.jsx)(TreeNode_1.TreeNode, { ...nodeProps, tabIndexAvailable: tabIndexAvailable, parentNode: parentNode, ref: ref });
16
+ });
@@ -0,0 +1 @@
1
+ export * from './TreeItem';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./TreeItem"), exports);
@@ -0,0 +1,10 @@
1
+ import { CSSProperties } from 'react';
2
+ export type TreeLineProps = {
3
+ className?: string;
4
+ /** Доп. инлайн-стили для контейнера (height/width передаются здесь, а не отдельными пропами). */
5
+ style?: CSSProperties;
6
+ halfWidth?: boolean;
7
+ visible?: boolean;
8
+ horizontal?: boolean;
9
+ };
10
+ export declare function TreeLine({ className, style, halfWidth, horizontal, visible }: TreeLineProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.TreeLine = TreeLine;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const classnames_1 = __importDefault(require("classnames"));
9
+ const constants_1 = require("../../constants");
10
+ const styles_module_scss_1 = __importDefault(require('./styles.module.css'));
11
+ function TreeLine({ className, style, halfWidth, horizontal, visible }) {
12
+ return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(styles_module_scss_1.default.treeLine, className), style: style, "data-horizontal": horizontal || undefined, "data-half-width": halfWidth || undefined, "data-visible": visible || undefined, "data-test-id": constants_1.TEST_IDS.line }));
13
+ }
@@ -0,0 +1 @@
1
+ export * from './TreeLine';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./TreeLine"), exports);
@@ -0,0 +1,37 @@
1
+ .treeLine{
2
+ pointer-events:none;
3
+ position:relative;
4
+ flex-shrink:0;
5
+ width:var(--tree-line-width, var(--sn-density-size-icon-s, var(--sn-primitive-dimension-24, 24px)));
6
+ visibility:hidden;
7
+ }
8
+ .treeLine[data-visible]{
9
+ visibility:visible;
10
+ }
11
+ .treeLine[data-visible]::after{
12
+ content:"";
13
+ position:absolute;
14
+ top:0;
15
+ left:50%;
16
+ transform:translateX(-50%);
17
+ width:var(--sn-primitive-strokeWeight-strokeRegular, 1px);
18
+ height:100%;
19
+ background:var(--sn-theme-color-available-borderColor, var(--sn-brand-color-state-neutralBorder-forLightMode-default-borderColor, rgba(159, 166, 198, 0.3019607843)));
20
+ }
21
+ .treeLine[data-horizontal]{
22
+ box-sizing:border-box;
23
+ }
24
+ .treeLine[data-horizontal]::after{
25
+ top:50%;
26
+ left:calc(-50% - var(--tree-item-gap, 0px));
27
+ transform:translateY(-50%);
28
+ width:calc(150% + var(--tree-item-gap, 0px));
29
+ height:var(--sn-primitive-strokeWeight-strokeRegular, 1px);
30
+ }
31
+ .treeLine[data-horizontal][data-half-width]{
32
+ width:0;
33
+ }
34
+ .treeLine[data-horizontal][data-half-width]::after{
35
+ left:calc(0px - var(--tree-line-width, var(--sn-density-size-icon-s, var(--sn-primitive-dimension-24, 24px))) / 2 - var(--tree-item-gap, 0px));
36
+ width:calc(var(--tree-line-width, var(--sn-density-size-icon-s, var(--sn-primitive-dimension-24, 24px))) / 2 + var(--tree-item-gap, 0px));
37
+ }
@@ -0,0 +1,4 @@
1
+ import { TreeNodeProps } from '../../types';
2
+ import { TreeNodeComponentProps } from './types';
3
+ export type { TreeNodeProps };
4
+ export declare const TreeNode: import("react").ForwardRefExoticComponent<TreeNodeComponentProps & import("react").RefAttributes<HTMLDivElement>>;