@cloud-ru/ds-uikit-product-page-layout 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 (385) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/LICENSE +201 -0
  3. package/README.md +943 -0
  4. package/dist/cjs/components/Actions/ActionView.d.ts +17 -0
  5. package/dist/cjs/components/Actions/ActionView.js +53 -0
  6. package/dist/cjs/components/Actions/DesktopActions.d.ts +10 -0
  7. package/dist/cjs/components/Actions/DesktopActions.js +26 -0
  8. package/dist/cjs/components/Actions/MobileActions.d.ts +10 -0
  9. package/dist/cjs/components/Actions/MobileActions.js +121 -0
  10. package/dist/cjs/components/Actions/buttons/ButtonDroplist.d.ts +11 -0
  11. package/dist/cjs/components/Actions/buttons/ButtonDroplist.js +21 -0
  12. package/dist/cjs/components/Actions/buttons/ButtonKebab.d.ts +7 -0
  13. package/dist/cjs/components/Actions/buttons/ButtonKebab.js +15 -0
  14. package/dist/cjs/components/Actions/buttons/ButtonQuota.d.ts +12 -0
  15. package/dist/cjs/components/Actions/buttons/ButtonQuota.js +8 -0
  16. package/dist/cjs/components/Actions/buttons/index.d.ts +3 -0
  17. package/dist/cjs/components/Actions/buttons/index.js +19 -0
  18. package/dist/cjs/components/Actions/constants.d.ts +11 -0
  19. package/dist/cjs/components/Actions/constants.js +14 -0
  20. package/dist/cjs/components/Actions/index.d.ts +7 -0
  21. package/dist/cjs/components/Actions/index.js +23 -0
  22. package/dist/cjs/components/Actions/styles.module.css +27 -0
  23. package/dist/cjs/components/Actions/types.d.ts +39 -0
  24. package/dist/cjs/components/Actions/types.js +2 -0
  25. package/dist/cjs/components/Actions/utils.d.ts +2 -0
  26. package/dist/cjs/components/Actions/utils.js +6 -0
  27. package/dist/cjs/components/DefaultSubtitle/DefaultSubtitle.d.ts +12 -0
  28. package/dist/cjs/components/DefaultSubtitle/DefaultSubtitle.js +14 -0
  29. package/dist/cjs/components/DefaultSubtitle/index.d.ts +1 -0
  30. package/dist/cjs/components/DefaultSubtitle/index.js +17 -0
  31. package/dist/cjs/components/DefaultSubtitle/styles.module.css +19 -0
  32. package/dist/cjs/components/Headline/Headline.d.ts +2 -0
  33. package/dist/cjs/components/Headline/Headline.js +17 -0
  34. package/dist/cjs/components/Headline/index.d.ts +2 -0
  35. package/dist/cjs/components/Headline/index.js +18 -0
  36. package/dist/cjs/components/Headline/styles.module.css +54 -0
  37. package/dist/cjs/components/Headline/types.d.ts +18 -0
  38. package/dist/cjs/components/Headline/types.js +2 -0
  39. package/dist/cjs/components/PageCatalog/DesktopPageCatalog.d.ts +11 -0
  40. package/dist/cjs/components/PageCatalog/DesktopPageCatalog.js +15 -0
  41. package/dist/cjs/components/PageCatalog/MobilePageCatalog.d.ts +10 -0
  42. package/dist/cjs/components/PageCatalog/MobilePageCatalog.js +15 -0
  43. package/dist/cjs/components/PageCatalog/PageCatalog.d.ts +13 -0
  44. package/dist/cjs/components/PageCatalog/PageCatalog.js +23 -0
  45. package/dist/cjs/components/PageCatalog/index.d.ts +3 -0
  46. package/dist/cjs/components/PageCatalog/index.js +19 -0
  47. package/dist/cjs/components/PageCatalog/mobileStyles.module.css +15 -0
  48. package/dist/cjs/components/PageCatalog/styles.module.css +16 -0
  49. package/dist/cjs/components/PageForm/DesktopPageForm.d.ts +5 -0
  50. package/dist/cjs/components/PageForm/DesktopPageForm.js +32 -0
  51. package/dist/cjs/components/PageForm/MobilePageForm.d.ts +11 -0
  52. package/dist/cjs/components/PageForm/MobilePageForm.js +88 -0
  53. package/dist/cjs/components/PageForm/PageForm.d.ts +12 -0
  54. package/dist/cjs/components/PageForm/PageForm.js +21 -0
  55. package/dist/cjs/components/PageForm/hooks.d.ts +22 -0
  56. package/dist/cjs/components/PageForm/hooks.js +51 -0
  57. package/dist/cjs/components/PageForm/index.d.ts +4 -0
  58. package/dist/cjs/components/PageForm/index.js +20 -0
  59. package/dist/cjs/components/PageForm/mobileStyles.module.css +75 -0
  60. package/dist/cjs/components/PageForm/styles.module.css +104 -0
  61. package/dist/cjs/components/PageForm/types.d.ts +47 -0
  62. package/dist/cjs/components/PageForm/types.js +2 -0
  63. package/dist/cjs/components/PageLoading/PageLoading.d.ts +6 -0
  64. package/dist/cjs/components/PageLoading/PageLoading.js +14 -0
  65. package/dist/cjs/components/PageLoading/index.d.ts +1 -0
  66. package/dist/cjs/components/PageLoading/index.js +17 -0
  67. package/dist/cjs/components/PageLoading/styles.module.css +13 -0
  68. package/dist/cjs/components/PageServices/DesktopPageServices.d.ts +5 -0
  69. package/dist/cjs/components/PageServices/DesktopPageServices.js +18 -0
  70. package/dist/cjs/components/PageServices/MobilePageServices.d.ts +12 -0
  71. package/dist/cjs/components/PageServices/MobilePageServices.js +16 -0
  72. package/dist/cjs/components/PageServices/PageServices.d.ts +14 -0
  73. package/dist/cjs/components/PageServices/PageServices.js +24 -0
  74. package/dist/cjs/components/PageServices/hooks.d.ts +6 -0
  75. package/dist/cjs/components/PageServices/hooks.js +29 -0
  76. package/dist/cjs/components/PageServices/index.d.ts +4 -0
  77. package/dist/cjs/components/PageServices/index.js +20 -0
  78. package/dist/cjs/components/PageServices/mobileStyles.module.css +28 -0
  79. package/dist/cjs/components/PageServices/styles.module.css +48 -0
  80. package/dist/cjs/components/PageServices/types.d.ts +10 -0
  81. package/dist/cjs/components/PageServices/types.js +2 -0
  82. package/dist/cjs/components/PageSidebar/PageSidebar.d.ts +21 -0
  83. package/dist/cjs/components/PageSidebar/PageSidebar.js +51 -0
  84. package/dist/cjs/components/PageSidebar/contexts.d.ts +13 -0
  85. package/dist/cjs/components/PageSidebar/contexts.js +21 -0
  86. package/dist/cjs/components/PageSidebar/helperComponents/SidebarSearch/SidebarSearch.d.ts +1 -0
  87. package/dist/cjs/components/PageSidebar/helperComponents/SidebarSearch/SidebarSearch.js +21 -0
  88. package/dist/cjs/components/PageSidebar/helperComponents/SidebarSearch/index.d.ts +1 -0
  89. package/dist/cjs/components/PageSidebar/helperComponents/SidebarSearch/index.js +17 -0
  90. package/dist/cjs/components/PageSidebar/helperComponents/SidebarSearchToggle/SidebarSearchToggle.d.ts +1 -0
  91. package/dist/cjs/components/PageSidebar/helperComponents/SidebarSearchToggle/SidebarSearchToggle.js +24 -0
  92. package/dist/cjs/components/PageSidebar/helperComponents/SidebarSearchToggle/index.d.ts +1 -0
  93. package/dist/cjs/components/PageSidebar/helperComponents/SidebarSearchToggle/index.js +17 -0
  94. package/dist/cjs/components/PageSidebar/helperComponents/SidebarSearchToggle/styles.module.css +4 -0
  95. package/dist/cjs/components/PageSidebar/helperComponents/SidebarSelect/SidebarSelect.d.ts +20 -0
  96. package/dist/cjs/components/PageSidebar/helperComponents/SidebarSelect/SidebarSelect.js +44 -0
  97. package/dist/cjs/components/PageSidebar/helperComponents/SidebarSelect/hooks/index.d.ts +3 -0
  98. package/dist/cjs/components/PageSidebar/helperComponents/SidebarSelect/hooks/index.js +9 -0
  99. package/dist/cjs/components/PageSidebar/helperComponents/SidebarSelect/hooks/useItemsContent.d.ts +3 -0
  100. package/dist/cjs/components/PageSidebar/helperComponents/SidebarSelect/hooks/useItemsContent.js +56 -0
  101. package/dist/cjs/components/PageSidebar/helperComponents/SidebarSelect/hooks/useSearchFilter.d.ts +7 -0
  102. package/dist/cjs/components/PageSidebar/helperComponents/SidebarSelect/hooks/useSearchFilter.js +40 -0
  103. package/dist/cjs/components/PageSidebar/helperComponents/SidebarSelect/hooks/useSelectedItem.d.ts +7 -0
  104. package/dist/cjs/components/PageSidebar/helperComponents/SidebarSelect/hooks/useSelectedItem.js +23 -0
  105. package/dist/cjs/components/PageSidebar/helperComponents/SidebarSelect/index.d.ts +1 -0
  106. package/dist/cjs/components/PageSidebar/helperComponents/SidebarSelect/index.js +17 -0
  107. package/dist/cjs/components/PageSidebar/helperComponents/SidebarSelect/styles.module.css +19 -0
  108. package/dist/cjs/components/PageSidebar/helperComponents/SidebarSelect/types.d.ts +1 -0
  109. package/dist/cjs/components/PageSidebar/helperComponents/SidebarSelect/types.js +2 -0
  110. package/dist/cjs/components/PageSidebar/helperComponents/SidebarTitle/SidebarTitle.d.ts +9 -0
  111. package/dist/cjs/components/PageSidebar/helperComponents/SidebarTitle/SidebarTitle.js +15 -0
  112. package/dist/cjs/components/PageSidebar/helperComponents/SidebarTitle/index.d.ts +1 -0
  113. package/dist/cjs/components/PageSidebar/helperComponents/SidebarTitle/index.js +17 -0
  114. package/dist/cjs/components/PageSidebar/helperComponents/SidebarTitle/styles.module.css +18 -0
  115. package/dist/cjs/components/PageSidebar/hooks/useItemsCreator.d.ts +8 -0
  116. package/dist/cjs/components/PageSidebar/hooks/useItemsCreator.js +106 -0
  117. package/dist/cjs/components/PageSidebar/hooks/useSearchFilter.d.ts +10 -0
  118. package/dist/cjs/components/PageSidebar/hooks/useSearchFilter.js +45 -0
  119. package/dist/cjs/components/PageSidebar/index.d.ts +3 -0
  120. package/dist/cjs/components/PageSidebar/index.js +19 -0
  121. package/dist/cjs/components/PageSidebar/styles.module.css +92 -0
  122. package/dist/cjs/components/PageSidebar/types.d.ts +42 -0
  123. package/dist/cjs/components/PageSidebar/types.js +2 -0
  124. package/dist/cjs/components/TreeNavigation/TreeNavigation.d.ts +2 -0
  125. package/dist/cjs/components/TreeNavigation/TreeNavigation.js +27 -0
  126. package/dist/cjs/components/TreeNavigation/helperComponents/ConditionalPopover/ConditionalPopover.d.ts +10 -0
  127. package/dist/cjs/components/TreeNavigation/helperComponents/ConditionalPopover/ConditionalPopover.js +15 -0
  128. package/dist/cjs/components/TreeNavigation/helperComponents/ConditionalPopover/styles.module.css +6 -0
  129. package/dist/cjs/components/TreeNavigation/helperComponents/Menu/Menu.d.ts +11 -0
  130. package/dist/cjs/components/TreeNavigation/helperComponents/Menu/Menu.js +25 -0
  131. package/dist/cjs/components/TreeNavigation/helperComponents/Menu/styles.module.css +12 -0
  132. package/dist/cjs/components/TreeNavigation/helperComponents/Menu/utils.d.ts +7 -0
  133. package/dist/cjs/components/TreeNavigation/helperComponents/Menu/utils.js +20 -0
  134. package/dist/cjs/components/TreeNavigation/helperComponents/index.d.ts +2 -0
  135. package/dist/cjs/components/TreeNavigation/helperComponents/index.js +18 -0
  136. package/dist/cjs/components/TreeNavigation/index.d.ts +2 -0
  137. package/dist/cjs/components/TreeNavigation/index.js +18 -0
  138. package/dist/cjs/components/TreeNavigation/styles.module.css +89 -0
  139. package/dist/cjs/components/TreeNavigation/types.d.ts +46 -0
  140. package/dist/cjs/components/TreeNavigation/types.js +2 -0
  141. package/dist/cjs/components/index.d.ts +9 -0
  142. package/dist/cjs/components/index.js +25 -0
  143. package/dist/cjs/constants.d.ts +57 -0
  144. package/dist/cjs/constants.js +53 -0
  145. package/dist/cjs/index.d.ts +4 -0
  146. package/dist/cjs/index.js +20 -0
  147. package/dist/cjs/locale/index.d.ts +112 -0
  148. package/dist/cjs/locale/index.js +62 -0
  149. package/dist/cjs/package.json +3 -0
  150. package/dist/cjs/style.css +639 -0
  151. package/dist/cjs/types.d.ts +7 -0
  152. package/dist/cjs/types.js +2 -0
  153. package/dist/esm/components/Actions/ActionView.d.ts +17 -0
  154. package/dist/esm/components/Actions/ActionView.js +50 -0
  155. package/dist/esm/components/Actions/DesktopActions.d.ts +10 -0
  156. package/dist/esm/components/Actions/DesktopActions.js +20 -0
  157. package/dist/esm/components/Actions/MobileActions.d.ts +10 -0
  158. package/dist/esm/components/Actions/MobileActions.js +115 -0
  159. package/dist/esm/components/Actions/buttons/ButtonDroplist.d.ts +11 -0
  160. package/dist/esm/components/Actions/buttons/ButtonDroplist.js +18 -0
  161. package/dist/esm/components/Actions/buttons/ButtonKebab.d.ts +7 -0
  162. package/dist/esm/components/Actions/buttons/ButtonKebab.js +12 -0
  163. package/dist/esm/components/Actions/buttons/ButtonQuota.d.ts +12 -0
  164. package/dist/esm/components/Actions/buttons/ButtonQuota.js +5 -0
  165. package/dist/esm/components/Actions/buttons/index.d.ts +3 -0
  166. package/dist/esm/components/Actions/buttons/index.js +3 -0
  167. package/dist/esm/components/Actions/constants.d.ts +11 -0
  168. package/dist/esm/components/Actions/constants.js +11 -0
  169. package/dist/esm/components/Actions/index.d.ts +7 -0
  170. package/dist/esm/components/Actions/index.js +7 -0
  171. package/dist/esm/components/Actions/styles.module.css +27 -0
  172. package/dist/esm/components/Actions/types.d.ts +39 -0
  173. package/dist/esm/components/Actions/types.js +1 -0
  174. package/dist/esm/components/Actions/utils.d.ts +2 -0
  175. package/dist/esm/components/Actions/utils.js +3 -0
  176. package/dist/esm/components/DefaultSubtitle/DefaultSubtitle.d.ts +12 -0
  177. package/dist/esm/components/DefaultSubtitle/DefaultSubtitle.js +8 -0
  178. package/dist/esm/components/DefaultSubtitle/index.d.ts +1 -0
  179. package/dist/esm/components/DefaultSubtitle/index.js +1 -0
  180. package/dist/esm/components/DefaultSubtitle/styles.module.css +19 -0
  181. package/dist/esm/components/Headline/Headline.d.ts +2 -0
  182. package/dist/esm/components/Headline/Headline.js +11 -0
  183. package/dist/esm/components/Headline/index.d.ts +2 -0
  184. package/dist/esm/components/Headline/index.js +2 -0
  185. package/dist/esm/components/Headline/styles.module.css +54 -0
  186. package/dist/esm/components/Headline/types.d.ts +18 -0
  187. package/dist/esm/components/Headline/types.js +1 -0
  188. package/dist/esm/components/PageCatalog/DesktopPageCatalog.d.ts +11 -0
  189. package/dist/esm/components/PageCatalog/DesktopPageCatalog.js +9 -0
  190. package/dist/esm/components/PageCatalog/MobilePageCatalog.d.ts +10 -0
  191. package/dist/esm/components/PageCatalog/MobilePageCatalog.js +9 -0
  192. package/dist/esm/components/PageCatalog/PageCatalog.d.ts +13 -0
  193. package/dist/esm/components/PageCatalog/PageCatalog.js +20 -0
  194. package/dist/esm/components/PageCatalog/index.d.ts +3 -0
  195. package/dist/esm/components/PageCatalog/index.js +3 -0
  196. package/dist/esm/components/PageCatalog/mobileStyles.module.css +15 -0
  197. package/dist/esm/components/PageCatalog/styles.module.css +16 -0
  198. package/dist/esm/components/PageForm/DesktopPageForm.d.ts +5 -0
  199. package/dist/esm/components/PageForm/DesktopPageForm.js +26 -0
  200. package/dist/esm/components/PageForm/MobilePageForm.d.ts +11 -0
  201. package/dist/esm/components/PageForm/MobilePageForm.js +82 -0
  202. package/dist/esm/components/PageForm/PageForm.d.ts +12 -0
  203. package/dist/esm/components/PageForm/PageForm.js +18 -0
  204. package/dist/esm/components/PageForm/hooks.d.ts +22 -0
  205. package/dist/esm/components/PageForm/hooks.js +46 -0
  206. package/dist/esm/components/PageForm/index.d.ts +4 -0
  207. package/dist/esm/components/PageForm/index.js +4 -0
  208. package/dist/esm/components/PageForm/mobileStyles.module.css +75 -0
  209. package/dist/esm/components/PageForm/styles.module.css +104 -0
  210. package/dist/esm/components/PageForm/types.d.ts +47 -0
  211. package/dist/esm/components/PageForm/types.js +1 -0
  212. package/dist/esm/components/PageLoading/PageLoading.d.ts +6 -0
  213. package/dist/esm/components/PageLoading/PageLoading.js +8 -0
  214. package/dist/esm/components/PageLoading/index.d.ts +1 -0
  215. package/dist/esm/components/PageLoading/index.js +1 -0
  216. package/dist/esm/components/PageLoading/styles.module.css +13 -0
  217. package/dist/esm/components/PageServices/DesktopPageServices.d.ts +5 -0
  218. package/dist/esm/components/PageServices/DesktopPageServices.js +12 -0
  219. package/dist/esm/components/PageServices/MobilePageServices.d.ts +12 -0
  220. package/dist/esm/components/PageServices/MobilePageServices.js +10 -0
  221. package/dist/esm/components/PageServices/PageServices.d.ts +14 -0
  222. package/dist/esm/components/PageServices/PageServices.js +21 -0
  223. package/dist/esm/components/PageServices/hooks.d.ts +6 -0
  224. package/dist/esm/components/PageServices/hooks.js +26 -0
  225. package/dist/esm/components/PageServices/index.d.ts +4 -0
  226. package/dist/esm/components/PageServices/index.js +4 -0
  227. package/dist/esm/components/PageServices/mobileStyles.module.css +28 -0
  228. package/dist/esm/components/PageServices/styles.module.css +48 -0
  229. package/dist/esm/components/PageServices/types.d.ts +10 -0
  230. package/dist/esm/components/PageServices/types.js +1 -0
  231. package/dist/esm/components/PageSidebar/PageSidebar.d.ts +21 -0
  232. package/dist/esm/components/PageSidebar/PageSidebar.js +45 -0
  233. package/dist/esm/components/PageSidebar/contexts.d.ts +13 -0
  234. package/dist/esm/components/PageSidebar/contexts.js +16 -0
  235. package/dist/esm/components/PageSidebar/helperComponents/SidebarSearch/SidebarSearch.d.ts +1 -0
  236. package/dist/esm/components/PageSidebar/helperComponents/SidebarSearch/SidebarSearch.js +18 -0
  237. package/dist/esm/components/PageSidebar/helperComponents/SidebarSearch/index.d.ts +1 -0
  238. package/dist/esm/components/PageSidebar/helperComponents/SidebarSearch/index.js +1 -0
  239. package/dist/esm/components/PageSidebar/helperComponents/SidebarSearchToggle/SidebarSearchToggle.d.ts +1 -0
  240. package/dist/esm/components/PageSidebar/helperComponents/SidebarSearchToggle/SidebarSearchToggle.js +18 -0
  241. package/dist/esm/components/PageSidebar/helperComponents/SidebarSearchToggle/index.d.ts +1 -0
  242. package/dist/esm/components/PageSidebar/helperComponents/SidebarSearchToggle/index.js +1 -0
  243. package/dist/esm/components/PageSidebar/helperComponents/SidebarSearchToggle/styles.module.css +4 -0
  244. package/dist/esm/components/PageSidebar/helperComponents/SidebarSelect/SidebarSelect.d.ts +20 -0
  245. package/dist/esm/components/PageSidebar/helperComponents/SidebarSelect/SidebarSelect.js +38 -0
  246. package/dist/esm/components/PageSidebar/helperComponents/SidebarSelect/hooks/index.d.ts +3 -0
  247. package/dist/esm/components/PageSidebar/helperComponents/SidebarSelect/hooks/index.js +3 -0
  248. package/dist/esm/components/PageSidebar/helperComponents/SidebarSelect/hooks/useItemsContent.d.ts +3 -0
  249. package/dist/esm/components/PageSidebar/helperComponents/SidebarSelect/hooks/useItemsContent.js +53 -0
  250. package/dist/esm/components/PageSidebar/helperComponents/SidebarSelect/hooks/useSearchFilter.d.ts +7 -0
  251. package/dist/esm/components/PageSidebar/helperComponents/SidebarSelect/hooks/useSearchFilter.js +36 -0
  252. package/dist/esm/components/PageSidebar/helperComponents/SidebarSelect/hooks/useSelectedItem.d.ts +7 -0
  253. package/dist/esm/components/PageSidebar/helperComponents/SidebarSelect/hooks/useSelectedItem.js +20 -0
  254. package/dist/esm/components/PageSidebar/helperComponents/SidebarSelect/index.d.ts +1 -0
  255. package/dist/esm/components/PageSidebar/helperComponents/SidebarSelect/index.js +1 -0
  256. package/dist/esm/components/PageSidebar/helperComponents/SidebarSelect/styles.module.css +19 -0
  257. package/dist/esm/components/PageSidebar/helperComponents/SidebarSelect/types.d.ts +1 -0
  258. package/dist/esm/components/PageSidebar/helperComponents/SidebarSelect/types.js +1 -0
  259. package/dist/esm/components/PageSidebar/helperComponents/SidebarTitle/SidebarTitle.d.ts +9 -0
  260. package/dist/esm/components/PageSidebar/helperComponents/SidebarTitle/SidebarTitle.js +9 -0
  261. package/dist/esm/components/PageSidebar/helperComponents/SidebarTitle/index.d.ts +1 -0
  262. package/dist/esm/components/PageSidebar/helperComponents/SidebarTitle/index.js +1 -0
  263. package/dist/esm/components/PageSidebar/helperComponents/SidebarTitle/styles.module.css +18 -0
  264. package/dist/esm/components/PageSidebar/hooks/useItemsCreator.d.ts +8 -0
  265. package/dist/esm/components/PageSidebar/hooks/useItemsCreator.js +99 -0
  266. package/dist/esm/components/PageSidebar/hooks/useSearchFilter.d.ts +10 -0
  267. package/dist/esm/components/PageSidebar/hooks/useSearchFilter.js +41 -0
  268. package/dist/esm/components/PageSidebar/index.d.ts +3 -0
  269. package/dist/esm/components/PageSidebar/index.js +3 -0
  270. package/dist/esm/components/PageSidebar/styles.module.css +92 -0
  271. package/dist/esm/components/PageSidebar/types.d.ts +42 -0
  272. package/dist/esm/components/PageSidebar/types.js +1 -0
  273. package/dist/esm/components/TreeNavigation/TreeNavigation.d.ts +2 -0
  274. package/dist/esm/components/TreeNavigation/TreeNavigation.js +21 -0
  275. package/dist/esm/components/TreeNavigation/helperComponents/ConditionalPopover/ConditionalPopover.d.ts +10 -0
  276. package/dist/esm/components/TreeNavigation/helperComponents/ConditionalPopover/ConditionalPopover.js +9 -0
  277. package/dist/esm/components/TreeNavigation/helperComponents/ConditionalPopover/styles.module.css +6 -0
  278. package/dist/esm/components/TreeNavigation/helperComponents/Menu/Menu.d.ts +11 -0
  279. package/dist/esm/components/TreeNavigation/helperComponents/Menu/Menu.js +19 -0
  280. package/dist/esm/components/TreeNavigation/helperComponents/Menu/styles.module.css +12 -0
  281. package/dist/esm/components/TreeNavigation/helperComponents/Menu/utils.d.ts +7 -0
  282. package/dist/esm/components/TreeNavigation/helperComponents/Menu/utils.js +16 -0
  283. package/dist/esm/components/TreeNavigation/helperComponents/index.d.ts +2 -0
  284. package/dist/esm/components/TreeNavigation/helperComponents/index.js +2 -0
  285. package/dist/esm/components/TreeNavigation/index.d.ts +2 -0
  286. package/dist/esm/components/TreeNavigation/index.js +2 -0
  287. package/dist/esm/components/TreeNavigation/styles.module.css +89 -0
  288. package/dist/esm/components/TreeNavigation/types.d.ts +46 -0
  289. package/dist/esm/components/TreeNavigation/types.js +1 -0
  290. package/dist/esm/components/index.d.ts +9 -0
  291. package/dist/esm/components/index.js +9 -0
  292. package/dist/esm/constants.d.ts +57 -0
  293. package/dist/esm/constants.js +50 -0
  294. package/dist/esm/index.d.ts +4 -0
  295. package/dist/esm/index.js +4 -0
  296. package/dist/esm/locale/index.d.ts +112 -0
  297. package/dist/esm/locale/index.js +59 -0
  298. package/dist/esm/style.css +639 -0
  299. package/dist/esm/types.d.ts +7 -0
  300. package/dist/esm/types.js +1 -0
  301. package/dist/tsconfig.cjs.tsbuildinfo +1 -0
  302. package/dist/tsconfig.esm.tsbuildinfo +1 -0
  303. package/package.json +68 -0
  304. package/src/components/Actions/ActionView.tsx +71 -0
  305. package/src/components/Actions/DesktopActions.tsx +33 -0
  306. package/src/components/Actions/MobileActions.tsx +167 -0
  307. package/src/components/Actions/buttons/ButtonDroplist.tsx +43 -0
  308. package/src/components/Actions/buttons/ButtonKebab.tsx +29 -0
  309. package/src/components/Actions/buttons/ButtonQuota.tsx +16 -0
  310. package/src/components/Actions/buttons/index.ts +3 -0
  311. package/src/components/Actions/constants.ts +11 -0
  312. package/src/components/Actions/index.ts +7 -0
  313. package/src/components/Actions/styles.module.scss +34 -0
  314. package/src/components/Actions/types.ts +34 -0
  315. package/src/components/Actions/utils.ts +5 -0
  316. package/src/components/DefaultSubtitle/DefaultSubtitle.tsx +27 -0
  317. package/src/components/DefaultSubtitle/index.ts +1 -0
  318. package/src/components/DefaultSubtitle/styles.module.scss +17 -0
  319. package/src/components/Headline/Headline.tsx +42 -0
  320. package/src/components/Headline/index.ts +2 -0
  321. package/src/components/Headline/styles.module.scss +61 -0
  322. package/src/components/Headline/types.ts +19 -0
  323. package/src/components/PageCatalog/DesktopPageCatalog.tsx +26 -0
  324. package/src/components/PageCatalog/MobilePageCatalog.tsx +36 -0
  325. package/src/components/PageCatalog/PageCatalog.tsx +28 -0
  326. package/src/components/PageCatalog/index.ts +3 -0
  327. package/src/components/PageCatalog/mobileStyles.module.scss +18 -0
  328. package/src/components/PageCatalog/styles.module.scss +21 -0
  329. package/src/components/PageForm/DesktopPageForm.tsx +112 -0
  330. package/src/components/PageForm/MobilePageForm.tsx +187 -0
  331. package/src/components/PageForm/PageForm.tsx +25 -0
  332. package/src/components/PageForm/hooks.tsx +63 -0
  333. package/src/components/PageForm/index.ts +4 -0
  334. package/src/components/PageForm/mobileStyles.module.scss +88 -0
  335. package/src/components/PageForm/styles.module.scss +134 -0
  336. package/src/components/PageForm/types.ts +64 -0
  337. package/src/components/PageLoading/PageLoading.tsx +18 -0
  338. package/src/components/PageLoading/index.ts +1 -0
  339. package/src/components/PageLoading/styles.module.scss +17 -0
  340. package/src/components/PageServices/DesktopPageServices.tsx +55 -0
  341. package/src/components/PageServices/MobilePageServices.tsx +47 -0
  342. package/src/components/PageServices/PageServices.tsx +30 -0
  343. package/src/components/PageServices/hooks.ts +35 -0
  344. package/src/components/PageServices/index.ts +4 -0
  345. package/src/components/PageServices/mobileStyles.module.scss +34 -0
  346. package/src/components/PageServices/styles.module.scss +61 -0
  347. package/src/components/PageServices/types.ts +16 -0
  348. package/src/components/PageSidebar/PageSidebar.tsx +143 -0
  349. package/src/components/PageSidebar/contexts.tsx +30 -0
  350. package/src/components/PageSidebar/helperComponents/SidebarSearch/SidebarSearch.tsx +31 -0
  351. package/src/components/PageSidebar/helperComponents/SidebarSearch/index.ts +1 -0
  352. package/src/components/PageSidebar/helperComponents/SidebarSearchToggle/SidebarSearchToggle.tsx +36 -0
  353. package/src/components/PageSidebar/helperComponents/SidebarSearchToggle/index.ts +1 -0
  354. package/src/components/PageSidebar/helperComponents/SidebarSearchToggle/styles.module.scss +6 -0
  355. package/src/components/PageSidebar/helperComponents/SidebarSelect/SidebarSelect.tsx +91 -0
  356. package/src/components/PageSidebar/helperComponents/SidebarSelect/hooks/index.ts +3 -0
  357. package/src/components/PageSidebar/helperComponents/SidebarSelect/hooks/useItemsContent.tsx +85 -0
  358. package/src/components/PageSidebar/helperComponents/SidebarSelect/hooks/useSearchFilter.tsx +53 -0
  359. package/src/components/PageSidebar/helperComponents/SidebarSelect/hooks/useSelectedItem.tsx +35 -0
  360. package/src/components/PageSidebar/helperComponents/SidebarSelect/index.ts +1 -0
  361. package/src/components/PageSidebar/helperComponents/SidebarSelect/styles.module.scss +20 -0
  362. package/src/components/PageSidebar/helperComponents/SidebarSelect/types.ts +1 -0
  363. package/src/components/PageSidebar/helperComponents/SidebarTitle/SidebarTitle.tsx +33 -0
  364. package/src/components/PageSidebar/helperComponents/SidebarTitle/index.ts +1 -0
  365. package/src/components/PageSidebar/helperComponents/SidebarTitle/styles.module.scss +20 -0
  366. package/src/components/PageSidebar/hooks/useItemsCreator.tsx +161 -0
  367. package/src/components/PageSidebar/hooks/useSearchFilter.tsx +57 -0
  368. package/src/components/PageSidebar/index.ts +3 -0
  369. package/src/components/PageSidebar/styles.module.scss +133 -0
  370. package/src/components/PageSidebar/types.ts +42 -0
  371. package/src/components/TreeNavigation/TreeNavigation.tsx +108 -0
  372. package/src/components/TreeNavigation/helperComponents/ConditionalPopover/ConditionalPopover.tsx +31 -0
  373. package/src/components/TreeNavigation/helperComponents/ConditionalPopover/styles.module.scss +7 -0
  374. package/src/components/TreeNavigation/helperComponents/Menu/Menu.tsx +69 -0
  375. package/src/components/TreeNavigation/helperComponents/Menu/styles.module.scss +17 -0
  376. package/src/components/TreeNavigation/helperComponents/Menu/utils.ts +22 -0
  377. package/src/components/TreeNavigation/helperComponents/index.ts +2 -0
  378. package/src/components/TreeNavigation/index.ts +2 -0
  379. package/src/components/TreeNavigation/styles.module.scss +97 -0
  380. package/src/components/TreeNavigation/types.ts +48 -0
  381. package/src/components/index.ts +9 -0
  382. package/src/constants.ts +56 -0
  383. package/src/index.ts +4 -0
  384. package/src/locale/index.ts +64 -0
  385. package/src/types.ts +15 -0
@@ -0,0 +1,161 @@
1
+ import { ChevronLeftSVG } from '@cloud-ru/ds-icons/interface/system';
2
+ import { ITEM_TYPE, ItemProps } from '@cloud-ru/ds-list';
3
+ import { Tooltip } from '@cloud-ru/ds-tooltip';
4
+ import cn from 'classnames';
5
+ import { MouseEvent, ReactNode, useMemo } from 'react';
6
+
7
+ import { SIDEBAR_HEADER_TYPE, SIDEBAR_ITEM_TYPE } from '../../../constants';
8
+ import { pageLayoutLocale } from '../../../locale';
9
+ import { useSearchContext } from '../contexts';
10
+ import { SidebarSearch } from '../helperComponents/SidebarSearch';
11
+ import { SidebarSearchToggle } from '../helperComponents/SidebarSearchToggle';
12
+ import { SidebarTitle } from '../helperComponents/SidebarTitle';
13
+ import styles from '../styles.module.scss';
14
+ import { HeaderProps, SidebarItem } from '../types';
15
+
16
+ const EMPTY_LIST: ItemProps[] = [];
17
+
18
+ export function useTopPinnedContent(
19
+ header?: HeaderProps,
20
+ hasSearch?: boolean,
21
+ ): { title?: ReactNode; pinTop: ItemProps[] } {
22
+ const { t } = pageLayoutLocale.useTranslations();
23
+ const { searchOpened } = useSearchContext();
24
+
25
+ return useMemo(() => {
26
+ switch (header?.type) {
27
+ case SIDEBAR_HEADER_TYPE.Title:
28
+ return {
29
+ pinTop: [
30
+ {
31
+ // Кнопка поиска живёт в `content` рядом с заголовком/полем, а не в `afterContent`:
32
+ // отдельный слот `afterContent` центрируется по-своему и ломает вертикальное
33
+ // выравнивание кнопки с полем.
34
+ content: (
35
+ <div
36
+ className={cn(styles.pinnedHeaderSlot, hasSearch && searchOpened && styles.pinnedHeaderSlotSearch)}
37
+ >
38
+ <div className={styles.pinnedHeaderContent}>
39
+ {
40
+ // При открытом поиске строка заголовка заменяется полем поиска (без наложения).
41
+ hasSearch && searchOpened ? (
42
+ <SidebarSearch />
43
+ ) : (
44
+ <SidebarTitle title={header.label} icon={header.icon} afterContent={header.afterContent} />
45
+ )
46
+ }
47
+ </div>
48
+ {hasSearch && <SidebarSearchToggle />}
49
+ </div>
50
+ ),
51
+ inactive: true,
52
+ },
53
+ ],
54
+ };
55
+ case SIDEBAR_HEADER_TYPE.Back:
56
+ return {
57
+ pinTop: [
58
+ {
59
+ content: { label: `${t('PageSidebar.backTo')} ${header.label}` },
60
+ beforeContent: <ChevronLeftSVG />,
61
+ onClick: header.href ? undefined : header.onClick,
62
+ itemWrapRender: header.href
63
+ ? item => (
64
+ <a href={header.href} onClick={header.onClick}>
65
+ {item}
66
+ </a>
67
+ )
68
+ : undefined,
69
+ },
70
+ ],
71
+ };
72
+ default:
73
+ return { pinTop: EMPTY_LIST };
74
+ }
75
+ }, [header, t, hasSearch, searchOpened]);
76
+ }
77
+
78
+ export function useItemsContent(items: SidebarItem[], onSelect?: (id: string | number) => void): ItemProps[] {
79
+ return useMemo(() => {
80
+ const getItemsContent = (items: SidebarItem[], onSelect?: (id: string | number) => void) =>
81
+ items.map(
82
+ ({
83
+ id,
84
+ label,
85
+ beforeContent,
86
+ onClick,
87
+ afterContent,
88
+ disabledReason,
89
+ disabledReasonPlacement,
90
+ ...rest
91
+ }): ItemProps => {
92
+ const href = 'href' in rest ? rest.href : undefined;
93
+ const newItems = 'items' in rest ? rest.items : undefined;
94
+ const type = 'type' in rest ? rest.type : undefined;
95
+
96
+ const clickHandler = (event: MouseEvent<HTMLElement>) => {
97
+ if (href && (event?.metaKey || event?.button === 1)) {
98
+ return;
99
+ }
100
+
101
+ event.preventDefault();
102
+ onClick?.(event);
103
+ onSelect?.(id);
104
+ };
105
+
106
+ if (type === SIDEBAR_ITEM_TYPE.Group) {
107
+ return {
108
+ ...rest,
109
+ label,
110
+ type: ITEM_TYPE.Group,
111
+ items: getItemsContent(newItems || [], onSelect),
112
+ };
113
+ }
114
+
115
+ const newItem = {
116
+ id,
117
+ content: { label: label },
118
+ itemWrapRender: (item: ReactNode) => {
119
+ if (!disabledReason) {
120
+ return href ? (
121
+ <a href={href} onClick={clickHandler}>
122
+ {item}
123
+ </a>
124
+ ) : (
125
+ item
126
+ );
127
+ }
128
+
129
+ return (
130
+ <Tooltip
131
+ hoverDelayOpen={500}
132
+ open={disabledReason ? undefined : false}
133
+ tip={disabledReason}
134
+ placement={disabledReasonPlacement}
135
+ >
136
+ {item}
137
+ </Tooltip>
138
+ );
139
+ },
140
+
141
+ onClick: href ? undefined : clickHandler,
142
+ beforeContent,
143
+ afterContent,
144
+ disabled: Boolean(disabledReason),
145
+ };
146
+
147
+ if (newItems?.length) {
148
+ return {
149
+ ...newItem,
150
+ type: ITEM_TYPE.Collapse,
151
+ items: getItemsContent(newItems || [], onSelect),
152
+ };
153
+ }
154
+
155
+ return newItem;
156
+ },
157
+ );
158
+
159
+ return getItemsContent(items, onSelect);
160
+ }, [items, onSelect]);
161
+ }
@@ -0,0 +1,57 @@
1
+ import { useMemo } from 'react';
2
+
3
+ import { useSearchContext } from '../contexts';
4
+ import { SidebarItem } from '../types';
5
+
6
+ const matchString = (value: string, searchValue: string) =>
7
+ value.trim().toLowerCase().includes(searchValue.trim().toLowerCase());
8
+
9
+ const filterService = (servicesList: SidebarItem[], searchValue: string): SidebarItem[] => {
10
+ if (!searchValue) return servicesList;
11
+
12
+ return servicesList.reduce((result, service) => {
13
+ if (service.label && matchString(service.label, searchValue)) {
14
+ result.push(service);
15
+ return result;
16
+ }
17
+
18
+ if ('items' in service && service.items?.length) {
19
+ const items = filterService(service.items, searchValue);
20
+
21
+ if (items.length) {
22
+ result.push({ ...service, items });
23
+ }
24
+
25
+ return result;
26
+ }
27
+
28
+ return result;
29
+ }, [] as SidebarItem[]);
30
+ };
31
+
32
+ const getSidebarItemIds = (list: SidebarItem[]): (string | number)[] =>
33
+ list.reduce(
34
+ (result, el) => {
35
+ result.push(el.id);
36
+ if ('items' in el && el.items?.length) {
37
+ const childItems = getSidebarItemIds(el.items);
38
+ result.push(...childItems);
39
+ }
40
+ return result;
41
+ },
42
+ [] as (string | number)[],
43
+ );
44
+
45
+ export const useSearchFilter = (list: SidebarItem[]) => {
46
+ const { searchValue, setSearchValue, searchOpened } = useSearchContext();
47
+ const filteredList = useMemo(() => filterService(list, searchValue), [list, searchValue]);
48
+ const searchCollapseState = useMemo(() => ({ value: getSidebarItemIds(filteredList) }), [filteredList]);
49
+
50
+ return {
51
+ searchOpened,
52
+ searchValue,
53
+ setSearchValue,
54
+ filteredList,
55
+ searchCollapseState,
56
+ };
57
+ };
@@ -0,0 +1,3 @@
1
+ export * from './PageSidebar';
2
+ export * from './helperComponents/SidebarSelect';
3
+ export * from './types';
@@ -0,0 +1,133 @@
1
+ @use '@cloud-ru/ds-figma-variables/build/scss/styles/styles.module' as base;
2
+
3
+ // Ширина сайдбара 256px — фиксированный layout-размер из Figma-мастера, токена нет.
4
+ $width: 256px;
5
+ // Ширина hover-ловушки слева от свёрнутого сайдбара.
6
+ $catcherWidth: base.$sn-primitive-dimension-4;
7
+ // Тайминги slide-анимации — анимационные литералы, токенов нет.
8
+ $instantAnimation: left 0.15s ease-in-out;
9
+ $delayedAnimation: left 0.15s 0.35s ease-in-out;
10
+
11
+ .wrapper {
12
+ width: $width;
13
+
14
+ &[data-collapsed] {
15
+ width: 0;
16
+ }
17
+
18
+ .body {
19
+ position: absolute;
20
+
21
+ display: flex;
22
+
23
+ width: $width;
24
+ height: 100%;
25
+
26
+ transition: $delayedAnimation;
27
+
28
+ &[data-hover-off] {
29
+ pointer-events: none;
30
+ transition: $instantAnimation;
31
+ }
32
+
33
+ &[data-collapsed] {
34
+ left: calc(-1 * $width);
35
+
36
+ &::before {
37
+ content: ' ';
38
+
39
+ position: absolute;
40
+ right: calc(-1 * $catcherWidth);
41
+
42
+ width: $catcherWidth;
43
+ height: 100%;
44
+ }
45
+
46
+ &:hover {
47
+ left: 0;
48
+ transition: $instantAnimation;
49
+
50
+ &::before {
51
+ right: calc(-4 * $catcherWidth);
52
+ width: calc(4 * $catcherWidth);
53
+ }
54
+ }
55
+ }
56
+ }
57
+
58
+ .content {
59
+ overflow: hidden;
60
+ display: flex;
61
+ flex-direction: column;
62
+ flex-grow: 1;
63
+
64
+ box-sizing: border-box;
65
+ padding: base.$sn-primitive-dimension-4 0;
66
+ // Правый разделитель = stateLayer/borderOnBackground color.
67
+ border-right: base.$sn-primitive-strokeWeight-strokeRegular solid
68
+ base.$sn-theme-color-material-stateLayer-neutral-border-default-borderColor;
69
+
70
+ background-color: base.$sn-theme-color-neutral-background;
71
+
72
+ // Правило сравнивает этот селектор с `.body:hover` выше, хотя это разные элементы
73
+ // (`.content` и `.body`) и каскад между ними невозможен.
74
+ // stylelint-disable-next-line no-descending-specificity
75
+ &[data-collapsed] {
76
+ margin: base.$sn-primitive-dimension-4;
77
+ border-right: none;
78
+ box-shadow: base.$sn-boxShadow-elevation-level3;
79
+ }
80
+ }
81
+
82
+ .list {
83
+ position: relative;
84
+
85
+ overflow-y: auto;
86
+ display: flex;
87
+ flex-direction: column-reverse;
88
+ flex-grow: 1;
89
+ flex-shrink: 1;
90
+ }
91
+
92
+ .toggler {
93
+ display: flex;
94
+ flex-grow: 0;
95
+ flex-shrink: 0;
96
+ justify-content: end;
97
+
98
+ padding: 0 base.$sn-primitive-dimension-4;
99
+ }
100
+
101
+ .expandButton {
102
+ position: fixed;
103
+ bottom: base.$sn-primitive-dimension-8;
104
+ left: base.$sn-primitive-dimension-8;
105
+ }
106
+ }
107
+
108
+ .button {
109
+ background-color: base.$sn-theme-color-neutral-background2Level;
110
+ }
111
+
112
+ // Высота строки шапки 48px. 44 − 1px: разделитель-полоску listItemGroup (1px)
113
+ // добавляет сверху хост @cloud-ru/ds-list.
114
+ .pinnedHeaderSlot {
115
+ display: flex;
116
+ flex-direction: row;
117
+ gap: base.$sn-primitive-dimension-8;
118
+ align-items: center;
119
+
120
+ min-height: calc(base.$sn-primitive-dimension-44 - base.$sn-primitive-strokeWeight-strokeRegular);
121
+ }
122
+
123
+ .pinnedHeaderContent {
124
+ display: flex;
125
+ flex-grow: 1;
126
+ min-width: 0;
127
+ }
128
+
129
+ // Инсет под focus-outline поля: строка списка держит overflow: hidden и обрезала бы
130
+ // рамку по краям. Только для поиска — иконка заголовка остаётся выровнена с навигацией.
131
+ .pinnedHeaderSlotSearch {
132
+ padding-inline: base.$sn-primitive-dimension-4;
133
+ }
@@ -0,0 +1,42 @@
1
+ import { IconPredefinedProps } from '@cloud-ru/ds-icon-predefined';
2
+ import { TooltipProps } from '@cloud-ru/ds-tooltip';
3
+ import { AnchorHTMLAttributes, MouseEvent, MouseEventHandler, ReactNode } from 'react';
4
+
5
+ import { SIDEBAR_HEADER_TYPE } from '../../constants';
6
+ import { SidebarItemType } from '../../types';
7
+
8
+ export type SidebarItemBase = {
9
+ id: string | number;
10
+ label: string;
11
+ 'data-test-id'?: string;
12
+ onClick?(e: MouseEvent<HTMLElement>): void;
13
+ afterContent?: ReactNode;
14
+ disabledReason?: ReactNode;
15
+ disabledReasonPlacement?: TooltipProps['placement'];
16
+ beforeContent?: ReactNode;
17
+ };
18
+
19
+ export type SidebarItemWithHref = SidebarItemBase & {
20
+ href: string;
21
+ };
22
+
23
+ export type SidebarItemWithItems = SidebarItemBase & {
24
+ /** @default collapse */
25
+ type?: SidebarItemType;
26
+ divider?: boolean;
27
+ items?: SidebarItem[];
28
+ };
29
+
30
+ export type SidebarItem = SidebarItemWithHref | SidebarItemWithItems;
31
+
32
+ export type Icon = IconPredefinedProps['icon'];
33
+
34
+ export type HeaderProps =
35
+ | { type: typeof SIDEBAR_HEADER_TYPE.Title; label: string; icon: Icon; afterContent?: ReactNode }
36
+ | { type: typeof SIDEBAR_HEADER_TYPE.Back; label: string; href?: string; onClick?: MouseEventHandler };
37
+
38
+ export type Documentation = {
39
+ href?: string;
40
+ onClick?: MouseEventHandler;
41
+ target?: AnchorHTMLAttributes<HTMLAnchorElement>['target'];
42
+ };
@@ -0,0 +1,108 @@
1
+ import { APPEARANCE, Button, SIZE, VIEW } from '@cloud-ru/ds-button';
2
+ import { BurgerSVG, CloseSVG } from '@cloud-ru/ds-icons/interface/product';
3
+ import { Status } from '@cloud-ru/ds-status';
4
+ import { SIZE as TYPOGRAPHY_SIZE, Typography, VARIANT } from '@cloud-ru/ds-typography';
5
+ import { useUncontrolledProp } from '@cloud-ru/ds-utils';
6
+ import cn from 'classnames';
7
+ import { useMemo } from 'react';
8
+
9
+ import { TREE_NAVIGATION_MODE } from '../../constants';
10
+ import { pageLayoutLocale } from '../../locale';
11
+ import { ConditionalPopover, Menu } from './helperComponents';
12
+ import styles from './styles.module.scss';
13
+ import { TreeNavigationProps } from './types';
14
+
15
+ export function TreeNavigation({
16
+ header: { title, icon, description, status, actions },
17
+ menu: {
18
+ menuTitle,
19
+ items,
20
+ enableShrinkMenuButton,
21
+ withDefaultOpenedMenuList,
22
+ isMenuOpen,
23
+ defaultMenuOpened,
24
+ onMenuToggle,
25
+ selected,
26
+ onSelect,
27
+ },
28
+ content,
29
+ mode,
30
+ contentClassName,
31
+ }: TreeNavigationProps) {
32
+ const [open, setOpen] = useUncontrolledProp(isMenuOpen, defaultMenuOpened, onMenuToggle);
33
+ const { t } = pageLayoutLocale.useTranslations();
34
+
35
+ // В режиме `fixed` aside-меню всегда раскрыто, переключатель неактуален.
36
+ const isFixed = mode === TREE_NAVIGATION_MODE.Fixed;
37
+ const isAsideOpen = isFixed || (mode === TREE_NAVIGATION_MODE.Aside && Boolean(open));
38
+
39
+ const menu = useMemo(
40
+ () => (
41
+ <Menu
42
+ menuItems={items}
43
+ menuTitle={menuTitle}
44
+ enableShrinkMenuButton={enableShrinkMenuButton}
45
+ withDefaultOpenedMenuList={withDefaultOpenedMenuList}
46
+ selected={selected}
47
+ onSelect={onSelect}
48
+ />
49
+ ),
50
+ [onSelect, selected, items, menuTitle, enableShrinkMenuButton, withDefaultOpenedMenuList],
51
+ );
52
+
53
+ return (
54
+ <div className={styles.root}>
55
+ <div className={styles.header}>
56
+ <div className={styles.titleWrapper}>
57
+ <div className={styles.titleInner}>
58
+ {!isFixed && (
59
+ <ConditionalPopover
60
+ isOpen={Boolean(open)}
61
+ onOpenChange={setOpen}
62
+ tip={menu}
63
+ withPopover={mode === TREE_NAVIGATION_MODE.Popover}
64
+ >
65
+ <div className={styles.innerElement}>
66
+ <Button
67
+ view={VIEW.Simple}
68
+ appearance={APPEARANCE.Neutral}
69
+ size={SIZE.S}
70
+ aria-label={open ? t('TreeNavigation.closeMenu') : t('TreeNavigation.openMenu')}
71
+ icon={open ? <CloseSVG /> : <BurgerSVG />}
72
+ onClick={() => setOpen(!open)}
73
+ />
74
+ </div>
75
+ </ConditionalPopover>
76
+ )}
77
+ {icon && (
78
+ <div className={styles.innerElement}>
79
+ <div className={styles.icon}>{icon}</div>
80
+ </div>
81
+ )}
82
+ <Typography variant={VARIANT.title} size={TYPOGRAPHY_SIZE.l} className={styles.title}>
83
+ {title}
84
+ </Typography>
85
+
86
+ {status && (
87
+ <div className={styles.innerElement}>
88
+ <Status {...status} />
89
+ </div>
90
+ )}
91
+ </div>
92
+ {description && (
93
+ <Typography variant={VARIANT.body} size={TYPOGRAPHY_SIZE.s} className={styles.description}>
94
+ {description}
95
+ </Typography>
96
+ )}
97
+ </div>
98
+
99
+ {actions && <div className={styles.headerActions}>{actions}</div>}
100
+ </div>
101
+
102
+ <div className={styles.body}>
103
+ {isAsideOpen && <aside className={styles.sidebar}>{menu}</aside>}
104
+ <div className={cn(styles.main, contentClassName)}>{content}</div>
105
+ </div>
106
+ </div>
107
+ );
108
+ }
@@ -0,0 +1,31 @@
1
+ import { PLACEMENT, Popover, TRIGGER } from '@cloud-ru/ds-popover';
2
+ import { ReactNode } from 'react';
3
+
4
+ import styles from './styles.module.scss';
5
+
6
+ type ConditionalPopoverProps = {
7
+ isOpen: boolean;
8
+ onOpenChange(value: boolean): void;
9
+ tip: ReactNode;
10
+ withPopover?: boolean;
11
+ children: ReactNode;
12
+ };
13
+
14
+ export function ConditionalPopover({ tip, withPopover, isOpen, onOpenChange, children }: ConditionalPopoverProps) {
15
+ if (withPopover) {
16
+ return (
17
+ <Popover
18
+ className={styles.popover}
19
+ open={isOpen}
20
+ onOpenChange={nextOpen => onOpenChange(nextOpen)}
21
+ content={tip}
22
+ trigger={TRIGGER.Click}
23
+ placement={PLACEMENT.BottomStart}
24
+ >
25
+ {children}
26
+ </Popover>
27
+ );
28
+ }
29
+
30
+ return children;
31
+ }
@@ -0,0 +1,7 @@
1
+ .popover {
2
+ max-height: 80%;
3
+
4
+ & > div {
5
+ overflow: auto;
6
+ }
7
+ }
@@ -0,0 +1,69 @@
1
+ import { APPEARANCE, Button, VIEW } from '@cloud-ru/ds-button';
2
+ import { HorizontalMenuCloseSVG, HorizontalMenuOpenSVG } from '@cloud-ru/ds-icons/interface/product';
3
+ import { Tree, TreeNodeId, TreeNodeProps } from '@cloud-ru/ds-tree';
4
+ import { SIZE, Typography, VARIANT } from '@cloud-ru/ds-typography';
5
+ import { useMemo, useState } from 'react';
6
+
7
+ import { pageLayoutLocale } from '../../../../locale';
8
+ import styles from './styles.module.scss';
9
+ import { getExpandedNodes } from './utils';
10
+
11
+ type MenuProps = {
12
+ menuTitle?: string;
13
+ menuItems: TreeNodeProps[];
14
+ enableShrinkMenuButton?: boolean;
15
+ withDefaultOpenedMenuList?: boolean;
16
+ selected?: TreeNodeId;
17
+ onSelect?(selectedKey: TreeNodeId | undefined, node: TreeNodeProps): void;
18
+ };
19
+
20
+ export function Menu({
21
+ menuTitle,
22
+ menuItems,
23
+ enableShrinkMenuButton = true,
24
+ withDefaultOpenedMenuList,
25
+ selected,
26
+ onSelect,
27
+ }: MenuProps) {
28
+ const { t } = pageLayoutLocale.useTranslations();
29
+ const allExpandedNodes = useMemo(() => getExpandedNodes(menuItems), [menuItems]);
30
+
31
+ const [expandedNodes, setExpandedNodes] = useState<string[]>(withDefaultOpenedMenuList ? allExpandedNodes : []);
32
+
33
+ const isExpanded = expandedNodes.length > 0;
34
+
35
+ const handleExpandAll = () => setExpandedNodes(getExpandedNodes(menuItems));
36
+ const handleCollapseAll = () => setExpandedNodes([]);
37
+
38
+ const showSubheader = Boolean(menuTitle || enableShrinkMenuButton);
39
+
40
+ return (
41
+ <div className={styles.sidebar}>
42
+ {showSubheader && (
43
+ <div className={styles.subheader}>
44
+ <Typography variant={VARIANT.title} size={SIZE.m}>
45
+ {menuTitle}
46
+ </Typography>
47
+ {enableShrinkMenuButton && (
48
+ <Button
49
+ view={VIEW.Simple}
50
+ appearance={APPEARANCE.Neutral}
51
+ label={isExpanded ? t('TreeNavigation.collapseAll') : t('TreeNavigation.expandAll')}
52
+ icon={isExpanded ? <HorizontalMenuCloseSVG /> : <HorizontalMenuOpenSVG />}
53
+ onClick={isExpanded ? handleCollapseAll : handleExpandAll}
54
+ />
55
+ )}
56
+ </div>
57
+ )}
58
+
59
+ <Tree
60
+ data={menuItems}
61
+ selectionMode='single'
62
+ expandedNodes={expandedNodes}
63
+ onExpand={setExpandedNodes}
64
+ selected={selected}
65
+ onSelect={onSelect}
66
+ />
67
+ </div>
68
+ );
69
+ }
@@ -0,0 +1,17 @@
1
+ @use '@cloud-ru/ds-figma-variables/build/scss/styles/styles.module' as base;
2
+
3
+ // Ширина меню 292px (общая 324px из-за 16px paddings родителя) — layout-литерал из Figma-мастера.
4
+ $sidebar-width: 292px;
5
+
6
+ .sidebar {
7
+ display: flex;
8
+ flex-direction: column;
9
+ gap: base.$sn-primitive-dimension-12;
10
+ min-width: $sidebar-width;
11
+ }
12
+
13
+ .subheader {
14
+ display: flex;
15
+ align-items: center;
16
+ justify-content: space-between;
17
+ }
@@ -0,0 +1,22 @@
1
+ import { TreeNodeProps } from '@cloud-ru/ds-tree';
2
+
3
+ /**
4
+ * Рекурсивно собирает все ID узлов дерева для их разворачивания
5
+ * @param nodes - Массив узлов дерева
6
+ * @returns Массив ID всех узлов (включая вложенные)
7
+ */
8
+ export const getExpandedNodes = (nodes: TreeNodeProps[]): string[] => {
9
+ if (!nodes || nodes.length === 0) {
10
+ return [];
11
+ }
12
+
13
+ const ids: string[] = [];
14
+
15
+ nodes.forEach(el => {
16
+ const children = 'nested' in el && el.nested ? getExpandedNodes(el.nested) : [];
17
+
18
+ ids.push(el.id, ...children);
19
+ });
20
+
21
+ return ids;
22
+ };
@@ -0,0 +1,2 @@
1
+ export * from './Menu/Menu';
2
+ export * from './ConditionalPopover/ConditionalPopover';
@@ -0,0 +1,2 @@
1
+ export * from './TreeNavigation';
2
+ export * from './types';