@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,151 @@
1
+ import { ItemProps } from '@cloud-ru/ds-list';
2
+ import { ValueOf, WithSupportProps } from '@cloud-ru/ds-utils';
3
+ import { MouseEvent, MouseEventHandler, ReactNode } from 'react';
4
+ import { SELECTION_MODE, SIZE } from './constants';
5
+ export type SelectionMode = ValueOf<typeof SELECTION_MODE>;
6
+ export type Size = ValueOf<typeof SIZE>;
7
+ export type TreeNodeId = string;
8
+ export type BaseTreeNode = WithSupportProps<{
9
+ /** Идентификатор элемента */
10
+ id: TreeNodeId;
11
+ /** Имя элемента */
12
+ title: string | ((value: Pick<BaseTreeNode, 'id' | 'disabled'>) => ReactNode);
13
+ /** Является ли элемент деактивированным */
14
+ disabled?: boolean;
15
+ /** Обработчик клика по элементу */
16
+ onClick?: MouseEventHandler;
17
+ /** CSS-класс */
18
+ className?: string;
19
+ /** Ссылка на элемент */
20
+ href?: string;
21
+ }>;
22
+ export type ChildTreeNode = BaseTreeNode & {
23
+ /** Иконка дочернего элемента */
24
+ icon?: ReactNode;
25
+ nested?: never;
26
+ expandedIcon?: never;
27
+ collapsedIcon?: never;
28
+ };
29
+ export type ParentTreeNode = BaseTreeNode & {
30
+ icon?: never;
31
+ /** Иконка элемента-родителя в открытом состоянии */
32
+ expandedIcon?: ReactNode;
33
+ /** Иконка элемента-родителя в закрытом состоянии */
34
+ collapsedIcon?: ReactNode;
35
+ /** Вложенные элементы дерева */
36
+ nested: (ChildTreeNode | ParentTreeNode)[];
37
+ /** Имя элемента-родителя (расширяет вариант из `BaseTreeNode` — в callback приходят также `nested`-узлы) */
38
+ title: string | ((value: Pick<ParentTreeNode, 'id' | 'disabled' | 'nested'>) => ReactNode);
39
+ };
40
+ export type TreeNodeProps = ChildTreeNode | ParentTreeNode;
41
+ export type ParentNode = Pick<TreeNodeProps, 'id' | 'nested'> & {
42
+ parentNode?: ParentNode;
43
+ };
44
+ export type OnNodeClick = (node: TreeNodeProps, e: MouseEvent) => void;
45
+ export type TreeCommonProps = {
46
+ /** Данные для отрисовки */
47
+ data: TreeNodeProps[];
48
+ /**
49
+ * Режим выбора элементов:
50
+ * <br> - `Single` - одиночный выбор
51
+ * <br> - `Multi` - множественный выбор
52
+ * <br> - `undefined` - без выбора
53
+ */
54
+ selectionMode?: SelectionMode;
55
+ /** Обработчик клика по элементу дерева */
56
+ onNodeClick?: OnNodeClick;
57
+ /** Состояние для раскрытых элементов */
58
+ expandedNodes?: TreeNodeId[];
59
+ /** Колбэк при раскрытии/закрытии элементов */
60
+ onExpand?(expandedKeys: TreeNodeId[], node: TreeNodeProps): void;
61
+ /** Состояние для выбранных элементов */
62
+ selected?: TreeNodeId[] | TreeNodeId;
63
+ /** Колбэк для асинхронной загрузки данных при раскрытии дерева */
64
+ onDataLoad?(node: TreeNodeProps): Promise<boolean | unknown>;
65
+ /** Дополнительные действия для элемента-родителя */
66
+ parentActions?(node: TreeNodeProps): ItemProps[];
67
+ /** Дополнительные действия для элемента-потомка */
68
+ nodeActions?(node: TreeNodeProps): ItemProps[];
69
+ /**
70
+ * Флаг отвечающий за отображение иконок у элементов дерева
71
+ * @default true
72
+ */
73
+ showIcons?: boolean;
74
+ /** Флаг отвечающий за отображение линий вложенности */
75
+ showLines?: boolean;
76
+ /**
77
+ * Размер строк дерева (Figma variant `size`).
78
+ * @default 'm'
79
+ */
80
+ size?: Size;
81
+ /**
82
+ * Максимальное число строк заголовка узла до обрезки многоточием.
83
+ * Значение больше 1 разрешает перенос; строка растёт по высоте.
84
+ * @default 1
85
+ */
86
+ titleMaxLines?: number;
87
+ /** CSS-класс */
88
+ className?: string;
89
+ };
90
+ export type TreeView = Omit<TreeCommonProps, 'selected' | 'selectionMode'> & {
91
+ selectionMode?: never;
92
+ selected?: never;
93
+ onSelect?: never;
94
+ };
95
+ export type TreeSingleSelect = Omit<TreeCommonProps, 'selected'> & {
96
+ selectionMode: 'single';
97
+ /** Состояние для выбраного элемента */
98
+ /** <br> - При <strong>selectionMode</strong>=`Single` - принимает строку */
99
+ selected?: TreeNodeId;
100
+ /** <br> - При <strong>selectionMode</strong>=`Single` - возвращает строку */
101
+ onSelect?(selectedKey: TreeNodeId, node: TreeNodeProps): void;
102
+ showToggle?: boolean;
103
+ };
104
+ export type TreeMultiSelect = Omit<TreeCommonProps, 'selected'> & {
105
+ selectionMode: 'multiple';
106
+ /**
107
+ * Состояние для выбраных элементов:
108
+ * <br> - При <strong>selectionMode</strong>=`Multiple` - принимает массив строк
109
+ */
110
+ selected?: TreeNodeId[];
111
+ /**
112
+ * Колбэк при изменении выбраных элементов:
113
+ * <br> - При <strong>selectionMode</strong>=`Multiple` - возвращает массив строк
114
+ */
115
+ onSelect?(selectedKeys: TreeNodeId[], node: TreeNodeProps): void;
116
+ };
117
+ export type TreeBaseProps = TreeView | TreeMultiSelect | TreeSingleSelect;
118
+ /**
119
+ * Расширение `TreeNodeProps` для внутренних helper'ов поиска/сортировки.
120
+ *
121
+ * Когда `title` — функция (а не строка), helper'ы не могут отсортировать или
122
+ * отфильтровать узел по содержимому JSX. `getTitle` даёт строковый ключ, по
123
+ * которому можно сравнивать узлы.
124
+ */
125
+ export type ExtendedTreeNodeProps = TreeNodeProps & {
126
+ /** Возвращает строковый ключ узла для сравнения/поиска, когда `title` — ReactNode. */
127
+ getTitle?(): string;
128
+ };
129
+ export type PreloadNodeHandler<TTreeNode extends TreeNodeProps> = (node: TreeNodeProps) => Promise<{
130
+ preloadedChildren: TTreeNode[];
131
+ updatedTree: TTreeNode[];
132
+ }>;
133
+ export type SearchableTreeDataLoadResult<TTreeNode extends TreeNodeProps, TRecordValue> = {
134
+ preloadedChildren: TTreeNode[];
135
+ updatedTree: TTreeNode[];
136
+ newTreeItemsRecord: Record<string, TRecordValue>;
137
+ };
138
+ /**
139
+ * Резолвер выделения для multi-select-режима: получает текущий список выбранных
140
+ * id, целевой узел и его новое состояние, возвращает diff (`added`/`removed`)
141
+ * относительно входного `selectedKeys`. Используется для кастомных стратегий
142
+ * каскадирования.
143
+ */
144
+ export type SelectHandler = (props: {
145
+ selectedKeys: string[];
146
+ node: TreeNodeProps;
147
+ isSelected: boolean;
148
+ }) => {
149
+ added: string[];
150
+ removed: string[];
151
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,4 @@
1
+ import { WithSupportProps } from '@cloud-ru/ds-utils';
2
+ import { TreeBaseProps } from '../../types.js';
3
+ export type TreeProps = WithSupportProps<TreeBaseProps>;
4
+ export declare function Tree({ data, onNodeClick, onExpand, expandedNodes, nodeActions, parentActions, onDataLoad, showLines, showIcons, size, titleMaxLines, className, ...rest }: TreeProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { extractSupportProps } from '@cloud-ru/ds-utils';
3
+ import cn from 'classnames';
4
+ import { SIZE } from '../../constants.js';
5
+ import { TreeContextProvider } from '../../contexts/TreeContext.js';
6
+ import { TreeItem } from '../../helperComponents/index.js';
7
+ import styles from './styles.module.css';
8
+ import { extractSelectableProps } from './utils.js';
9
+ export function Tree({ data, onNodeClick, onExpand, expandedNodes, nodeActions, parentActions, onDataLoad, showLines = true, showIcons = true, size = SIZE.M, titleMaxLines = 1, className, ...rest }) {
10
+ return (_jsx("div", { className: cn(styles.tree, className), role: 'tree', "data-size": size, ...extractSupportProps(rest), children: _jsx(TreeContextProvider, { value: {
11
+ showToggle: rest.selectionMode === 'single' && rest.showToggle,
12
+ data,
13
+ expandedNodes,
14
+ onNodeClick,
15
+ onExpand,
16
+ nodeActions,
17
+ parentActions,
18
+ onDataLoad,
19
+ showLines,
20
+ showIcons,
21
+ size,
22
+ titleMaxLines,
23
+ ...extractSelectableProps(rest),
24
+ }, children: data.map((node, index) => (_jsx(TreeItem, { node: node, tabIndexAvailable: index === 0 || index === data.length - 1 }, node.id))) }) }));
25
+ }
@@ -0,0 +1 @@
1
+ export * from './Tree.js';
@@ -0,0 +1 @@
1
+ export * from './Tree.js';
@@ -0,0 +1,17 @@
1
+ .tree{
2
+ box-sizing:border-box;
3
+ min-width:0;
4
+ height:100%;
5
+ }
6
+ .tree[data-size=s]{
7
+ --tree-line-width:var(--sn-tree-anatomy-size-s-treeItem-centeredWrapper-width, var(--sn-density-size-icon-xs, var(--sn-primitive-dimension-24, 24px)));
8
+ --tree-item-gap:var(--sn-tree-anatomy-size-s-treeItem-gap, var(--sn-density-spacing-control-container-horizontal-s, var(--sn-primitive-dimension-12, 12px)));
9
+ }
10
+ .tree[data-size=m]{
11
+ --tree-line-width:var(--sn-tree-anatomy-size-m-treeItem-centeredWrapper-width, var(--sn-density-size-icon-s, var(--sn-primitive-dimension-24, 24px)));
12
+ --tree-item-gap:var(--sn-tree-anatomy-size-m-treeItem-gap, var(--sn-density-spacing-control-container-horizontal-m, var(--sn-primitive-dimension-16, 16px)));
13
+ }
14
+ .tree[data-size=l]{
15
+ --tree-line-width:var(--sn-tree-anatomy-size-l-treeItem-centeredWrapper-width, var(--sn-density-size-icon-s, var(--sn-primitive-dimension-24, 24px)));
16
+ --tree-item-gap:var(--sn-tree-anatomy-size-l-treeItem-gap, var(--sn-density-spacing-control-container-horizontal-l, var(--sn-primitive-dimension-20, 20px)));
17
+ }
@@ -0,0 +1,4 @@
1
+ import { TreeBaseProps, TreeMultiSelect, TreeSingleSelect, TreeView } from '../../types.js';
2
+ type SelectableProps<T> = Pick<T, Extract<keyof T, 'selectionMode' | 'selected' | 'onSelect'>>;
3
+ export declare function extractSelectableProps({ selectionMode, selected, onSelect }: SelectableProps<TreeBaseProps>): SelectableProps<TreeSingleSelect> | SelectableProps<TreeMultiSelect> | SelectableProps<TreeView>;
4
+ export {};
@@ -0,0 +1,12 @@
1
+ import { SELECTION_MODE } from '../../constants.js';
2
+ // Сужение discriminated union к конкретному варианту: TS не выводит ветку из switch-case по
3
+ // дженерик-проп `selectionMode`, поэтому возвращаем строго типизированный Pick через `as`.
4
+ export function extractSelectableProps({ selectionMode, selected, onSelect }) {
5
+ if (selectionMode === SELECTION_MODE.Single) {
6
+ return { selectionMode, selected, onSelect };
7
+ }
8
+ if (selectionMode === SELECTION_MODE.Multiple) {
9
+ return { selectionMode, selected, onSelect };
10
+ }
11
+ return {};
12
+ }
@@ -0,0 +1 @@
1
+ export * from './Tree/index.js';
@@ -0,0 +1 @@
1
+ export * from './Tree/index.js';
@@ -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,26 @@
1
+ export const SELECTION_MODE = {
2
+ Single: 'single',
3
+ Multiple: 'multiple',
4
+ };
5
+ export const SIZE = {
6
+ S: 's',
7
+ M: 'm',
8
+ L: 'l',
9
+ };
10
+ export const TRANSITION_TIMING = {
11
+ accordionFolding: 200,
12
+ };
13
+ export const TEST_IDS = {
14
+ node: 'tree__node',
15
+ line: 'tree__node__line',
16
+ item: 'tree__node__item',
17
+ chevron: 'tree__node__chevron',
18
+ checkbox: 'tree__node__checkbox',
19
+ radio: 'tree__node__radio',
20
+ icon: 'tree__node__icon',
21
+ title: 'tree__node__title',
22
+ droplistTrigger: 'tree__node__droplist-trigger',
23
+ expandable: 'tree__node__expandable',
24
+ expandableContent: 'tree__node__expandable-content',
25
+ link: 'tree__node__link',
26
+ };
@@ -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.js';
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,103 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useHierarchicalSelection, useUncontrolledProp } from '@cloud-ru/ds-utils';
3
+ import { createContext, useCallback, useContext, useMemo, useState } from 'react';
4
+ import { SELECTION_MODE } from '../constants.js';
5
+ import { findAllExpandedChildNodeIds, lookupTreeForSelectedNodes } from '../helpers/index.js';
6
+ const EMPTY_EXPANDED = [];
7
+ export const TreeContext = createContext({
8
+ data: [],
9
+ selected: undefined,
10
+ onSelect() { },
11
+ expandedNodes: [],
12
+ onExpand() { },
13
+ onNodeClick() { },
14
+ setFocusPosition() { },
15
+ setFocusIndex() { },
16
+ resetFocusPosition() { },
17
+ focusableNodeIds: [],
18
+ isMultiSelect: false,
19
+ isSingleSelect: false,
20
+ isSelectable: false,
21
+ getSelectionState: () => ({ checked: false, indeterminate: false }),
22
+ toggleSelection: ({ selectedIds }) => selectedIds,
23
+ });
24
+ export function TreeContextProvider({ children, value }) {
25
+ const { onNodeClick: onNodeClickProp, onExpand: onExpandProp, onSelect: onSelectProp, selectionMode, data, ...props } = value;
26
+ const isMultiSelect = selectionMode === SELECTION_MODE.Multiple;
27
+ const isSingleSelect = selectionMode === SELECTION_MODE.Single;
28
+ const isSelectable = Boolean(selectionMode);
29
+ const { getSelectionState, toggleSelection } = useHierarchicalSelection({ includeParentsInValue: true });
30
+ const [expandedNodes, onExpandHandler] = useUncontrolledProp(value.expandedNodes, value.expandedNodes ?? EMPTY_EXPANDED, onExpandProp);
31
+ const onExpand = useCallback(node => {
32
+ const isExpanded = expandedNodes.includes(node.id);
33
+ const nodes = isExpanded ? expandedNodes.filter(id => id !== node.id) : expandedNodes.concat(node.id);
34
+ onExpandHandler(nodes, node);
35
+ }, [expandedNodes, onExpandHandler]);
36
+ const [selectedNodes, onSelectHandler] = useUncontrolledProp(value.selected, [], onSelectProp);
37
+ const onSelect = useCallback((node, parentNode) => {
38
+ if (!isSelectable || node.disabled)
39
+ return;
40
+ if (isSingleSelect) {
41
+ onSelectHandler(node.id === selectedNodes ? undefined : node.id, node);
42
+ return;
43
+ }
44
+ if (Array.isArray(selectedNodes)) {
45
+ const updatedSelectedNodes = lookupTreeForSelectedNodes({
46
+ node,
47
+ parentNode,
48
+ selectedNodes,
49
+ toggleSelection,
50
+ });
51
+ onSelectHandler(updatedSelectedNodes, node);
52
+ }
53
+ }, [isSingleSelect, onSelectHandler, selectedNodes, isSelectable, toggleSelection]);
54
+ const focusableNodeIds = useMemo(() => {
55
+ if (!expandedNodes?.length) {
56
+ return data.map(node => node.id);
57
+ }
58
+ return data.reduce((acc, cur) => {
59
+ acc.push(cur.id);
60
+ const isExpanded = expandedNodes.includes(cur.id);
61
+ if (isExpanded && cur.nested?.length) {
62
+ acc.push(...findAllExpandedChildNodeIds(cur.nested, expandedNodes));
63
+ }
64
+ return acc;
65
+ }, []);
66
+ }, [data, expandedNodes]);
67
+ const [focusIndex, setFocusIndex] = useState();
68
+ const focusedNodeId = focusIndex !== undefined ? focusableNodeIds[focusIndex] : undefined;
69
+ const setFocusPosition = useCallback((nodeId) => {
70
+ const newFocusIndex = focusableNodeIds.indexOf(nodeId);
71
+ setFocusIndex(newFocusIndex >= 0 ? newFocusIndex : undefined);
72
+ }, [focusableNodeIds]);
73
+ const resetFocusPosition = useCallback(() => setFocusIndex(undefined), []);
74
+ const onNodeClick = useCallback((node, e) => {
75
+ if (node.disabled) {
76
+ return;
77
+ }
78
+ if (isSingleSelect) {
79
+ onSelect(node);
80
+ }
81
+ node.onClick?.(e) || onNodeClickProp?.(node, e);
82
+ }, [isSingleSelect, onSelect, onNodeClickProp]);
83
+ return (_jsx(TreeContext.Provider, { value: {
84
+ ...props,
85
+ data,
86
+ selected: selectedNodes,
87
+ isSingleSelect,
88
+ isMultiSelect,
89
+ isSelectable,
90
+ expandedNodes,
91
+ onExpand,
92
+ onSelect,
93
+ onNodeClick,
94
+ focusedNodeId,
95
+ setFocusPosition,
96
+ resetFocusPosition,
97
+ setFocusIndex,
98
+ focusableNodeIds,
99
+ getSelectionState,
100
+ toggleSelection,
101
+ }, children: children }));
102
+ }
103
+ export const useTreeContext = () => useContext(TreeContext);
@@ -0,0 +1,11 @@
1
+ import { ParentNode } from '../../types.js';
2
+ import { TreeNodeProps } from '../TreeNode/index.js';
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,81 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { forwardRef, useEffect, useRef, useState } from 'react';
3
+ import useTransition from 'react-transition-state';
4
+ import { TEST_IDS, TRANSITION_TIMING } from '../../constants.js';
5
+ import { useTreeContext } from '../../contexts/TreeContext.js';
6
+ import { TreeItem } from '../TreeItem/index.js';
7
+ import { TreeLine } from '../TreeLine/index.js';
8
+ import { TreeNode } from '../TreeNode/index.js';
9
+ import styles from './styles.module.css';
10
+ export const ExpandableTreeNode = forwardRef(({ node: { 'data-test-id': dataTestId, ...node }, parentNode, tabIndexAvailable }, ref) => {
11
+ const { expandedNodes, onExpand, onDataLoad, showLines } = useTreeContext();
12
+ const isExpandable = Boolean(node.nested);
13
+ const isExpanded = expandedNodes?.includes(node.id) || false;
14
+ const [loading, setLoading] = useState(false);
15
+ const [state, toggle] = useTransition({
16
+ timeout: TRANSITION_TIMING.accordionFolding,
17
+ initialEntered: isExpanded || undefined,
18
+ enter: isExpanded,
19
+ });
20
+ const showContent = node.nested && node.nested.length > 0 && state.status !== 'exited';
21
+ const childrenRefs = useRef([]);
22
+ const [lastItemHeight, setLastItemHeight] = useState(0);
23
+ useEffect(() => {
24
+ const lastItem = childrenRefs.current?.at(-1);
25
+ if (lastItem) {
26
+ // Trunk обрывается L-bend'ом на середине СТРОКИ последнего ребёнка, не его поддерева.
27
+ // Укорачиваем на (wrapperHeight - rowHeight/2); для листа == rowHeight/2.
28
+ const lastRow = (lastItem.hasAttribute('data-node-id') ? lastItem : lastItem.querySelector('[data-node-id]')) ?? lastItem;
29
+ const recompute = () => {
30
+ const wrapperHeight = lastItem.getBoundingClientRect().height;
31
+ const rowHeight = lastRow.getBoundingClientRect().height;
32
+ setLastItemHeight(wrapperHeight - rowHeight / 2);
33
+ };
34
+ const observer = new ResizeObserver(() => recompute());
35
+ observer.observe(lastItem);
36
+ if (lastRow !== lastItem)
37
+ observer.observe(lastRow);
38
+ recompute();
39
+ return () => observer.disconnect();
40
+ }
41
+ }, [state.status]);
42
+ useEffect(() => {
43
+ if (node.nested?.length && isExpanded && state.status === 'exited') {
44
+ toggle(true);
45
+ }
46
+ }, [isExpanded, node.nested, state.status]);
47
+ const toggleExpand = async () => {
48
+ if (node.nested && !node.nested.length && !isExpanded && onDataLoad) {
49
+ setLoading(true);
50
+ await onDataLoad(node).finally(() => {
51
+ setLoading(false);
52
+ });
53
+ }
54
+ onExpand(node);
55
+ toggle();
56
+ };
57
+ const handleKeyDown = e => {
58
+ if (!isExpandable)
59
+ return;
60
+ switch (e.key) {
61
+ case 'ArrowRight': {
62
+ if (!isExpanded) {
63
+ toggleExpand();
64
+ }
65
+ return;
66
+ }
67
+ case 'ArrowLeft': {
68
+ if (isExpanded) {
69
+ toggleExpand();
70
+ }
71
+ return;
72
+ }
73
+ default:
74
+ return;
75
+ }
76
+ };
77
+ return (_jsxs("div", { className: styles.expandableTreeNode, "data-test-id": dataTestId, "data-expandable": Boolean(node.nested) || undefined, "data-disabled": node.disabled || undefined, ref: ref, children: [_jsx(TreeNode, { ...node, loading: loading, parentNode: parentNode, onChevronClick: toggleExpand, onKeyDown: handleKeyDown, tabIndexAvailable: tabIndexAvailable }), node.nested && (_jsx("div", { className: styles.expandableWrap, "data-expanded": isExpanded || undefined, "data-test-id": TEST_IDS.expandable, children: showContent && (_jsxs("div", { className: styles.expandableContent, "data-test-id": TEST_IDS.expandableContent, children: [_jsx(TreeLine, { visible: showLines, "data-test-id": TEST_IDS.line, style: { height: `calc(100% - ${lastItemHeight}px)` } }), _jsx("div", { className: styles.expandableNested, children: node.nested.map((nestedNode, index) => {
78
+ const parent = { id: node.id, nested: node.nested, parentNode };
79
+ return (_jsx(TreeItem, { ref: el => (childrenRefs.current[index] = el), node: { ...nestedNode, disabled: node.disabled || nestedNode.disabled }, parentNode: parent }, nestedNode.id));
80
+ }) })] })) }))] }));
81
+ });
@@ -0,0 +1 @@
1
+ export * from './ExpandableTreeNode.js';
@@ -0,0 +1 @@
1
+ export * from './ExpandableTreeNode.js';
@@ -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.js';
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,13 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { forwardRef } from 'react';
3
+ import { TEST_IDS } from '../../constants.js';
4
+ import { ExpandableTreeNode } from '../ExpandableTreeNode/index.js';
5
+ import { TreeNode } from '../TreeNode/index.js';
6
+ export const TreeItem = forwardRef(({ node, tabIndexAvailable, parentNode }, ref) => {
7
+ const dataTestId = node['data-test-id'] || TEST_IDS.node;
8
+ const nodeProps = { ...node, 'data-test-id': dataTestId };
9
+ if (node.nested) {
10
+ return (_jsx(ExpandableTreeNode, { node: nodeProps, tabIndexAvailable: tabIndexAvailable, parentNode: parentNode, ref: ref }));
11
+ }
12
+ return _jsx(TreeNode, { ...nodeProps, tabIndexAvailable: tabIndexAvailable, parentNode: parentNode, ref: ref });
13
+ });
@@ -0,0 +1 @@
1
+ export * from './TreeItem.js';
@@ -0,0 +1 @@
1
+ export * from './TreeItem.js';
@@ -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,7 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import cn from 'classnames';
3
+ import { TEST_IDS } from '../../constants.js';
4
+ import styles from './styles.module.css';
5
+ export function TreeLine({ className, style, halfWidth, horizontal, visible }) {
6
+ return (_jsx("div", { className: cn(styles.treeLine, className), style: style, "data-horizontal": horizontal || undefined, "data-half-width": halfWidth || undefined, "data-visible": visible || undefined, "data-test-id": TEST_IDS.line }));
7
+ }
@@ -0,0 +1 @@
1
+ export * from './TreeLine.js';
@@ -0,0 +1 @@
1
+ export * from './TreeLine.js';