@gravity-ui/navigation 6.5.1 → 7.0.0-beta.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 (298) hide show
  1. package/build/cjs/components/AsideHeader/AsideHeader.css +9 -1
  2. package/build/cjs/components/AsideHeader/AsideHeader.js +2 -2
  3. package/build/cjs/components/AsideHeader/AsideHeader.js.map +1 -1
  4. package/build/cjs/components/AsideHeader/AsideHeader.module.scss.js +1 -1
  5. package/build/cjs/components/AsideHeader/AsideHeaderContext.d.ts +5 -0
  6. package/build/cjs/components/AsideHeader/AsideHeaderContext.js +2 -0
  7. package/build/cjs/components/AsideHeader/AsideHeaderContext.js.map +1 -1
  8. package/build/cjs/components/AsideHeader/__playwright__/AsideTransitionExample.d.ts +8 -0
  9. package/build/cjs/components/AsideHeader/__playwright__/CollapseButtonExample.d.ts +14 -0
  10. package/build/cjs/components/AsideHeader/__playwright__/CompactTransitionExample.d.ts +12 -0
  11. package/build/cjs/components/AsideHeader/__playwright__/CurrentIndicatorExample.d.ts +20 -0
  12. package/build/cjs/components/AsideHeader/__playwright__/QuickAccessOverflowExample.d.ts +8 -0
  13. package/build/cjs/components/AsideHeader/__playwright__/currentIndicatorPaint.d.ts +21 -0
  14. package/build/cjs/components/AsideHeader/__playwright__/transitionTestUtils.d.ts +4 -0
  15. package/build/cjs/components/AsideHeader/__stories__/fullNavigationMoc.d.ts +6 -0
  16. package/build/cjs/components/AsideHeader/components/AllPagesPanel/AllPagesListItem/AllPagesListItem.js +2 -4
  17. package/build/cjs/components/AsideHeader/components/AllPagesPanel/AllPagesListItem/AllPagesListItem.js.map +1 -1
  18. package/build/cjs/components/AsideHeader/components/AllPagesPanel/allPagesEditDisplay.d.ts +2 -1
  19. package/build/cjs/components/AsideHeader/components/AllPagesPanel/allPagesEditDisplay.js +5 -1
  20. package/build/cjs/components/AsideHeader/components/AllPagesPanel/allPagesEditDisplay.js.map +1 -1
  21. package/build/cjs/components/AsideHeader/components/AllPagesPanel/i18n/en.json.js +1 -3
  22. package/build/cjs/components/AsideHeader/components/AllPagesPanel/i18n/en.json.js.map +1 -1
  23. package/build/cjs/components/AsideHeader/components/AllPagesPanel/i18n/index.d.ts +4 -4
  24. package/build/cjs/components/AsideHeader/components/AllPagesPanel/i18n/ru.json.js +2 -4
  25. package/build/cjs/components/AsideHeader/components/AllPagesPanel/i18n/ru.json.js.map +1 -1
  26. package/build/cjs/components/AsideHeader/components/AsideDivider.d.ts +7 -0
  27. package/build/cjs/components/AsideHeader/components/AsideDivider.js +13 -0
  28. package/build/cjs/components/AsideHeader/components/AsideDivider.js.map +1 -0
  29. package/build/cjs/components/AsideHeader/components/CollapseButton/CollapseButton.css +1 -1
  30. package/build/cjs/components/AsideHeader/components/CollapseButton/CollapseButton.d.ts +3 -1
  31. package/build/cjs/components/AsideHeader/components/CollapseButton/CollapseButton.js +12 -8
  32. package/build/cjs/components/AsideHeader/components/CollapseButton/CollapseButton.js.map +1 -1
  33. package/build/cjs/components/AsideHeader/components/CollapseButton/CollapseButton.module.scss.js +1 -1
  34. package/build/cjs/components/AsideHeader/components/CollapseButton/useCollapseAnchor.d.ts +20 -0
  35. package/build/cjs/components/AsideHeader/components/CollapseButton/useCollapseAnchor.js +170 -0
  36. package/build/cjs/components/AsideHeader/components/CollapseButton/useCollapseAnchor.js.map +1 -0
  37. package/build/cjs/components/AsideHeader/components/CompositeBar/CompositeBar.css +3 -1
  38. package/build/cjs/components/AsideHeader/components/CompositeBar/CompositeBar.d.ts +13 -2
  39. package/build/cjs/components/AsideHeader/components/CompositeBar/CompositeBar.js +53 -39
  40. package/build/cjs/components/AsideHeader/components/CompositeBar/CompositeBar.js.map +1 -1
  41. package/build/cjs/components/AsideHeader/components/CompositeBar/CompositeBar.module.scss.js +1 -1
  42. package/build/cjs/components/AsideHeader/components/CompositeBar/HighlightedItem/HighlightedItem.css +1 -1
  43. package/build/cjs/components/AsideHeader/components/CompositeBar/HighlightedItem/HighlightedItem.js +4 -2
  44. package/build/cjs/components/AsideHeader/components/CompositeBar/HighlightedItem/HighlightedItem.js.map +1 -1
  45. package/build/cjs/components/AsideHeader/components/CompositeBar/Item/Item.css +33 -1
  46. package/build/cjs/components/AsideHeader/components/CompositeBar/Item/Item.js +158 -43
  47. package/build/cjs/components/AsideHeader/components/CompositeBar/Item/Item.js.map +1 -1
  48. package/build/cjs/components/AsideHeader/components/CompositeBar/Item/Item.module.scss.js +1 -1
  49. package/build/cjs/components/AsideHeader/components/CompositeBar/Item/Item.types.d.ts +22 -4
  50. package/build/cjs/components/AsideHeader/components/CompositeBar/Item/ItemPopup.d.ts +19 -0
  51. package/build/cjs/components/AsideHeader/components/CompositeBar/Item/ItemPopup.js +137 -20
  52. package/build/cjs/components/AsideHeader/components/CompositeBar/Item/ItemPopup.js.map +1 -1
  53. package/build/cjs/components/AsideHeader/components/CompositeBar/Item/ItemQuickAccessPin.d.ts +7 -0
  54. package/build/cjs/components/AsideHeader/components/CompositeBar/Item/ItemQuickAccessPin.js +25 -0
  55. package/build/cjs/components/AsideHeader/components/CompositeBar/Item/ItemQuickAccessPin.js.map +1 -0
  56. package/build/cjs/components/AsideHeader/components/CompositeBar/Item/renderItemTitle.d.ts +1 -1
  57. package/build/cjs/components/AsideHeader/components/CompositeBar/Item/renderItemTitle.js +5 -1
  58. package/build/cjs/components/AsideHeader/components/CompositeBar/Item/renderItemTitle.js.map +1 -1
  59. package/build/cjs/components/AsideHeader/components/CompositeBar/ScrollableWithScrollbar/ScrollableWithScrollbar.css +1 -1
  60. package/build/cjs/components/AsideHeader/components/CompositeBar/ScrollableWithScrollbar/ScrollableWithScrollbar.d.ts +4 -6
  61. package/build/cjs/components/AsideHeader/components/CompositeBar/ScrollableWithScrollbar/ScrollableWithScrollbar.js +14 -5
  62. package/build/cjs/components/AsideHeader/components/CompositeBar/ScrollableWithScrollbar/ScrollableWithScrollbar.js.map +1 -1
  63. package/build/cjs/components/AsideHeader/components/CompositeBar/ScrollableWithScrollbar/ScrollableWithScrollbar.module.scss.js +1 -1
  64. package/build/cjs/components/AsideHeader/components/CompositeBar/ScrollableWithScrollbar/useScrollableScrollbarSync.d.ts +8 -8
  65. package/build/cjs/components/AsideHeader/components/CompositeBar/ScrollableWithScrollbar/useScrollableScrollbarSync.js +68 -33
  66. package/build/cjs/components/AsideHeader/components/CompositeBar/ScrollableWithScrollbar/useScrollableScrollbarSync.js.map +1 -1
  67. package/build/cjs/components/AsideHeader/components/CompositeBar/constants.d.ts +1 -0
  68. package/build/cjs/components/AsideHeader/components/CompositeBar/constants.js +2 -0
  69. package/build/cjs/components/AsideHeader/components/CompositeBar/constants.js.map +1 -1
  70. package/build/cjs/components/AsideHeader/components/CompositeBar/presentationCurrent.d.ts +24 -0
  71. package/build/cjs/components/AsideHeader/components/CompositeBar/presentationCurrent.js +39 -0
  72. package/build/cjs/components/AsideHeader/components/CompositeBar/presentationCurrent.js.map +1 -0
  73. package/build/cjs/components/AsideHeader/components/CompositeBar/utils.d.ts +12 -7
  74. package/build/cjs/components/AsideHeader/components/CompositeBar/utils.js +42 -35
  75. package/build/cjs/components/AsideHeader/components/CompositeBar/utils.js.map +1 -1
  76. package/build/cjs/components/AsideHeader/components/FirstPanel.js +129 -10
  77. package/build/cjs/components/AsideHeader/components/FirstPanel.js.map +1 -1
  78. package/build/cjs/components/AsideHeader/components/FooterItem/FooterItem.css +1 -1
  79. package/build/cjs/components/AsideHeader/components/FooterItem/FooterItem.js +18 -2
  80. package/build/cjs/components/AsideHeader/components/FooterItem/FooterItem.js.map +1 -1
  81. package/build/cjs/components/AsideHeader/components/FooterItem/FooterItem.module.scss.js +1 -1
  82. package/build/cjs/components/AsideHeader/components/Header.js +7 -3
  83. package/build/cjs/components/AsideHeader/components/Header.js.map +1 -1
  84. package/build/cjs/components/AsideHeader/components/PageLayout/AsideFallback.css +9 -1
  85. package/build/cjs/components/AsideHeader/components/PageLayout/AsideFallback.d.ts +1 -0
  86. package/build/cjs/components/AsideHeader/components/PageLayout/AsideFallback.js +13 -6
  87. package/build/cjs/components/AsideHeader/components/PageLayout/AsideFallback.js.map +1 -1
  88. package/build/cjs/components/AsideHeader/components/PageLayout/AsideLayoutTransition.d.ts +80 -0
  89. package/build/cjs/components/AsideHeader/components/PageLayout/AsideLayoutTransition.js +600 -0
  90. package/build/cjs/components/AsideHeader/components/PageLayout/AsideLayoutTransition.js.map +1 -0
  91. package/build/cjs/components/AsideHeader/components/PageLayout/CurrentIndicatorTransition.d.ts +14 -0
  92. package/build/cjs/components/AsideHeader/components/PageLayout/CurrentIndicatorTransition.js +164 -0
  93. package/build/cjs/components/AsideHeader/components/PageLayout/CurrentIndicatorTransition.js.map +1 -0
  94. package/build/cjs/components/AsideHeader/components/PageLayout/CurrentPresentationObserver.d.ts +14 -0
  95. package/build/cjs/components/AsideHeader/components/PageLayout/CurrentPresentationObserver.js +94 -0
  96. package/build/cjs/components/AsideHeader/components/PageLayout/CurrentPresentationObserver.js.map +1 -0
  97. package/build/cjs/components/AsideHeader/components/PageLayout/PageLayout.css +9 -1
  98. package/build/cjs/components/AsideHeader/components/PageLayout/PageLayout.d.ts +1 -1
  99. package/build/cjs/components/AsideHeader/components/PageLayout/PageLayout.js +14 -5
  100. package/build/cjs/components/AsideHeader/components/PageLayout/PageLayout.js.map +1 -1
  101. package/build/cjs/components/AsideHeader/components/PageLayout/PageLayoutAside.css +9 -1
  102. package/build/cjs/components/AsideHeader/components/PageLayout/PageLayoutAside.d.ts +1 -1
  103. package/build/cjs/components/AsideHeader/components/PageLayout/PageLayoutAside.js +5 -2
  104. package/build/cjs/components/AsideHeader/components/PageLayout/PageLayoutAside.js.map +1 -1
  105. package/build/cjs/components/AsideHeader/components/PageLayout/currentIndicatorDom.d.ts +7 -0
  106. package/build/cjs/components/AsideHeader/components/PageLayout/currentIndicatorDom.js +25 -0
  107. package/build/cjs/components/AsideHeader/components/PageLayout/currentIndicatorDom.js.map +1 -0
  108. package/build/cjs/components/AsideHeader/components/PageLayout/currentIndicatorModel.d.ts +25 -0
  109. package/build/cjs/components/AsideHeader/components/PageLayout/currentIndicatorModel.js +89 -0
  110. package/build/cjs/components/AsideHeader/components/PageLayout/currentIndicatorModel.js.map +1 -0
  111. package/build/cjs/components/AsideHeader/components/Panels.js +2 -2
  112. package/build/cjs/components/AsideHeader/components/Panels.js.map +1 -1
  113. package/build/cjs/components/AsideHeader/density.d.ts +21 -0
  114. package/build/cjs/components/AsideHeader/density.js +61 -0
  115. package/build/cjs/components/AsideHeader/density.js.map +1 -0
  116. package/build/cjs/components/AsideHeader/i18n/__mocks__/index.d.ts +1 -0
  117. package/build/cjs/components/AsideHeader/i18n/en.json.js +10 -1
  118. package/build/cjs/components/AsideHeader/i18n/en.json.js.map +1 -1
  119. package/build/cjs/components/AsideHeader/i18n/index.d.ts +4 -4
  120. package/build/cjs/components/AsideHeader/i18n/ru.json.js +10 -1
  121. package/build/cjs/components/AsideHeader/i18n/ru.json.js.map +1 -1
  122. package/build/cjs/components/AsideHeader/index.d.ts +1 -0
  123. package/build/cjs/components/AsideHeader/quickAccess.d.ts +9 -0
  124. package/build/cjs/components/AsideHeader/quickAccess.js +31 -0
  125. package/build/cjs/components/AsideHeader/quickAccess.js.map +1 -0
  126. package/build/cjs/components/AsideHeader/types.d.ts +50 -5
  127. package/build/cjs/components/AsideHeader/types.js.map +1 -1
  128. package/build/cjs/components/AsideHeader/useAsideHeaderInnerContextValue.js +18 -3
  129. package/build/cjs/components/AsideHeader/useAsideHeaderInnerContextValue.js.map +1 -1
  130. package/build/cjs/components/AsideHeader/utils.d.ts +1 -0
  131. package/build/cjs/components/AsideHeader/utils.js +2 -0
  132. package/build/cjs/components/AsideHeader/utils.js.map +1 -1
  133. package/build/cjs/components/Footer/desktop/Footer.css +1 -1
  134. package/build/cjs/components/Footer/mobile/Footer.css +1 -1
  135. package/build/cjs/components/HotkeysPanel/HotkeysPanel.css +1 -1
  136. package/build/cjs/components/HotkeysPanel/HotkeysPanel.js +1 -1
  137. package/build/cjs/components/HotkeysPanel/HotkeysPanel.js.map +1 -1
  138. package/build/cjs/components/HotkeysPanel/HotkeysPanel.module.scss.js +1 -1
  139. package/build/cjs/components/Logo/Logo.css +1 -1
  140. package/build/cjs/components/Logo/Logo.d.ts +1 -0
  141. package/build/cjs/components/Logo/Logo.js +4 -4
  142. package/build/cjs/components/Logo/Logo.js.map +1 -1
  143. package/build/cjs/components/constants.d.ts +5 -0
  144. package/build/cjs/components/constants.js +6 -0
  145. package/build/cjs/components/constants.js.map +1 -1
  146. package/build/cjs/components/types.d.ts +11 -4
  147. package/build/docs/components/AsideHeader.md +244 -51
  148. package/build/esm/components/AsideHeader/AsideHeader.css +9 -1
  149. package/build/esm/components/AsideHeader/AsideHeader.js +2 -2
  150. package/build/esm/components/AsideHeader/AsideHeader.js.map +1 -1
  151. package/build/esm/components/AsideHeader/AsideHeader.module.scss.js +1 -1
  152. package/build/esm/components/AsideHeader/AsideHeaderContext.d.ts +5 -0
  153. package/build/esm/components/AsideHeader/AsideHeaderContext.js +2 -0
  154. package/build/esm/components/AsideHeader/AsideHeaderContext.js.map +1 -1
  155. package/build/esm/components/AsideHeader/__playwright__/AsideTransitionExample.d.ts +8 -0
  156. package/build/esm/components/AsideHeader/__playwright__/CollapseButtonExample.d.ts +14 -0
  157. package/build/esm/components/AsideHeader/__playwright__/CompactTransitionExample.d.ts +12 -0
  158. package/build/esm/components/AsideHeader/__playwright__/CurrentIndicatorExample.d.ts +20 -0
  159. package/build/esm/components/AsideHeader/__playwright__/QuickAccessOverflowExample.d.ts +8 -0
  160. package/build/esm/components/AsideHeader/__playwright__/currentIndicatorPaint.d.ts +21 -0
  161. package/build/esm/components/AsideHeader/__playwright__/transitionTestUtils.d.ts +4 -0
  162. package/build/esm/components/AsideHeader/__stories__/fullNavigationMoc.d.ts +6 -0
  163. package/build/esm/components/AsideHeader/components/AllPagesPanel/AllPagesListItem/AllPagesListItem.js +3 -5
  164. package/build/esm/components/AsideHeader/components/AllPagesPanel/AllPagesListItem/AllPagesListItem.js.map +1 -1
  165. package/build/esm/components/AsideHeader/components/AllPagesPanel/allPagesEditDisplay.d.ts +2 -1
  166. package/build/esm/components/AsideHeader/components/AllPagesPanel/allPagesEditDisplay.js +5 -1
  167. package/build/esm/components/AsideHeader/components/AllPagesPanel/allPagesEditDisplay.js.map +1 -1
  168. package/build/esm/components/AsideHeader/components/AllPagesPanel/i18n/en.json.js +1 -3
  169. package/build/esm/components/AsideHeader/components/AllPagesPanel/i18n/en.json.js.map +1 -1
  170. package/build/esm/components/AsideHeader/components/AllPagesPanel/i18n/index.d.ts +4 -4
  171. package/build/esm/components/AsideHeader/components/AllPagesPanel/i18n/ru.json.js +2 -4
  172. package/build/esm/components/AsideHeader/components/AllPagesPanel/i18n/ru.json.js.map +1 -1
  173. package/build/esm/components/AsideHeader/components/AsideDivider.d.ts +7 -0
  174. package/build/esm/components/AsideHeader/components/AsideDivider.js +11 -0
  175. package/build/esm/components/AsideHeader/components/AsideDivider.js.map +1 -0
  176. package/build/esm/components/AsideHeader/components/CollapseButton/CollapseButton.css +1 -1
  177. package/build/esm/components/AsideHeader/components/CollapseButton/CollapseButton.d.ts +3 -1
  178. package/build/esm/components/AsideHeader/components/CollapseButton/CollapseButton.js +12 -8
  179. package/build/esm/components/AsideHeader/components/CollapseButton/CollapseButton.js.map +1 -1
  180. package/build/esm/components/AsideHeader/components/CollapseButton/CollapseButton.module.scss.js +1 -1
  181. package/build/esm/components/AsideHeader/components/CollapseButton/useCollapseAnchor.d.ts +20 -0
  182. package/build/esm/components/AsideHeader/components/CollapseButton/useCollapseAnchor.js +167 -0
  183. package/build/esm/components/AsideHeader/components/CollapseButton/useCollapseAnchor.js.map +1 -0
  184. package/build/esm/components/AsideHeader/components/CompositeBar/CompositeBar.css +3 -1
  185. package/build/esm/components/AsideHeader/components/CompositeBar/CompositeBar.d.ts +13 -2
  186. package/build/esm/components/AsideHeader/components/CompositeBar/CompositeBar.js +54 -40
  187. package/build/esm/components/AsideHeader/components/CompositeBar/CompositeBar.js.map +1 -1
  188. package/build/esm/components/AsideHeader/components/CompositeBar/CompositeBar.module.scss.js +1 -1
  189. package/build/esm/components/AsideHeader/components/CompositeBar/HighlightedItem/HighlightedItem.css +1 -1
  190. package/build/esm/components/AsideHeader/components/CompositeBar/HighlightedItem/HighlightedItem.js +4 -2
  191. package/build/esm/components/AsideHeader/components/CompositeBar/HighlightedItem/HighlightedItem.js.map +1 -1
  192. package/build/esm/components/AsideHeader/components/CompositeBar/Item/Item.css +33 -1
  193. package/build/esm/components/AsideHeader/components/CompositeBar/Item/Item.js +161 -46
  194. package/build/esm/components/AsideHeader/components/CompositeBar/Item/Item.js.map +1 -1
  195. package/build/esm/components/AsideHeader/components/CompositeBar/Item/Item.module.scss.js +1 -1
  196. package/build/esm/components/AsideHeader/components/CompositeBar/Item/Item.types.d.ts +22 -4
  197. package/build/esm/components/AsideHeader/components/CompositeBar/Item/ItemPopup.d.ts +19 -0
  198. package/build/esm/components/AsideHeader/components/CompositeBar/Item/ItemPopup.js +139 -23
  199. package/build/esm/components/AsideHeader/components/CompositeBar/Item/ItemPopup.js.map +1 -1
  200. package/build/esm/components/AsideHeader/components/CompositeBar/Item/ItemQuickAccessPin.d.ts +7 -0
  201. package/build/esm/components/AsideHeader/components/CompositeBar/Item/ItemQuickAccessPin.js +23 -0
  202. package/build/esm/components/AsideHeader/components/CompositeBar/Item/ItemQuickAccessPin.js.map +1 -0
  203. package/build/esm/components/AsideHeader/components/CompositeBar/Item/renderItemTitle.d.ts +1 -1
  204. package/build/esm/components/AsideHeader/components/CompositeBar/Item/renderItemTitle.js +5 -1
  205. package/build/esm/components/AsideHeader/components/CompositeBar/Item/renderItemTitle.js.map +1 -1
  206. package/build/esm/components/AsideHeader/components/CompositeBar/ScrollableWithScrollbar/ScrollableWithScrollbar.css +1 -1
  207. package/build/esm/components/AsideHeader/components/CompositeBar/ScrollableWithScrollbar/ScrollableWithScrollbar.d.ts +4 -6
  208. package/build/esm/components/AsideHeader/components/CompositeBar/ScrollableWithScrollbar/ScrollableWithScrollbar.js +15 -6
  209. package/build/esm/components/AsideHeader/components/CompositeBar/ScrollableWithScrollbar/ScrollableWithScrollbar.js.map +1 -1
  210. package/build/esm/components/AsideHeader/components/CompositeBar/ScrollableWithScrollbar/ScrollableWithScrollbar.module.scss.js +1 -1
  211. package/build/esm/components/AsideHeader/components/CompositeBar/ScrollableWithScrollbar/useScrollableScrollbarSync.d.ts +8 -8
  212. package/build/esm/components/AsideHeader/components/CompositeBar/ScrollableWithScrollbar/useScrollableScrollbarSync.js +68 -33
  213. package/build/esm/components/AsideHeader/components/CompositeBar/ScrollableWithScrollbar/useScrollableScrollbarSync.js.map +1 -1
  214. package/build/esm/components/AsideHeader/components/CompositeBar/constants.d.ts +1 -0
  215. package/build/esm/components/AsideHeader/components/CompositeBar/constants.js +2 -1
  216. package/build/esm/components/AsideHeader/components/CompositeBar/constants.js.map +1 -1
  217. package/build/esm/components/AsideHeader/components/CompositeBar/presentationCurrent.d.ts +24 -0
  218. package/build/esm/components/AsideHeader/components/CompositeBar/presentationCurrent.js +36 -0
  219. package/build/esm/components/AsideHeader/components/CompositeBar/presentationCurrent.js.map +1 -0
  220. package/build/esm/components/AsideHeader/components/CompositeBar/utils.d.ts +12 -7
  221. package/build/esm/components/AsideHeader/components/CompositeBar/utils.js +44 -35
  222. package/build/esm/components/AsideHeader/components/CompositeBar/utils.js.map +1 -1
  223. package/build/esm/components/AsideHeader/components/FirstPanel.js +131 -12
  224. package/build/esm/components/AsideHeader/components/FirstPanel.js.map +1 -1
  225. package/build/esm/components/AsideHeader/components/FooterItem/FooterItem.css +1 -1
  226. package/build/esm/components/AsideHeader/components/FooterItem/FooterItem.js +18 -2
  227. package/build/esm/components/AsideHeader/components/FooterItem/FooterItem.js.map +1 -1
  228. package/build/esm/components/AsideHeader/components/FooterItem/FooterItem.module.scss.js +1 -1
  229. package/build/esm/components/AsideHeader/components/Header.js +8 -4
  230. package/build/esm/components/AsideHeader/components/Header.js.map +1 -1
  231. package/build/esm/components/AsideHeader/components/PageLayout/AsideFallback.css +9 -1
  232. package/build/esm/components/AsideHeader/components/PageLayout/AsideFallback.d.ts +1 -0
  233. package/build/esm/components/AsideHeader/components/PageLayout/AsideFallback.js +14 -7
  234. package/build/esm/components/AsideHeader/components/PageLayout/AsideFallback.js.map +1 -1
  235. package/build/esm/components/AsideHeader/components/PageLayout/AsideLayoutTransition.d.ts +80 -0
  236. package/build/esm/components/AsideHeader/components/PageLayout/AsideLayoutTransition.js +598 -0
  237. package/build/esm/components/AsideHeader/components/PageLayout/AsideLayoutTransition.js.map +1 -0
  238. package/build/esm/components/AsideHeader/components/PageLayout/CurrentIndicatorTransition.d.ts +14 -0
  239. package/build/esm/components/AsideHeader/components/PageLayout/CurrentIndicatorTransition.js +162 -0
  240. package/build/esm/components/AsideHeader/components/PageLayout/CurrentIndicatorTransition.js.map +1 -0
  241. package/build/esm/components/AsideHeader/components/PageLayout/CurrentPresentationObserver.d.ts +14 -0
  242. package/build/esm/components/AsideHeader/components/PageLayout/CurrentPresentationObserver.js +92 -0
  243. package/build/esm/components/AsideHeader/components/PageLayout/CurrentPresentationObserver.js.map +1 -0
  244. package/build/esm/components/AsideHeader/components/PageLayout/PageLayout.css +9 -1
  245. package/build/esm/components/AsideHeader/components/PageLayout/PageLayout.d.ts +1 -1
  246. package/build/esm/components/AsideHeader/components/PageLayout/PageLayout.js +15 -6
  247. package/build/esm/components/AsideHeader/components/PageLayout/PageLayout.js.map +1 -1
  248. package/build/esm/components/AsideHeader/components/PageLayout/PageLayoutAside.css +9 -1
  249. package/build/esm/components/AsideHeader/components/PageLayout/PageLayoutAside.d.ts +1 -1
  250. package/build/esm/components/AsideHeader/components/PageLayout/PageLayoutAside.js +5 -2
  251. package/build/esm/components/AsideHeader/components/PageLayout/PageLayoutAside.js.map +1 -1
  252. package/build/esm/components/AsideHeader/components/PageLayout/currentIndicatorDom.d.ts +7 -0
  253. package/build/esm/components/AsideHeader/components/PageLayout/currentIndicatorDom.js +17 -0
  254. package/build/esm/components/AsideHeader/components/PageLayout/currentIndicatorDom.js.map +1 -0
  255. package/build/esm/components/AsideHeader/components/PageLayout/currentIndicatorModel.d.ts +25 -0
  256. package/build/esm/components/AsideHeader/components/PageLayout/currentIndicatorModel.js +84 -0
  257. package/build/esm/components/AsideHeader/components/PageLayout/currentIndicatorModel.js.map +1 -0
  258. package/build/esm/components/AsideHeader/components/Panels.js +3 -3
  259. package/build/esm/components/AsideHeader/components/Panels.js.map +1 -1
  260. package/build/esm/components/AsideHeader/density.d.ts +21 -0
  261. package/build/esm/components/AsideHeader/density.js +58 -0
  262. package/build/esm/components/AsideHeader/density.js.map +1 -0
  263. package/build/esm/components/AsideHeader/i18n/__mocks__/index.d.ts +1 -0
  264. package/build/esm/components/AsideHeader/i18n/en.json.js +8 -2
  265. package/build/esm/components/AsideHeader/i18n/en.json.js.map +1 -1
  266. package/build/esm/components/AsideHeader/i18n/index.d.ts +4 -4
  267. package/build/esm/components/AsideHeader/i18n/ru.json.js +8 -2
  268. package/build/esm/components/AsideHeader/i18n/ru.json.js.map +1 -1
  269. package/build/esm/components/AsideHeader/index.d.ts +1 -0
  270. package/build/esm/components/AsideHeader/quickAccess.d.ts +9 -0
  271. package/build/esm/components/AsideHeader/quickAccess.js +27 -0
  272. package/build/esm/components/AsideHeader/quickAccess.js.map +1 -0
  273. package/build/esm/components/AsideHeader/types.d.ts +50 -5
  274. package/build/esm/components/AsideHeader/types.js.map +1 -1
  275. package/build/esm/components/AsideHeader/useAsideHeaderInnerContextValue.js +18 -3
  276. package/build/esm/components/AsideHeader/useAsideHeaderInnerContextValue.js.map +1 -1
  277. package/build/esm/components/AsideHeader/utils.d.ts +1 -0
  278. package/build/esm/components/AsideHeader/utils.js +2 -1
  279. package/build/esm/components/AsideHeader/utils.js.map +1 -1
  280. package/build/esm/components/Footer/desktop/Footer.css +1 -1
  281. package/build/esm/components/Footer/mobile/Footer.css +1 -1
  282. package/build/esm/components/HotkeysPanel/HotkeysPanel.css +1 -1
  283. package/build/esm/components/HotkeysPanel/HotkeysPanel.js +1 -1
  284. package/build/esm/components/HotkeysPanel/HotkeysPanel.js.map +1 -1
  285. package/build/esm/components/HotkeysPanel/HotkeysPanel.module.scss.js +1 -1
  286. package/build/esm/components/Logo/Logo.css +1 -1
  287. package/build/esm/components/Logo/Logo.d.ts +1 -0
  288. package/build/esm/components/Logo/Logo.js +4 -4
  289. package/build/esm/components/Logo/Logo.js.map +1 -1
  290. package/build/esm/components/constants.d.ts +5 -0
  291. package/build/esm/components/constants.js +6 -1
  292. package/build/esm/components/constants.js.map +1 -1
  293. package/build/esm/components/types.d.ts +11 -4
  294. package/package.json +1 -1
  295. package/build/cjs/assets/icons/control-menu-button.svg.js +0 -41
  296. package/build/cjs/assets/icons/control-menu-button.svg.js.map +0 -1
  297. package/build/esm/assets/icons/control-menu-button.svg.js +0 -18
  298. package/build/esm/assets/icons/control-menu-button.svg.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ItemQuickAccessPin.js","sources":["../../../../../../../../src/components/AsideHeader/components/CompositeBar/Item/ItemQuickAccessPin.tsx"],"sourcesContent":["import React from 'react';\n\nimport {Pin, PinFill} from '@gravity-ui/icons';\nimport {Button, Icon} from '@gravity-ui/uikit';\n\nimport {createBlock} from '../../../../utils/cn';\nimport i18n from '../../../i18n';\n\nimport styles from './Item.module.scss';\n\nconst b = createBlock('composite-bar-item', styles);\n\ntype ItemQuickAccessPinProps = {\n quickAccess?: boolean;\n onToggle: (event: React.MouseEvent<HTMLButtonElement>) => void;\n};\n\nexport const ItemQuickAccessPin: React.FC<ItemQuickAccessPinProps> = ({quickAccess, onToggle}) => {\n const label = quickAccess ? i18n('quick_access_unpin') : i18n('quick_access_pin');\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n onToggle(event);\n },\n [onToggle],\n );\n\n return (\n <Button\n className={b('quick-access-pin', {pinned: quickAccess})}\n view=\"flat-secondary\"\n size=\"s\"\n onClick={handleClick}\n aria-label={label}\n title={label}\n >\n <Button.Icon>\n <Icon data={quickAccess ? PinFill : Pin} />\n </Button.Icon>\n </Button>\n );\n};\n\nItemQuickAccessPin.displayName = 'ItemQuickAccessPin';\n"],"names":["React"],"mappings":";;;;;;;AAUA,MAAM,CAAC,GAAG,WAAW,CAAC,oBAAoB,EAAE,MAAM,CAAC;AAOtC,MAAA,kBAAkB,GAAsC,CAAC,EAAC,WAAW,EAAE,QAAQ,EAAC,KAAI;AAC7F,IAAA,MAAM,KAAK,GAAG,WAAW,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,IAAI,CAAC,kBAAkB,CAAC;IACjF,MAAM,WAAW,GAAGA,cAAK,CAAC,WAAW,CACjC,CAAC,KAA0C,KAAI;QAC3C,KAAK,CAAC,cAAc,EAAE;QACtB,KAAK,CAAC,eAAe,EAAE;QACvB,QAAQ,CAAC,KAAK,CAAC;AACnB,KAAC,EACD,CAAC,QAAQ,CAAC,CACb;AAED,IAAA,QACIA,cAAA,CAAA,aAAA,CAAC,MAAM,EAAA,EACH,SAAS,EAAE,CAAC,CAAC,kBAAkB,EAAE,EAAC,MAAM,EAAE,WAAW,EAAC,CAAC,EACvD,IAAI,EAAC,gBAAgB,EACrB,IAAI,EAAC,GAAG,EACR,OAAO,EAAE,WAAW,EACR,YAAA,EAAA,KAAK,EACjB,KAAK,EAAE,KAAK,EAAA;QAEZA,cAAC,CAAA,aAAA,CAAA,MAAM,CAAC,IAAI,EAAA,IAAA;AACR,YAAAA,cAAA,CAAA,aAAA,CAAC,IAAI,EAAC,EAAA,IAAI,EAAE,WAAW,GAAG,OAAO,GAAG,GAAG,GAAI,CACjC,CACT;AAEjB;AAEA,kBAAkB,CAAC,WAAW,GAAG,oBAAoB;;;;"}
@@ -1,3 +1,3 @@
1
1
  import React from 'react';
2
2
  import { AsideHeaderItem } from 'src/components/AsideHeader/types';
3
- export declare function renderItemTitle(params: Pick<AsideHeaderItem, 'title' | 'rightAdornment'>): React.JSX.Element;
3
+ export declare function renderItemTitle(params: Pick<AsideHeaderItem, 'title' | 'rightAdornment' | 'titleLines'>): React.JSX.Element;
@@ -4,7 +4,11 @@ import styles from './Item.module.scss.js';
4
4
 
5
5
  const b = createBlock('composite-bar-item', styles);
6
6
  function renderItemTitle(params) {
7
- let titleNode = React__default.createElement("div", { className: b('title-text') }, params.title);
7
+ var _a;
8
+ // Preserve the pre-v7 two-line fallback. Consumers opt into the new
9
+ // single-line presentation explicitly with `titleLines: 1`.
10
+ const titleLines = (_a = params.titleLines) !== null && _a !== undefined ? _a : 2;
11
+ let titleNode = (React__default.createElement("div", { className: b('title-text', { lines: titleLines === 2 ? '2' : undefined }) }, params.title));
8
12
  if (params.rightAdornment) {
9
13
  titleNode = (React__default.createElement(React__default.Fragment, null,
10
14
  titleNode,
@@ -1 +1 @@
1
- {"version":3,"file":"renderItemTitle.js","sources":["../../../../../../../../src/components/AsideHeader/components/CompositeBar/Item/renderItemTitle.tsx"],"sourcesContent":["import React from 'react';\n\nimport {AsideHeaderItem} from 'src/components/AsideHeader/types';\n\nimport {createBlock} from '../../../../utils/cn';\n\nimport styles from './Item.module.scss';\n\nconst b = createBlock('composite-bar-item', styles);\n\nexport function renderItemTitle(params: Pick<AsideHeaderItem, 'title' | 'rightAdornment'>) {\n let titleNode = <div className={b('title-text')}>{params.title}</div>;\n\n if (params.rightAdornment) {\n titleNode = (\n <React.Fragment>\n {titleNode}\n <div className={b('title-adornment')}>{params.rightAdornment}</div>\n </React.Fragment>\n );\n }\n\n return titleNode;\n}\n"],"names":["React"],"mappings":";;;;AAQA,MAAM,CAAC,GAAG,WAAW,CAAC,oBAAoB,EAAE,MAAM,CAAC;AAE7C,SAAU,eAAe,CAAC,MAAyD,EAAA;AACrF,IAAA,IAAI,SAAS,GAAGA,cAAK,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,SAAS,EAAE,CAAC,CAAC,YAAY,CAAC,EAAG,EAAA,MAAM,CAAC,KAAK,CAAO;AAErE,IAAA,IAAI,MAAM,CAAC,cAAc,EAAE;AACvB,QAAA,SAAS,IACLA,cAAC,CAAA,aAAA,CAAAA,cAAK,CAAC,QAAQ,EAAA,IAAA;YACV,SAAS;AACV,YAAAA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,CAAC,CAAC,iBAAiB,CAAC,EAAG,EAAA,MAAM,CAAC,cAAc,CAAO,CACtD,CACpB;;AAGL,IAAA,OAAO,SAAS;AACpB;;;;"}
1
+ {"version":3,"file":"renderItemTitle.js","sources":["../../../../../../../../src/components/AsideHeader/components/CompositeBar/Item/renderItemTitle.tsx"],"sourcesContent":["import React from 'react';\n\nimport {AsideHeaderItem} from 'src/components/AsideHeader/types';\n\nimport {createBlock} from '../../../../utils/cn';\n\nimport styles from './Item.module.scss';\n\nconst b = createBlock('composite-bar-item', styles);\n\nexport function renderItemTitle(\n params: Pick<AsideHeaderItem, 'title' | 'rightAdornment' | 'titleLines'>,\n) {\n // Preserve the pre-v7 two-line fallback. Consumers opt into the new\n // single-line presentation explicitly with `titleLines: 1`.\n const titleLines = params.titleLines ?? 2;\n let titleNode = (\n <div className={b('title-text', {lines: titleLines === 2 ? '2' : undefined})}>\n {params.title}\n </div>\n );\n\n if (params.rightAdornment) {\n titleNode = (\n <React.Fragment>\n {titleNode}\n <div className={b('title-adornment')}>{params.rightAdornment}</div>\n </React.Fragment>\n );\n }\n\n return titleNode;\n}\n"],"names":["React"],"mappings":";;;;AAQA,MAAM,CAAC,GAAG,WAAW,CAAC,oBAAoB,EAAE,MAAM,CAAC;AAE7C,SAAU,eAAe,CAC3B,MAAwE,EAAA;;;;IAIxE,MAAM,UAAU,GAAG,CAAA,EAAA,GAAA,MAAM,CAAC,UAAU,MAAA,IAAA,IAAA,EAAA,KAAA,SAAA,GAAA,EAAA,GAAI,CAAC;AACzC,IAAA,IAAI,SAAS,IACTA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,CAAC,CAAC,YAAY,EAAE,EAAC,KAAK,EAAE,UAAU,KAAK,CAAC,GAAG,GAAG,GAAG,SAAS,EAAC,CAAC,EAAA,EACvE,MAAM,CAAC,KAAK,CACX,CACT;AAED,IAAA,IAAI,MAAM,CAAC,cAAc,EAAE;AACvB,QAAA,SAAS,IACLA,cAAC,CAAA,aAAA,CAAAA,cAAK,CAAC,QAAQ,EAAA,IAAA;YACV,SAAS;AACV,YAAAA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,CAAC,CAAC,iBAAiB,CAAC,EAAG,EAAA,MAAM,CAAC,cAAc,CAAO,CACtD,CACpB;;AAGL,IAAA,OAAO,SAAS;AACpB;;;;"}
@@ -1 +1 @@
1
- .ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar___S-GKS{--_--scrollbar-width:var(--gn-aside-scrollbar-width,8px);--_--scrollbar-thumb-width:var(--gn-aside-scrollbar-thumb-width,4px);flex:1 1 auto;min-height:0;position:relative;width:100%}.ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar___S-GKS:before{background:var(--gn-aside-bottom-shadow-color,linear-gradient(to bottom,transparent 0,transparent 50%,rgba(0,0,0,.08) 100%));bottom:0;content:"";height:100%;left:0;opacity:0;pointer-events:none;position:absolute;right:0;transition:opacity .3s ease-in-out}.ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar___S-GKS.ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar_bottom-shadow___YoCCZ:before{opacity:1}.ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scrollable-inner___yRIza{-ms-overflow-style:none;height:100%;overflow-y:auto;scrollbar-width:none;width:100%}.ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scrollable-inner___yRIza::-webkit-scrollbar{display:none;height:0;width:0}.ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scrollbar-track___u6MVN{background:var(--gn-aside-scrollbar-track-color,transparent);bottom:0;pointer-events:auto;position:absolute;right:0;top:0;width:var(--_--scrollbar-width);z-index:3}.ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scrollbar-thumb___bLf6h{background:var(--gn-aside-scrollbar-handle-color,var(--g-color-base-simple-hover));border-radius:calc(var(--_--scrollbar-thumb-width)/2);opacity:0;position:absolute;right:calc((var(--_--scrollbar-width) - var(--_--scrollbar-thumb-width))/2);top:0;touch-action:none;transition:opacity .15s ease-in-out;width:var(--_--scrollbar-thumb-width)}.ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar___S-GKS:hover .ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scrollbar-thumb___bLf6h{opacity:1}.g-root_theme_light .ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar___S-GKS, .g-root_theme_light-hc .ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar___S-GKS{--gn-aside-bottom-shadow-color:linear-gradient(180deg,transparent 0%,transparent 50%,rgba(0,0,0,.08))}.g-root_theme_dark .ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar___S-GKS, .g-root_theme_dark-hc .ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar___S-GKS{--gn-aside-bottom-shadow-color:linear-gradient(180deg,transparent 0%,transparent 80%,rgba(0,0,0,.4))}
1
+ .ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar___S-GKS{--_--scrollbar-width:var(--gn-aside-scrollbar-width,8px);--_--scrollbar-thumb-width:var(--gn-aside-scrollbar-thumb-width,4px);flex:1 1 auto;min-height:0;position:relative;width:100%}.ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar___S-GKS:after, .ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar___S-GKS:before{content:"";height:12px;inset-inline:0;opacity:0;pointer-events:none;position:absolute;transition:opacity .3s ease-in-out;z-index:2}.ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar___S-GKS:before{background:linear-gradient(to bottom,var(--g-color-sfx-shadow),transparent);inset-block-start:0}.ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar___S-GKS:after{background:linear-gradient(to top,var(--g-color-sfx-shadow),transparent);inset-block-end:0}.ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar_shadow-end___WH4ZY:after, .ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar_shadow-start___dQ8Jw:before{opacity:.7}.ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scrollable-inner___yRIza{-ms-overflow-style:none;height:100%;overflow-y:auto;scrollbar-width:none;width:100%}.ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scrollable-inner___yRIza::-webkit-scrollbar{display:none;height:0;width:0}.ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scroll-divider___QV96G{background-color:var(--gn-aside-header-divider-horizontal-color,var(--g-color-line-generic));height:1px;inset-inline:0;opacity:0;pointer-events:none;position:absolute;transition:opacity .3s ease-in-out;z-index:2}.ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scroll-divider_start___jneED{inset-block-start:0}.ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scroll-divider_end___YqNPa{inset-block-end:0}.ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scroll-divider_visible___B7td6{opacity:1}.ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scrollbar-track___u6MVN{background:var(--gn-aside-scrollbar-track-color,transparent);bottom:0;pointer-events:auto;position:absolute;right:0;top:0;width:var(--_--scrollbar-width);z-index:3}.ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scrollbar-thumb___bLf6h{background:var(--gn-aside-scrollbar-handle-color,var(--g-color-base-simple-hover));border-radius:calc(var(--_--scrollbar-thumb-width)/2);opacity:0;position:absolute;right:calc((var(--_--scrollbar-width) - var(--_--scrollbar-thumb-width))/2);top:0;touch-action:none;transition:opacity .15s ease-in-out;width:var(--_--scrollbar-thumb-width)}.ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar___S-GKS:hover .ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scrollbar-thumb___bLf6h{opacity:1}
@@ -1,12 +1,10 @@
1
- import React, { FC, ReactNode } from 'react';
1
+ import { FC, ReactNode } from 'react';
2
2
  type ScrollableWithScrollbarProps = {
3
3
  children: ReactNode;
4
4
  className?: string;
5
- /**
6
- * Extra dependencies that should trigger a recalculation of the bottom
7
- * shadow and custom scrollbar thumb (e.g. when the rendered items change).
8
- */
9
- recalcDeps?: React.DependencyList;
5
+ showScrollDividers?: boolean;
6
+ /** Called when scrollable content overflows the allocated height. */
7
+ onOverflowChange?: (overflows: boolean) => void;
10
8
  };
11
9
  export declare const ScrollableWithScrollbar: FC<ScrollableWithScrollbarProps>;
12
10
  export {};
@@ -1,19 +1,28 @@
1
1
  import './ScrollableWithScrollbar.css';
2
- import React__default from 'react';
2
+ import React__default, { useEffect } from 'react';
3
3
  import { createBlock } from '../../../../utils/cn.js';
4
+ import { AsideDivider } from '../../AsideDivider.js';
4
5
  import { useScrollableScrollbarSync } from './useScrollableScrollbarSync.js';
5
6
  import styles from './ScrollableWithScrollbar.module.scss.js';
6
7
 
7
8
  const b = createBlock('scrollable-with-scrollbar', styles);
8
- const EMPTY_DEPS = [];
9
9
  // Hides the native scrollbar and renders a custom thumb synced with the
10
10
  // underlying scroll position. The scroll itself stays native (wheel / touch /
11
11
  // keyboard) — only the visual indicator and drag handling are custom, so the
12
12
  // reserved gutter width is identical across OS / browser scrollbar settings.
13
- const ScrollableWithScrollbar = ({ children, className, recalcDeps = EMPTY_DEPS, }) => {
14
- const { scrollRef, trackRef, thumbRef, hasContentBelow, overflows, thumb, scheduleUpdate, handleThumbPointerDown, handleTrackPointerDown, } = useScrollableScrollbarSync(recalcDeps);
15
- return (React__default.createElement("div", { className: b({ 'bottom-shadow': hasContentBelow }, className) },
16
- React__default.createElement("div", { ref: scrollRef, className: b('scrollable-inner'), onScroll: scheduleUpdate }, children),
13
+ const ScrollableWithScrollbar = ({ children, className, showScrollDividers = false, onOverflowChange, }) => {
14
+ const { scrollRef, trackRef, thumbRef, overflows, canScrollUp, canScrollDown, thumb, scheduleUpdate, handleThumbPointerDown, handleTrackPointerDown, } = useScrollableScrollbarSync();
15
+ useEffect(() => {
16
+ onOverflowChange === null || onOverflowChange === undefined ? undefined : onOverflowChange(overflows);
17
+ }, [onOverflowChange, overflows]);
18
+ useEffect(() => {
19
+ return () => onOverflowChange === null || onOverflowChange === undefined ? undefined : onOverflowChange(false);
20
+ }, [onOverflowChange]);
21
+ return (React__default.createElement("div", { className: b({ 'shadow-start': canScrollUp, 'shadow-end': canScrollDown }, className) },
22
+ React__default.createElement("div", { ref: scrollRef, className: b('scrollable-inner'), onScroll: scheduleUpdate, "data-gn-aside-scrollport": true }, children),
23
+ showScrollDividers && (React__default.createElement(React__default.Fragment, null,
24
+ React__default.createElement(AsideDivider, { transitionId: "scroll-start", className: b('scroll-divider', { start: true, visible: canScrollUp }) }),
25
+ React__default.createElement(AsideDivider, { transitionId: "scroll-end", className: b('scroll-divider', { end: true, visible: canScrollDown }) }))),
17
26
  overflows ? (React__default.createElement("div", { ref: trackRef, className: b('scrollbar-track'), onPointerDown: handleTrackPointerDown, "aria-hidden": "true" },
18
27
  React__default.createElement("div", { ref: thumbRef, className: b('scrollbar-thumb'), style: { transform: `translateY(${thumb.top}px)`, height: thumb.height }, onPointerDown: handleThumbPointerDown }))) : null));
19
28
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ScrollableWithScrollbar.js","sources":["../../../../../../../../src/components/AsideHeader/components/CompositeBar/ScrollableWithScrollbar/ScrollableWithScrollbar.tsx"],"sourcesContent":["import React, {FC, ReactNode} from 'react';\n\nimport {createBlock} from '../../../../utils/cn';\n\nimport {useScrollableScrollbarSync} from './useScrollableScrollbarSync';\n\nimport styles from './ScrollableWithScrollbar.module.scss';\n\nconst b = createBlock('scrollable-with-scrollbar', styles);\n\nconst EMPTY_DEPS: React.DependencyList = [];\n\ntype ScrollableWithScrollbarProps = {\n children: ReactNode;\n className?: string;\n /**\n * Extra dependencies that should trigger a recalculation of the bottom\n * shadow and custom scrollbar thumb (e.g. when the rendered items change).\n */\n recalcDeps?: React.DependencyList;\n};\n\n// Hides the native scrollbar and renders a custom thumb synced with the\n// underlying scroll position. The scroll itself stays native (wheel / touch /\n// keyboard) — only the visual indicator and drag handling are custom, so the\n// reserved gutter width is identical across OS / browser scrollbar settings.\nexport const ScrollableWithScrollbar: FC<ScrollableWithScrollbarProps> = ({\n children,\n className,\n recalcDeps = EMPTY_DEPS,\n}) => {\n const {\n scrollRef,\n trackRef,\n thumbRef,\n hasContentBelow,\n overflows,\n thumb,\n scheduleUpdate,\n handleThumbPointerDown,\n handleTrackPointerDown,\n } = useScrollableScrollbarSync(recalcDeps);\n\n return (\n <div className={b({'bottom-shadow': hasContentBelow}, className)}>\n <div ref={scrollRef} className={b('scrollable-inner')} onScroll={scheduleUpdate}>\n {children}\n </div>\n\n {overflows ? (\n <div\n ref={trackRef}\n className={b('scrollbar-track')}\n onPointerDown={handleTrackPointerDown}\n aria-hidden=\"true\"\n >\n <div\n ref={thumbRef}\n className={b('scrollbar-thumb')}\n style={{transform: `translateY(${thumb.top}px)`, height: thumb.height}}\n onPointerDown={handleThumbPointerDown}\n />\n </div>\n ) : null}\n </div>\n );\n};\n"],"names":["React"],"mappings":";;;;;AAQA,MAAM,CAAC,GAAG,WAAW,CAAC,2BAA2B,EAAE,MAAM,CAAC;AAE1D,MAAM,UAAU,GAAyB,EAAE;AAY3C;AACA;AACA;AACA;AACO,MAAM,uBAAuB,GAAqC,CAAC,EACtE,QAAQ,EACR,SAAS,EACT,UAAU,GAAG,UAAU,GAC1B,KAAI;IACD,MAAM,EACF,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,eAAe,EACf,SAAS,EACT,KAAK,EACL,cAAc,EACd,sBAAsB,EACtB,sBAAsB,GACzB,GAAG,0BAA0B,CAAC,UAAU,CAAC;AAE1C,IAAA,QACIA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,CAAC,CAAC,EAAC,eAAe,EAAE,eAAe,EAAC,EAAE,SAAS,CAAC,EAAA;AAC5D,QAAAA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC,kBAAkB,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAA,EAC1E,QAAQ,CACP;QAEL,SAAS,IACNA,sCACI,GAAG,EAAE,QAAQ,EACb,SAAS,EAAE,CAAC,CAAC,iBAAiB,CAAC,EAC/B,aAAa,EAAE,sBAAsB,iBACzB,MAAM,EAAA;AAElB,YAAAA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EACI,GAAG,EAAE,QAAQ,EACb,SAAS,EAAE,CAAC,CAAC,iBAAiB,CAAC,EAC/B,KAAK,EAAE,EAAC,SAAS,EAAE,CAAA,WAAA,EAAc,KAAK,CAAC,GAAG,CAAK,GAAA,CAAA,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAC,EACtE,aAAa,EAAE,sBAAsB,EACvC,CAAA,CACA,IACN,IAAI,CACN;AAEd;;;;"}
1
+ {"version":3,"file":"ScrollableWithScrollbar.js","sources":["../../../../../../../../src/components/AsideHeader/components/CompositeBar/ScrollableWithScrollbar/ScrollableWithScrollbar.tsx"],"sourcesContent":["import React, {FC, ReactNode, useEffect} from 'react';\n\nimport {createBlock} from '../../../../utils/cn';\nimport {AsideDivider} from '../../AsideDivider';\n\nimport {useScrollableScrollbarSync} from './useScrollableScrollbarSync';\n\nimport styles from './ScrollableWithScrollbar.module.scss';\n\nconst b = createBlock('scrollable-with-scrollbar', styles);\n\ntype ScrollableWithScrollbarProps = {\n children: ReactNode;\n className?: string;\n showScrollDividers?: boolean;\n /** Called when scrollable content overflows the allocated height. */\n onOverflowChange?: (overflows: boolean) => void;\n};\n\n// Hides the native scrollbar and renders a custom thumb synced with the\n// underlying scroll position. The scroll itself stays native (wheel / touch /\n// keyboard) — only the visual indicator and drag handling are custom, so the\n// reserved gutter width is identical across OS / browser scrollbar settings.\nexport const ScrollableWithScrollbar: FC<ScrollableWithScrollbarProps> = ({\n children,\n className,\n showScrollDividers = false,\n onOverflowChange,\n}) => {\n const {\n scrollRef,\n trackRef,\n thumbRef,\n overflows,\n canScrollUp,\n canScrollDown,\n thumb,\n scheduleUpdate,\n handleThumbPointerDown,\n handleTrackPointerDown,\n } = useScrollableScrollbarSync();\n\n useEffect(() => {\n onOverflowChange?.(overflows);\n }, [onOverflowChange, overflows]);\n\n useEffect(() => {\n return () => onOverflowChange?.(false);\n }, [onOverflowChange]);\n\n return (\n <div className={b({'shadow-start': canScrollUp, 'shadow-end': canScrollDown}, className)}>\n <div\n ref={scrollRef}\n className={b('scrollable-inner')}\n onScroll={scheduleUpdate}\n data-gn-aside-scrollport\n >\n {children}\n </div>\n\n {showScrollDividers && (\n <React.Fragment>\n <AsideDivider\n transitionId=\"scroll-start\"\n className={b('scroll-divider', {start: true, visible: canScrollUp})}\n />\n <AsideDivider\n transitionId=\"scroll-end\"\n className={b('scroll-divider', {end: true, visible: canScrollDown})}\n />\n </React.Fragment>\n )}\n {overflows ? (\n <div\n ref={trackRef}\n className={b('scrollbar-track')}\n onPointerDown={handleTrackPointerDown}\n aria-hidden=\"true\"\n >\n <div\n ref={thumbRef}\n className={b('scrollbar-thumb')}\n style={{transform: `translateY(${thumb.top}px)`, height: thumb.height}}\n onPointerDown={handleThumbPointerDown}\n />\n </div>\n ) : null}\n </div>\n );\n};\n"],"names":["React"],"mappings":";;;;;;AASA,MAAM,CAAC,GAAG,WAAW,CAAC,2BAA2B,EAAE,MAAM,CAAC;AAU1D;AACA;AACA;AACA;AACa,MAAA,uBAAuB,GAAqC,CAAC,EACtE,QAAQ,EACR,SAAS,EACT,kBAAkB,GAAG,KAAK,EAC1B,gBAAgB,GACnB,KAAI;IACD,MAAM,EACF,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,WAAW,EACX,aAAa,EACb,KAAK,EACL,cAAc,EACd,sBAAsB,EACtB,sBAAsB,GACzB,GAAG,0BAA0B,EAAE;IAEhC,SAAS,CAAC,MAAK;AACX,QAAA,gBAAgB,aAAhB,gBAAgB,KAAA,SAAA,GAAA,SAAA,GAAhB,gBAAgB,CAAG,SAAS,CAAC;AACjC,KAAC,EAAE,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;IAEjC,SAAS,CAAC,MAAK;QACX,OAAO,MAAM,gBAAgB,KAAA,IAAA,IAAhB,gBAAgB,KAAA,SAAA,GAAA,SAAA,GAAhB,gBAAgB,CAAG,KAAK,CAAC;AAC1C,KAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC;AAEtB,IAAA,QACIA,cAAK,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,SAAS,EAAE,CAAC,CAAC,EAAC,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAC,EAAE,SAAS,CAAC,EAAA;AACpF,QAAAA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EACI,GAAG,EAAE,SAAS,EACd,SAAS,EAAE,CAAC,CAAC,kBAAkB,CAAC,EAChC,QAAQ,EAAE,cAAc,EAAA,0BAAA,EAAA,IAAA,EAAA,EAGvB,QAAQ,CACP;AAEL,QAAA,kBAAkB,KACfA,cAAC,CAAA,aAAA,CAAAA,cAAK,CAAC,QAAQ,EAAA,IAAA;YACXA,cAAC,CAAA,aAAA,CAAA,YAAY,IACT,YAAY,EAAC,cAAc,EAC3B,SAAS,EAAE,CAAC,CAAC,gBAAgB,EAAE,EAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAC,CAAC,EACrE,CAAA;YACFA,cAAC,CAAA,aAAA,CAAA,YAAY,EACT,EAAA,YAAY,EAAC,YAAY,EACzB,SAAS,EAAE,CAAC,CAAC,gBAAgB,EAAE,EAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAC,CAAC,EACrE,CAAA,CACW,CACpB;QACA,SAAS,IACNA,sCACI,GAAG,EAAE,QAAQ,EACb,SAAS,EAAE,CAAC,CAAC,iBAAiB,CAAC,EAC/B,aAAa,EAAE,sBAAsB,iBACzB,MAAM,EAAA;AAElB,YAAAA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EACI,GAAG,EAAE,QAAQ,EACb,SAAS,EAAE,CAAC,CAAC,iBAAiB,CAAC,EAC/B,KAAK,EAAE,EAAC,SAAS,EAAE,CAAA,WAAA,EAAc,KAAK,CAAC,GAAG,CAAK,GAAA,CAAA,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAC,EACtE,aAAa,EAAE,sBAAsB,EACvC,CAAA,CACA,IACN,IAAI,CACN;AAEd;;;;"}
@@ -1,4 +1,4 @@
1
- var styles = {"gn-scrollable-with-scrollbar":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar___S-GKS","gnScrollableWithScrollbar":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar___S-GKS","gn-scrollable-with-scrollbar_bottom-shadow":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar_bottom-shadow___YoCCZ","gnScrollableWithScrollbarBottomShadow":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar_bottom-shadow___YoCCZ","gn-scrollable-with-scrollbar__scrollable-inner":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scrollable-inner___yRIza","gnScrollableWithScrollbarScrollableInner":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scrollable-inner___yRIza","gn-scrollable-with-scrollbar__scrollbar-track":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scrollbar-track___u6MVN","gnScrollableWithScrollbarScrollbarTrack":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scrollbar-track___u6MVN","gn-scrollable-with-scrollbar__scrollbar-thumb":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scrollbar-thumb___bLf6h","gnScrollableWithScrollbarScrollbarThumb":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scrollbar-thumb___bLf6h"};
1
+ var styles = {"gn-scrollable-with-scrollbar":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar___S-GKS","gnScrollableWithScrollbar":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar___S-GKS","gn-scrollable-with-scrollbar_shadow-start":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar_shadow-start___dQ8Jw","gnScrollableWithScrollbarShadowStart":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar_shadow-start___dQ8Jw","gn-scrollable-with-scrollbar_shadow-end":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar_shadow-end___WH4ZY","gnScrollableWithScrollbarShadowEnd":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar_shadow-end___WH4ZY","gn-scrollable-with-scrollbar__scrollable-inner":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scrollable-inner___yRIza","gnScrollableWithScrollbarScrollableInner":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scrollable-inner___yRIza","gn-scrollable-with-scrollbar__scroll-divider":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scroll-divider___QV96G","gnScrollableWithScrollbarScrollDivider":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scroll-divider___QV96G","gn-scrollable-with-scrollbar__scroll-divider_start":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scroll-divider_start___jneED","gnScrollableWithScrollbarScrollDividerStart":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scroll-divider_start___jneED","gn-scrollable-with-scrollbar__scroll-divider_end":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scroll-divider_end___YqNPa","gnScrollableWithScrollbarScrollDividerEnd":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scroll-divider_end___YqNPa","gn-scrollable-with-scrollbar__scroll-divider_visible":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scroll-divider_visible___B7td6","gnScrollableWithScrollbarScrollDividerVisible":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scroll-divider_visible___B7td6","gn-scrollable-with-scrollbar__scrollbar-track":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scrollbar-track___u6MVN","gnScrollableWithScrollbarScrollbarTrack":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scrollbar-track___u6MVN","gn-scrollable-with-scrollbar__scrollbar-thumb":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scrollbar-thumb___bLf6h","gnScrollableWithScrollbarScrollbarThumb":"ScrollableWithScrollbar-module__gn-scrollable-with-scrollbar__scrollbar-thumb___bLf6h"};
2
2
 
3
3
  export { styles as default };
4
4
  //# sourceMappingURL=ScrollableWithScrollbar.module.scss.js.map
@@ -7,22 +7,22 @@ type UseScrollableScrollbarSyncResult = {
7
7
  scrollRef: React.RefObject<HTMLDivElement>;
8
8
  trackRef: React.RefObject<HTMLDivElement>;
9
9
  thumbRef: React.RefObject<HTMLDivElement>;
10
- hasContentBelow: boolean;
11
10
  overflows: boolean;
11
+ canScrollUp: boolean;
12
+ canScrollDown: boolean;
12
13
  thumb: ThumbGeometry;
13
14
  scheduleUpdate: () => void;
14
15
  handleThumbPointerDown: (event: React.PointerEvent<HTMLDivElement>) => void;
15
16
  handleTrackPointerDown: (event: React.PointerEvent<HTMLDivElement>) => void;
16
17
  };
17
18
  /**
18
- * Keeps a custom scrollbar thumb and bottom shadow in sync with a native
19
- * scroll layer. The scroll element handles touch/keyboard; wheel events on the
20
- * overlay track are forwarded to it (the track sits above the scroller, so
21
- * they would not scroll otherwise). Wheel, touch, and keyboard on the
22
- * scrollable area itself are unchanged.
19
+ * Keeps a custom scrollbar thumb in sync with a native scroll layer. The
20
+ * scroll element handles touch/keyboard; wheel events on the overlay track are
21
+ * forwarded to it (the track sits above the scroller, so they would not scroll
22
+ * otherwise). Wheel, touch, and keyboard on the scrollable area itself are
23
+ * unchanged.
23
24
  *
24
- * @param recalcDeps - extra deps that should trigger thumb/shadow recalculation
25
25
  * @returns refs, scroll state, thumb geometry, and pointer handlers for the UI
26
26
  */
27
- export declare function useScrollableScrollbarSync(recalcDeps?: React.DependencyList): UseScrollableScrollbarSyncResult;
27
+ export declare function useScrollableScrollbarSync(): UseScrollableScrollbarSyncResult;
28
28
  export {};
@@ -1,24 +1,39 @@
1
1
  import { useRef, useState, useCallback, useEffect, useLayoutEffect } from 'react';
2
2
 
3
- const EMPTY_DEPS = [];
4
3
  const MIN_THUMB_HEIGHT = 24;
5
4
  /**
6
- * Keeps a custom scrollbar thumb and bottom shadow in sync with a native
7
- * scroll layer. The scroll element handles touch/keyboard; wheel events on the
8
- * overlay track are forwarded to it (the track sits above the scroller, so
9
- * they would not scroll otherwise). Wheel, touch, and keyboard on the
10
- * scrollable area itself are unchanged.
5
+ * A fractional container height can make the integer scrollHeight exceed clientHeight
6
+ * by this many pixels. Such a delta is sub-pixel rounding, not meaningfully scrollable
7
+ * content, so it is not reported as overflow.
8
+ */
9
+ const SUBPIXEL_OVERFLOW_PX = 1;
10
+ /**
11
+ * Keeps a custom scrollbar thumb in sync with a native scroll layer. The
12
+ * scroll element handles touch/keyboard; wheel events on the overlay track are
13
+ * forwarded to it (the track sits above the scroller, so they would not scroll
14
+ * otherwise). Wheel, touch, and keyboard on the scrollable area itself are
15
+ * unchanged.
11
16
  *
12
- * @param recalcDeps - extra deps that should trigger thumb/shadow recalculation
13
17
  * @returns refs, scroll state, thumb geometry, and pointer handlers for the UI
14
18
  */
15
- function useScrollableScrollbarSync(recalcDeps = EMPTY_DEPS) {
19
+ function useScrollableScrollbarSync() {
16
20
  const scrollRef = useRef(null);
17
21
  const trackRef = useRef(null);
18
22
  const thumbRef = useRef(null);
19
- const [hasContentBelow, setHasContentBelow] = useState(false);
20
23
  const [overflows, setOverflows] = useState(false);
21
- const [thumb, setThumb] = useState({ top: 0, height: 0 });
24
+ const [geometry, setGeometry] = useState({
25
+ thumb: { top: 0, height: 0 },
26
+ canScrollUp: false,
27
+ canScrollDown: false,
28
+ });
29
+ const updateGeometry = useCallback((next) => {
30
+ setGeometry((previous) => previous.thumb.top === next.thumb.top &&
31
+ previous.thumb.height === next.thumb.height &&
32
+ previous.canScrollUp === next.canScrollUp &&
33
+ previous.canScrollDown === next.canScrollDown
34
+ ? previous
35
+ : next);
36
+ }, []);
22
37
  const rafIdRef = useRef(null);
23
38
  const scheduleUpdate = useCallback(() => {
24
39
  if (rafIdRef.current !== null) {
@@ -30,39 +45,64 @@ function useScrollableScrollbarSync(recalcDeps = EMPTY_DEPS) {
30
45
  if (!el) {
31
46
  return;
32
47
  }
33
- const { scrollTop, scrollHeight, clientHeight } = el;
34
- const isOverflowing = scrollHeight > clientHeight;
35
- // `-1` guards against subpixel rounding at the bottom.
36
- const notAtBottom = scrollTop + clientHeight < scrollHeight - 1;
48
+ const { scrollHeight, clientHeight } = el;
49
+ const isOverflowing = scrollHeight - clientHeight > SUBPIXEL_OVERFLOW_PX;
37
50
  setOverflows(isOverflowing);
38
- setHasContentBelow(isOverflowing && notAtBottom);
39
51
  if (!isOverflowing) {
40
- setThumb({ top: 0, height: 0 });
52
+ updateGeometry({
53
+ thumb: { top: 0, height: 0 },
54
+ canScrollUp: false,
55
+ canScrollDown: false,
56
+ });
41
57
  return;
42
58
  }
43
59
  const ratio = clientHeight / scrollHeight;
44
60
  const rawHeight = clientHeight * ratio;
45
61
  const height = Math.max(rawHeight, MIN_THUMB_HEIGHT);
46
62
  const maxTop = clientHeight - height;
63
+ const { scrollTop } = el;
47
64
  const scrollRatio = scrollHeight - clientHeight > 0 ? scrollTop / (scrollHeight - clientHeight) : 0;
48
65
  const top = maxTop * scrollRatio;
49
- setThumb({ top, height });
66
+ updateGeometry({
67
+ thumb: { top, height },
68
+ canScrollUp: isOverflowing && scrollTop > SUBPIXEL_OVERFLOW_PX,
69
+ canScrollDown: isOverflowing && scrollHeight - clientHeight - scrollTop > SUBPIXEL_OVERFLOW_PX,
70
+ });
50
71
  });
51
- }, []);
72
+ }, [updateGeometry]);
52
73
  useEffect(() => {
53
74
  const el = scrollRef.current;
54
75
  if (!el) {
55
76
  return undefined;
56
77
  }
57
78
  scheduleUpdate();
58
- if (typeof ResizeObserver === 'undefined') {
59
- return undefined;
79
+ // `ResizeObserver` is missing in jsdom, so keep it optional: the mutation
80
+ // observer below is set up either way.
81
+ const observer = typeof ResizeObserver === 'undefined' ? undefined : new ResizeObserver(scheduleUpdate);
82
+ observer === null || observer === undefined ? undefined : observer.observe(el);
83
+ // Observe the direct content child as well: its content-box changes whenever
84
+ // the rendered content changes (rows, titles, adornments, groups, density).
85
+ const contentEl = el.firstElementChild;
86
+ if (contentEl) {
87
+ observer === null || observer === undefined ? undefined : observer.observe(contentEl);
60
88
  }
61
- const observer = new ResizeObserver(scheduleUpdate);
62
- observer.observe(el);
63
- return () => observer.disconnect();
64
- // eslint-disable-next-line react-hooks/exhaustive-deps
65
- }, [scheduleUpdate, ...recalcDeps]);
89
+ // Content can also change without resizing any observed box: the collapse-mode
90
+ // menu resizes its content wrapper via an inline style (AutoSizer), which
91
+ // changes scrollHeight while every observed box stays the same, leaving the
92
+ // overflow state stale. Re-measure on content mutations too (rAF-throttled
93
+ // by scheduleUpdate).
94
+ const mutationObserver = new MutationObserver(scheduleUpdate);
95
+ mutationObserver.observe(el, {
96
+ childList: true,
97
+ subtree: true,
98
+ characterData: true,
99
+ attributes: true,
100
+ });
101
+ return () => {
102
+ observer === null || observer === undefined ? undefined : observer.disconnect();
103
+ mutationObserver.disconnect();
104
+ };
105
+ }, [scheduleUpdate]);
66
106
  useEffect(() => {
67
107
  return () => {
68
108
  if (rafIdRef.current !== null) {
@@ -153,17 +193,12 @@ function useScrollableScrollbarSync(recalcDeps = EMPTY_DEPS) {
153
193
  behavior: 'auto',
154
194
  });
155
195
  }, [cancelProgrammaticSmoothScroll]);
156
- return {
157
- scrollRef,
196
+ return Object.assign(Object.assign({ scrollRef,
158
197
  trackRef,
159
198
  thumbRef,
160
- hasContentBelow,
161
- overflows,
162
- thumb,
163
- scheduleUpdate,
199
+ overflows }, geometry), { scheduleUpdate,
164
200
  handleThumbPointerDown,
165
- handleTrackPointerDown,
166
- };
201
+ handleTrackPointerDown });
167
202
  }
168
203
 
169
204
  export { useScrollableScrollbarSync };
@@ -1 +1 @@
1
- {"version":3,"file":"useScrollableScrollbarSync.js","sources":["../../../../../../../../src/components/AsideHeader/components/CompositeBar/ScrollableWithScrollbar/useScrollableScrollbarSync.ts"],"sourcesContent":["import React, {useCallback, useEffect, useLayoutEffect, useRef, useState} from 'react';\n\nconst EMPTY_DEPS: React.DependencyList = [];\n\nconst MIN_THUMB_HEIGHT = 24;\n\ntype ThumbGeometry = {\n top: number;\n height: number;\n};\n\ntype UseScrollableScrollbarSyncResult = {\n scrollRef: React.RefObject<HTMLDivElement>;\n trackRef: React.RefObject<HTMLDivElement>;\n thumbRef: React.RefObject<HTMLDivElement>;\n hasContentBelow: boolean;\n overflows: boolean;\n thumb: ThumbGeometry;\n scheduleUpdate: () => void;\n handleThumbPointerDown: (event: React.PointerEvent<HTMLDivElement>) => void;\n handleTrackPointerDown: (event: React.PointerEvent<HTMLDivElement>) => void;\n};\n\n/**\n * Keeps a custom scrollbar thumb and bottom shadow in sync with a native\n * scroll layer. The scroll element handles touch/keyboard; wheel events on the\n * overlay track are forwarded to it (the track sits above the scroller, so\n * they would not scroll otherwise). Wheel, touch, and keyboard on the\n * scrollable area itself are unchanged.\n *\n * @param recalcDeps - extra deps that should trigger thumb/shadow recalculation\n * @returns refs, scroll state, thumb geometry, and pointer handlers for the UI\n */\nexport function useScrollableScrollbarSync(\n recalcDeps: React.DependencyList = EMPTY_DEPS,\n): UseScrollableScrollbarSyncResult {\n const scrollRef = useRef<HTMLDivElement>(null);\n const trackRef = useRef<HTMLDivElement>(null);\n const thumbRef = useRef<HTMLDivElement>(null);\n\n const [hasContentBelow, setHasContentBelow] = useState(false);\n const [overflows, setOverflows] = useState(false);\n const [thumb, setThumb] = useState<ThumbGeometry>({top: 0, height: 0});\n\n const rafIdRef = useRef<number | null>(null);\n const scheduleUpdate = useCallback(() => {\n if (rafIdRef.current !== null) {\n return;\n }\n\n rafIdRef.current = requestAnimationFrame(() => {\n rafIdRef.current = null;\n\n const el = scrollRef.current;\n\n if (!el) {\n return;\n }\n\n const {scrollTop, scrollHeight, clientHeight} = el;\n const isOverflowing = scrollHeight > clientHeight;\n // `-1` guards against subpixel rounding at the bottom.\n const notAtBottom = scrollTop + clientHeight < scrollHeight - 1;\n\n setOverflows(isOverflowing);\n setHasContentBelow(isOverflowing && notAtBottom);\n\n if (!isOverflowing) {\n setThumb({top: 0, height: 0});\n return;\n }\n\n const ratio = clientHeight / scrollHeight;\n const rawHeight = clientHeight * ratio;\n const height = Math.max(rawHeight, MIN_THUMB_HEIGHT);\n const maxTop = clientHeight - height;\n const scrollRatio =\n scrollHeight - clientHeight > 0 ? scrollTop / (scrollHeight - clientHeight) : 0;\n const top = maxTop * scrollRatio;\n\n setThumb({top, height});\n });\n }, []);\n\n useEffect(() => {\n const el = scrollRef.current;\n\n if (!el) {\n return undefined;\n }\n\n scheduleUpdate();\n\n if (typeof ResizeObserver === 'undefined') {\n return undefined;\n }\n\n const observer = new ResizeObserver(scheduleUpdate);\n observer.observe(el);\n return () => observer.disconnect();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [scheduleUpdate, ...recalcDeps]);\n\n useEffect(() => {\n return () => {\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n rafIdRef.current = null;\n }\n };\n }, []);\n\n // Wheel events do not reach the native scroll layer when the cursor is over\n // the overlay track — forward them explicitly. `passive: false` is required\n // so `preventDefault` works in all browsers.\n useLayoutEffect(() => {\n if (!overflows) {\n return undefined;\n }\n\n const track = trackRef.current;\n const scrollEl = scrollRef.current;\n\n if (!track || !scrollEl) {\n return undefined;\n }\n\n const onWheel = (e: WheelEvent) => {\n e.preventDefault();\n scrollEl.scrollTop += e.deltaY;\n };\n\n track.addEventListener('wheel', onWheel, {passive: false});\n return () => track.removeEventListener('wheel', onWheel);\n }, [overflows]);\n\n const cancelProgrammaticSmoothScroll = useCallback((scrollEl: HTMLDivElement) => {\n const top = scrollEl.scrollTop;\n scrollEl.scrollTo({top, behavior: 'auto'});\n }, []);\n\n const handleThumbPointerDown = useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n const scrollEl = scrollRef.current;\n const thumbEl = thumbRef.current;\n\n if (!scrollEl || !thumbEl || event.button !== 0) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n cancelProgrammaticSmoothScroll(scrollEl);\n\n const startY = event.clientY;\n const startScrollTop = scrollEl.scrollTop;\n const {scrollHeight, clientHeight} = scrollEl;\n const thumbHeight = thumbEl.getBoundingClientRect().height;\n const trackHeight = clientHeight;\n const maxThumbTop = trackHeight - thumbHeight;\n const maxScrollTop = scrollHeight - clientHeight;\n\n if (maxThumbTop <= 0 || maxScrollTop <= 0) {\n return;\n }\n\n const handlePointerMove = (moveEvent: PointerEvent) => {\n const deltaY = moveEvent.clientY - startY;\n const deltaScroll = (deltaY / maxThumbTop) * maxScrollTop;\n scrollEl.scrollTop = startScrollTop + deltaScroll;\n };\n\n const handlePointerUp = () => {\n window.removeEventListener('pointermove', handlePointerMove);\n window.removeEventListener('pointerup', handlePointerUp);\n window.removeEventListener('pointercancel', handlePointerUp);\n };\n\n window.addEventListener('pointermove', handlePointerMove);\n window.addEventListener('pointerup', handlePointerUp);\n window.addEventListener('pointercancel', handlePointerUp);\n },\n [cancelProgrammaticSmoothScroll],\n );\n\n const handleTrackPointerDown = useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n const scrollEl = scrollRef.current;\n const thumbEl = thumbRef.current;\n\n if (\n !scrollEl ||\n !thumbEl ||\n event.button !== 0 ||\n event.target !== event.currentTarget\n ) {\n return;\n }\n\n cancelProgrammaticSmoothScroll(scrollEl);\n\n const trackRect = event.currentTarget.getBoundingClientRect();\n const thumbHeight = thumbEl.getBoundingClientRect().height;\n const clickY = event.clientY - trackRect.top;\n const targetThumbTop = Math.max(\n 0,\n Math.min(clickY - thumbHeight / 2, trackRect.height - thumbHeight),\n );\n const maxThumbTop = trackRect.height - thumbHeight;\n const maxScrollTop = scrollEl.scrollHeight - scrollEl.clientHeight;\n\n if (maxThumbTop <= 0 || maxScrollTop <= 0) {\n return;\n }\n\n // `auto` avoids racing with a subsequent thumb drag (smooth scroll would\n // still animate while pointer handlers update `scrollTop`).\n scrollEl.scrollTo({\n top: (targetThumbTop / maxThumbTop) * maxScrollTop,\n behavior: 'auto',\n });\n },\n [cancelProgrammaticSmoothScroll],\n );\n\n return {\n scrollRef,\n trackRef,\n thumbRef,\n hasContentBelow,\n overflows,\n thumb,\n scheduleUpdate,\n handleThumbPointerDown,\n handleTrackPointerDown,\n };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useScrollableScrollbarSync.js","sources":["../../../../../../../../src/components/AsideHeader/components/CompositeBar/ScrollableWithScrollbar/useScrollableScrollbarSync.ts"],"sourcesContent":["import React, {useCallback, useEffect, useLayoutEffect, useRef, useState} from 'react';\n\nconst MIN_THUMB_HEIGHT = 24;\n\n/**\n * A fractional container height can make the integer scrollHeight exceed clientHeight\n * by this many pixels. Such a delta is sub-pixel rounding, not meaningfully scrollable\n * content, so it is not reported as overflow.\n */\nconst SUBPIXEL_OVERFLOW_PX = 1;\n\ntype ThumbGeometry = {\n top: number;\n height: number;\n};\n\ntype UseScrollableScrollbarSyncResult = {\n scrollRef: React.RefObject<HTMLDivElement>;\n trackRef: React.RefObject<HTMLDivElement>;\n thumbRef: React.RefObject<HTMLDivElement>;\n overflows: boolean;\n canScrollUp: boolean;\n canScrollDown: boolean;\n thumb: ThumbGeometry;\n scheduleUpdate: () => void;\n handleThumbPointerDown: (event: React.PointerEvent<HTMLDivElement>) => void;\n handleTrackPointerDown: (event: React.PointerEvent<HTMLDivElement>) => void;\n};\n\n/**\n * Keeps a custom scrollbar thumb in sync with a native scroll layer. The\n * scroll element handles touch/keyboard; wheel events on the overlay track are\n * forwarded to it (the track sits above the scroller, so they would not scroll\n * otherwise). Wheel, touch, and keyboard on the scrollable area itself are\n * unchanged.\n *\n * @returns refs, scroll state, thumb geometry, and pointer handlers for the UI\n */\nexport function useScrollableScrollbarSync(): UseScrollableScrollbarSyncResult {\n const scrollRef = useRef<HTMLDivElement>(null);\n const trackRef = useRef<HTMLDivElement>(null);\n const thumbRef = useRef<HTMLDivElement>(null);\n\n const [overflows, setOverflows] = useState(false);\n const [geometry, setGeometry] = useState({\n thumb: {top: 0, height: 0} as ThumbGeometry,\n canScrollUp: false,\n canScrollDown: false,\n });\n\n const updateGeometry = useCallback((next: typeof geometry) => {\n setGeometry((previous) =>\n previous.thumb.top === next.thumb.top &&\n previous.thumb.height === next.thumb.height &&\n previous.canScrollUp === next.canScrollUp &&\n previous.canScrollDown === next.canScrollDown\n ? previous\n : next,\n );\n }, []);\n\n const rafIdRef = useRef<number | null>(null);\n const scheduleUpdate = useCallback(() => {\n if (rafIdRef.current !== null) {\n return;\n }\n\n rafIdRef.current = requestAnimationFrame(() => {\n rafIdRef.current = null;\n\n const el = scrollRef.current;\n\n if (!el) {\n return;\n }\n\n const {scrollHeight, clientHeight} = el;\n const isOverflowing = scrollHeight - clientHeight > SUBPIXEL_OVERFLOW_PX;\n\n setOverflows(isOverflowing);\n\n if (!isOverflowing) {\n updateGeometry({\n thumb: {top: 0, height: 0},\n canScrollUp: false,\n canScrollDown: false,\n });\n return;\n }\n\n const ratio = clientHeight / scrollHeight;\n const rawHeight = clientHeight * ratio;\n const height = Math.max(rawHeight, MIN_THUMB_HEIGHT);\n const maxTop = clientHeight - height;\n const {scrollTop} = el;\n const scrollRatio =\n scrollHeight - clientHeight > 0 ? scrollTop / (scrollHeight - clientHeight) : 0;\n const top = maxTop * scrollRatio;\n\n updateGeometry({\n thumb: {top, height},\n canScrollUp: isOverflowing && scrollTop > SUBPIXEL_OVERFLOW_PX,\n canScrollDown:\n isOverflowing && scrollHeight - clientHeight - scrollTop > SUBPIXEL_OVERFLOW_PX,\n });\n });\n }, [updateGeometry]);\n\n useEffect(() => {\n const el = scrollRef.current;\n\n if (!el) {\n return undefined;\n }\n\n scheduleUpdate();\n\n // `ResizeObserver` is missing in jsdom, so keep it optional: the mutation\n // observer below is set up either way.\n const observer =\n typeof ResizeObserver === 'undefined' ? undefined : new ResizeObserver(scheduleUpdate);\n observer?.observe(el);\n // Observe the direct content child as well: its content-box changes whenever\n // the rendered content changes (rows, titles, adornments, groups, density).\n const contentEl = el.firstElementChild;\n if (contentEl) {\n observer?.observe(contentEl);\n }\n\n // Content can also change without resizing any observed box: the collapse-mode\n // menu resizes its content wrapper via an inline style (AutoSizer), which\n // changes scrollHeight while every observed box stays the same, leaving the\n // overflow state stale. Re-measure on content mutations too (rAF-throttled\n // by scheduleUpdate).\n const mutationObserver = new MutationObserver(scheduleUpdate);\n mutationObserver.observe(el, {\n childList: true,\n subtree: true,\n characterData: true,\n attributes: true,\n });\n\n return () => {\n observer?.disconnect();\n mutationObserver.disconnect();\n };\n }, [scheduleUpdate]);\n\n useEffect(() => {\n return () => {\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n rafIdRef.current = null;\n }\n };\n }, []);\n\n // Wheel events do not reach the native scroll layer when the cursor is over\n // the overlay track — forward them explicitly. `passive: false` is required\n // so `preventDefault` works in all browsers.\n useLayoutEffect(() => {\n if (!overflows) {\n return undefined;\n }\n\n const track = trackRef.current;\n const scrollEl = scrollRef.current;\n\n if (!track || !scrollEl) {\n return undefined;\n }\n\n const onWheel = (e: WheelEvent) => {\n e.preventDefault();\n scrollEl.scrollTop += e.deltaY;\n };\n\n track.addEventListener('wheel', onWheel, {passive: false});\n return () => track.removeEventListener('wheel', onWheel);\n }, [overflows]);\n\n const cancelProgrammaticSmoothScroll = useCallback((scrollEl: HTMLDivElement) => {\n const top = scrollEl.scrollTop;\n scrollEl.scrollTo({top, behavior: 'auto'});\n }, []);\n\n const handleThumbPointerDown = useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n const scrollEl = scrollRef.current;\n const thumbEl = thumbRef.current;\n\n if (!scrollEl || !thumbEl || event.button !== 0) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n cancelProgrammaticSmoothScroll(scrollEl);\n\n const startY = event.clientY;\n const startScrollTop = scrollEl.scrollTop;\n const {scrollHeight, clientHeight} = scrollEl;\n const thumbHeight = thumbEl.getBoundingClientRect().height;\n const trackHeight = clientHeight;\n const maxThumbTop = trackHeight - thumbHeight;\n const maxScrollTop = scrollHeight - clientHeight;\n\n if (maxThumbTop <= 0 || maxScrollTop <= 0) {\n return;\n }\n\n const handlePointerMove = (moveEvent: PointerEvent) => {\n const deltaY = moveEvent.clientY - startY;\n const deltaScroll = (deltaY / maxThumbTop) * maxScrollTop;\n scrollEl.scrollTop = startScrollTop + deltaScroll;\n };\n\n const handlePointerUp = () => {\n window.removeEventListener('pointermove', handlePointerMove);\n window.removeEventListener('pointerup', handlePointerUp);\n window.removeEventListener('pointercancel', handlePointerUp);\n };\n\n window.addEventListener('pointermove', handlePointerMove);\n window.addEventListener('pointerup', handlePointerUp);\n window.addEventListener('pointercancel', handlePointerUp);\n },\n [cancelProgrammaticSmoothScroll],\n );\n\n const handleTrackPointerDown = useCallback(\n (event: React.PointerEvent<HTMLDivElement>) => {\n const scrollEl = scrollRef.current;\n const thumbEl = thumbRef.current;\n\n if (\n !scrollEl ||\n !thumbEl ||\n event.button !== 0 ||\n event.target !== event.currentTarget\n ) {\n return;\n }\n\n cancelProgrammaticSmoothScroll(scrollEl);\n\n const trackRect = event.currentTarget.getBoundingClientRect();\n const thumbHeight = thumbEl.getBoundingClientRect().height;\n const clickY = event.clientY - trackRect.top;\n const targetThumbTop = Math.max(\n 0,\n Math.min(clickY - thumbHeight / 2, trackRect.height - thumbHeight),\n );\n const maxThumbTop = trackRect.height - thumbHeight;\n const maxScrollTop = scrollEl.scrollHeight - scrollEl.clientHeight;\n\n if (maxThumbTop <= 0 || maxScrollTop <= 0) {\n return;\n }\n\n // `auto` avoids racing with a subsequent thumb drag (smooth scroll would\n // still animate while pointer handlers update `scrollTop`).\n scrollEl.scrollTo({\n top: (targetThumbTop / maxThumbTop) * maxScrollTop,\n behavior: 'auto',\n });\n },\n [cancelProgrammaticSmoothScroll],\n );\n\n return {\n scrollRef,\n trackRef,\n thumbRef,\n overflows,\n ...geometry,\n scheduleUpdate,\n handleThumbPointerDown,\n handleTrackPointerDown,\n };\n}\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  export declare const ITEM_TYPE_REGULAR = "regular";
2
2
  export declare const COLLAPSE_ITEM_ID = "collapse-item-id";
3
+ export declare const COMPOSITE_BAR_ITEM_ID_ATTRIBUTE = "data-gn-composite-bar-item-id";
3
4
  /** Prefix for synthetic CompositeBar row ids for grouped section headers ({@link makeGroupHeaderAsideItem}). */
4
5
  export declare const COMPOSITE_BAR_GROUP_HEADER_ID_PREFIX: "__gn-composite-bar__group-header__";
@@ -1,7 +1,8 @@
1
1
  const ITEM_TYPE_REGULAR = 'regular';
2
2
  const COLLAPSE_ITEM_ID = 'collapse-item-id';
3
+ const COMPOSITE_BAR_ITEM_ID_ATTRIBUTE = 'data-gn-composite-bar-item-id';
3
4
  /** Prefix for synthetic CompositeBar row ids for grouped section headers ({@link makeGroupHeaderAsideItem}). */
4
5
  const COMPOSITE_BAR_GROUP_HEADER_ID_PREFIX = '__gn-composite-bar__group-header__';
5
6
 
6
- export { COLLAPSE_ITEM_ID, COMPOSITE_BAR_GROUP_HEADER_ID_PREFIX, ITEM_TYPE_REGULAR };
7
+ export { COLLAPSE_ITEM_ID, COMPOSITE_BAR_GROUP_HEADER_ID_PREFIX, COMPOSITE_BAR_ITEM_ID_ATTRIBUTE, ITEM_TYPE_REGULAR };
7
8
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sources":["../../../../../../../src/components/AsideHeader/components/CompositeBar/constants.ts"],"sourcesContent":["export const ITEM_TYPE_REGULAR = 'regular';\nexport const COLLAPSE_ITEM_ID = 'collapse-item-id';\n\n/** Prefix for synthetic CompositeBar row ids for grouped section headers ({@link makeGroupHeaderAsideItem}). */\nexport const COMPOSITE_BAR_GROUP_HEADER_ID_PREFIX = '__gn-composite-bar__group-header__' as const;\n"],"names":[],"mappings":"AAAO,MAAM,iBAAiB,GAAG;AAC1B,MAAM,gBAAgB,GAAG;AAEhC;AACO,MAAM,oCAAoC,GAAG;;;;"}
1
+ {"version":3,"file":"constants.js","sources":["../../../../../../../src/components/AsideHeader/components/CompositeBar/constants.ts"],"sourcesContent":["export const ITEM_TYPE_REGULAR = 'regular';\nexport const COLLAPSE_ITEM_ID = 'collapse-item-id';\nexport const COMPOSITE_BAR_ITEM_ID_ATTRIBUTE = 'data-gn-composite-bar-item-id';\n\n/** Prefix for synthetic CompositeBar row ids for grouped section headers ({@link makeGroupHeaderAsideItem}). */\nexport const COMPOSITE_BAR_GROUP_HEADER_ID_PREFIX = '__gn-composite-bar__group-header__' as const;\n"],"names":[],"mappings":"AAAO,MAAM,iBAAiB,GAAG;AAC1B,MAAM,gBAAgB,GAAG;AACzB,MAAM,+BAA+B,GAAG;AAE/C;AACO,MAAM,oCAAoC,GAAG;;;;"}
@@ -0,0 +1,24 @@
1
+ import type { AsideHeaderItem } from '../../types';
2
+ type PresentationCurrentOptions = {
3
+ suppressCurrentItemIds?: ReadonlySet<string>;
4
+ popupItems?: AsideHeaderItem[];
5
+ };
6
+ /**
7
+ * Resolves the semantic ids represented by a visually current row. Popup parents aggregate the
8
+ * ids recursively, while synthetic group and More rows contribute only their current descendants.
9
+ *
10
+ * @param item - The row item whose presentation state is being resolved.
11
+ * @param options - Suppression and optional popup children resolved by the caller.
12
+ * @returns Sorted unique ids of unsuppressed current items represented by the row.
13
+ */
14
+ export declare function getItemPresentationCurrentIds(item: AsideHeaderItem, options?: PresentationCurrentOptions): string[];
15
+ /**
16
+ * Resolves the visual current state without changing the public item. Popup parents aggregate the
17
+ * state recursively, so group and More rows follow the same suppression rules as leaf rows.
18
+ *
19
+ * @param item - The row item whose presentation state is being resolved.
20
+ * @param options - Suppression and optional popup children resolved by the caller.
21
+ * @returns Whether the row or one of its popup descendants should look current.
22
+ */
23
+ export declare function isItemPresentationCurrent(item: AsideHeaderItem, options?: PresentationCurrentOptions): boolean;
24
+ export {};
@@ -0,0 +1,36 @@
1
+ function collectItemPresentationCurrentIds(item, suppressCurrentItemIds, popupItems, currentIds) {
2
+ if (item.current && !(suppressCurrentItemIds === null || suppressCurrentItemIds === undefined ? undefined : suppressCurrentItemIds.has(item.id))) {
3
+ currentIds.add(item.id);
4
+ }
5
+ popupItems === null || popupItems === undefined ? undefined : popupItems.forEach((popupItem) => {
6
+ collectItemPresentationCurrentIds(popupItem, suppressCurrentItemIds, popupItem.compositeBarMenuPopupItems, currentIds);
7
+ });
8
+ }
9
+ /**
10
+ * Resolves the semantic ids represented by a visually current row. Popup parents aggregate the
11
+ * ids recursively, while synthetic group and More rows contribute only their current descendants.
12
+ *
13
+ * @param item - The row item whose presentation state is being resolved.
14
+ * @param options - Suppression and optional popup children resolved by the caller.
15
+ * @returns Sorted unique ids of unsuppressed current items represented by the row.
16
+ */
17
+ function getItemPresentationCurrentIds(item, options = {}) {
18
+ const { suppressCurrentItemIds, popupItems = item.compositeBarMenuPopupItems } = options;
19
+ const currentIds = new Set();
20
+ collectItemPresentationCurrentIds(item, suppressCurrentItemIds, popupItems, currentIds);
21
+ return Array.from(currentIds).sort();
22
+ }
23
+ /**
24
+ * Resolves the visual current state without changing the public item. Popup parents aggregate the
25
+ * state recursively, so group and More rows follow the same suppression rules as leaf rows.
26
+ *
27
+ * @param item - The row item whose presentation state is being resolved.
28
+ * @param options - Suppression and optional popup children resolved by the caller.
29
+ * @returns Whether the row or one of its popup descendants should look current.
30
+ */
31
+ function isItemPresentationCurrent(item, options = {}) {
32
+ return getItemPresentationCurrentIds(item, options).length > 0;
33
+ }
34
+
35
+ export { getItemPresentationCurrentIds, isItemPresentationCurrent };
36
+ //# sourceMappingURL=presentationCurrent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentationCurrent.js","sources":["../../../../../../../src/components/AsideHeader/components/CompositeBar/presentationCurrent.ts"],"sourcesContent":["import type {AsideHeaderItem} from '../../types';\n\ntype PresentationCurrentOptions = {\n suppressCurrentItemIds?: ReadonlySet<string>;\n popupItems?: AsideHeaderItem[];\n};\n\nfunction collectItemPresentationCurrentIds(\n item: AsideHeaderItem,\n suppressCurrentItemIds: ReadonlySet<string> | undefined,\n popupItems: AsideHeaderItem[] | undefined,\n currentIds: Set<string>,\n) {\n if (item.current && !suppressCurrentItemIds?.has(item.id)) {\n currentIds.add(item.id);\n }\n\n popupItems?.forEach((popupItem) => {\n collectItemPresentationCurrentIds(\n popupItem,\n suppressCurrentItemIds,\n popupItem.compositeBarMenuPopupItems,\n currentIds,\n );\n });\n}\n\n/**\n * Resolves the semantic ids represented by a visually current row. Popup parents aggregate the\n * ids recursively, while synthetic group and More rows contribute only their current descendants.\n *\n * @param item - The row item whose presentation state is being resolved.\n * @param options - Suppression and optional popup children resolved by the caller.\n * @returns Sorted unique ids of unsuppressed current items represented by the row.\n */\nexport function getItemPresentationCurrentIds(\n item: AsideHeaderItem,\n options: PresentationCurrentOptions = {},\n): string[] {\n const {suppressCurrentItemIds, popupItems = item.compositeBarMenuPopupItems} = options;\n const currentIds = new Set<string>();\n\n collectItemPresentationCurrentIds(item, suppressCurrentItemIds, popupItems, currentIds);\n\n return Array.from(currentIds).sort();\n}\n\n/**\n * Resolves the visual current state without changing the public item. Popup parents aggregate the\n * state recursively, so group and More rows follow the same suppression rules as leaf rows.\n *\n * @param item - The row item whose presentation state is being resolved.\n * @param options - Suppression and optional popup children resolved by the caller.\n * @returns Whether the row or one of its popup descendants should look current.\n */\nexport function isItemPresentationCurrent(\n item: AsideHeaderItem,\n options: PresentationCurrentOptions = {},\n): boolean {\n return getItemPresentationCurrentIds(item, options).length > 0;\n}\n"],"names":[],"mappings":"AAOA,SAAS,iCAAiC,CACtC,IAAqB,EACrB,sBAAuD,EACvD,UAAyC,EACzC,UAAuB,EAAA;IAEvB,IAAI,IAAI,CAAC,OAAO,IAAI,EAAC,sBAAsB,aAAtB,sBAAsB,KAAA,SAAA,GAAA,SAAA,GAAtB,sBAAsB,CAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA,EAAE;AACvD,QAAA,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;;IAG3B,UAAU,KAAA,IAAA,IAAV,UAAU,KAAA,SAAA,GAAA,SAAA,GAAV,UAAU,CAAE,OAAO,CAAC,CAAC,SAAS,KAAI;QAC9B,iCAAiC,CAC7B,SAAS,EACT,sBAAsB,EACtB,SAAS,CAAC,0BAA0B,EACpC,UAAU,CACb;AACL,KAAC,CAAC;AACN;AAEA;;;;;;;AAOG;SACa,6BAA6B,CACzC,IAAqB,EACrB,UAAsC,EAAE,EAAA;IAExC,MAAM,EAAC,sBAAsB,EAAE,UAAU,GAAG,IAAI,CAAC,0BAA0B,EAAC,GAAG,OAAO;AACtF,IAAA,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU;IAEpC,iCAAiC,CAAC,IAAI,EAAE,sBAAsB,EAAE,UAAU,EAAE,UAAU,CAAC;IAEvF,OAAO,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE;AACxC;AAEA;;;;;;;AAOG;SACa,yBAAyB,CACrC,IAAqB,EACrB,UAAsC,EAAE,EAAA;IAExC,OAAO,6BAA6B,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC;AAClE;;;;"}
@@ -1,12 +1,16 @@
1
1
  import { MenuGroup } from '../../../types';
2
+ import { AsideHeaderMenuDensity } from '../../density';
2
3
  import { AsideHeaderItem } from '../../types';
3
4
  import type { CompositeBarRow } from './grouping';
4
- export declare function getItemHeight(compositeItem: AsideHeaderItem): 40 | 50 | 15;
5
+ type CompositeBarItemLayoutOptions = {
6
+ /** Collapsed sidebar (icon-only rows): multi-line titles use the regular row height. */
7
+ sidebarCompact?: boolean;
8
+ };
9
+ export declare function getItemHeight(compositeItem: AsideHeaderItem, menuDensity?: AsideHeaderMenuDensity, layout?: CompositeBarItemLayoutOptions): number;
5
10
  export declare function getPopupItemHeight(compositeItem: AsideHeaderItem): 32 | 50 | 15;
6
- export declare function getItemsHeight<T extends AsideHeaderItem>(items: T[]): number;
11
+ export declare function getItemsHeight<T extends AsideHeaderItem>(items: T[], menuDensity?: AsideHeaderMenuDensity, layout?: CompositeBarItemLayoutOptions): number;
7
12
  export declare function getPopupItemsHeight<T extends AsideHeaderItem>(items: T[]): number;
8
- export declare function getSelectedItemIndex(compositeItems: AsideHeaderItem[]): number | undefined;
9
- export declare function getMoreButtonItem(menuMoreTitle?: string): AsideHeaderItem;
13
+ export declare function getMoreButtonItem(menuMoreTitle?: string, menuDensity?: AsideHeaderMenuDensity): AsideHeaderItem;
10
14
  export declare function makeGroupHeaderAsideItem(group: MenuGroup): AsideHeaderItem;
11
15
  /**
12
16
  * Moves rows whose item has `afterMoreButton` to the end (parity with scroll vs collapse DOM order).
@@ -15,9 +19,10 @@ export declare function makeGroupHeaderAsideItem(group: MenuGroup): AsideHeaderI
15
19
  * @returns Rows with `afterMoreButton` item rows last, or the same array reference when none.
16
20
  */
17
21
  export declare function getReorderedCompositeBarRows(rows: CompositeBarRow[]): CompositeBarRow[];
18
- export declare function getCompositeBarRowsMinHeight(rows: CompositeBarRow[]): number;
19
- export declare function getSelectedCompositeBarRowIndex(rows: CompositeBarRow[]): number | undefined;
20
- export declare function getAutosizeCompositeBarRows(rows: CompositeBarRow[], height: number, collapseItem: AsideHeaderItem): {
22
+ export declare function getCompositeBarRowsMinHeight(rows: CompositeBarRow[], menuDensity?: AsideHeaderMenuDensity, layout?: CompositeBarItemLayoutOptions): number;
23
+ export declare function getSelectedCompositeBarRowIndex(rows: CompositeBarRow[], suppressCurrentItemIds?: ReadonlySet<string>): number | undefined;
24
+ export declare function getAutosizeCompositeBarRows(rows: CompositeBarRow[], height: number, collapseItem: AsideHeaderItem, menuDensity?: AsideHeaderMenuDensity, layout?: CompositeBarItemLayoutOptions): {
21
25
  listRows: CompositeBarRow[];
22
26
  collapseItems: AsideHeaderItem[];
23
27
  };
28
+ export {};