@geotab/zenith 3.10.0-beta.7 → 3.11.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 (317) hide show
  1. package/README.md +33 -0
  2. package/dist/calendar/calendar.js +7 -4
  3. package/dist/card/components/title.js +4 -1
  4. package/dist/card/components/titleLink.js +5 -2
  5. package/dist/chart/barChart/getDefaultOptions.d.ts +2 -1
  6. package/dist/chart/barChart/getDefaultOptions.js +5 -2
  7. package/dist/chart/barChart.js +6 -4
  8. package/dist/chart/lineChart/getDefaultOptions.d.ts +2 -1
  9. package/dist/chart/lineChart/getDefaultOptions.js +5 -2
  10. package/dist/chart/lineChart.js +4 -2
  11. package/dist/checkboxListWithAction/checkboxListWithAction.js +4 -1
  12. package/dist/commonHelpers/arrowNavigation/components/arrowButton/arrowButton.js +4 -1
  13. package/dist/commonStyles/pillStyles/pillContent.less +13 -14
  14. package/dist/commonStyles/pillStyles/pillStyles.less +4 -5
  15. package/dist/commonStyles/pillStyles/pillTextContent.less +2 -2
  16. package/dist/commonStyles/typography/typography.less +579 -19
  17. package/dist/controlledPopup/controlledPopup.d.ts +1 -0
  18. package/dist/controlledPopup/controlledPopup.js +3 -1
  19. package/dist/dataGrid/cell/cell.d.ts +2 -1
  20. package/dist/dataGrid/cell/cell.js +2 -2
  21. package/dist/dataGrid/dataGrid.js +7 -4
  22. package/dist/dataGrid/listColumn.d.ts +2 -0
  23. package/dist/dataGrid/row/row.d.ts +2 -1
  24. package/dist/dataGrid/row/row.js +13 -9
  25. package/dist/dataGrid/withFlexibleColumns/components/columnSettingsList.js +2 -1
  26. package/dist/dataGrid/withSelectableRows/components/bulkActions/bulkActions.d.ts +4 -0
  27. package/dist/dateRangeInner/dateRangeInner.js +5 -2
  28. package/dist/dateRangeRaw/dateRangeRaw.js +5 -2
  29. package/dist/dateRangeRaw/utils/parseLabel.js +1 -1
  30. package/dist/dropdownRaw/dropdownRaw.js +12 -6
  31. package/dist/fileUpload/components/dropZoneContent.js +100 -100
  32. package/dist/fileUpload/fileUpload.js +100 -100
  33. package/dist/filters/components/filtersSearchList.js +4 -1
  34. package/dist/filtersBar/filtersContainer/filtersContainer.js +62 -61
  35. package/dist/formStepperButtons/formStepperButtons.js +4 -1
  36. package/dist/groupsFilterRaw/groupsFilterAdjustmentState.js +4 -1
  37. package/dist/groupsFilterRaw/groupsFilterInitialState.js +4 -1
  38. package/dist/header/headerBack.js +4 -1
  39. package/dist/icons/iconAlignLeft.js +1 -3
  40. package/dist/icons/iconAlignmentLeft.js +1 -3
  41. package/dist/icons/iconAlignmentRight.js +1 -3
  42. package/dist/icons/iconArrowBottomLeft.js +1 -3
  43. package/dist/icons/iconArrowBottomRight.js +1 -3
  44. package/dist/icons/iconArrowLeftPath.js +1 -3
  45. package/dist/icons/iconArrowRight.js +1 -3
  46. package/dist/icons/iconArrowRightCircle.js +1 -3
  47. package/dist/icons/iconArrowRightPath.js +1 -3
  48. package/dist/icons/iconArrowTopLeft.js +1 -3
  49. package/dist/icons/iconArrowTopRight.js +1 -3
  50. package/dist/icons/iconChevronDoubleRight.js +1 -3
  51. package/dist/icons/iconChevronRight.js +1 -3
  52. package/dist/icons/iconChevronRightSmall.js +1 -3
  53. package/dist/icons/iconCornerDownLeft.js +1 -3
  54. package/dist/icons/iconCornerDownRight.js +1 -3
  55. package/dist/icons/iconCornerLeftDown.js +1 -3
  56. package/dist/icons/iconCornerLeftUp.js +1 -3
  57. package/dist/icons/iconCornerRightDown.js +1 -3
  58. package/dist/icons/iconCornerRightUp.js +1 -3
  59. package/dist/icons/iconCornerUpLeft.js +1 -3
  60. package/dist/icons/iconCornerUpRight.js +1 -3
  61. package/dist/index.css +3257 -2925
  62. package/dist/index.d.ts +1 -0
  63. package/dist/index.js +3 -1
  64. package/dist/lineChartMini/lineChartMini.js +15 -3
  65. package/dist/list/itemData/itemDataInternal.js +4 -1
  66. package/dist/list/list.d.ts +1 -0
  67. package/dist/list/list.js +2 -2
  68. package/dist/list/listItem/listItem.d.ts +1 -3
  69. package/dist/list/listItem/listItem.js +6 -5
  70. package/dist/menu/components/controlledMenuList/controlledMenuList.d.ts +27 -0
  71. package/dist/menu/components/controlledMenuList/controlledMenuList.js +126 -0
  72. package/dist/menu/components/createControlledMenuList.d.ts +37 -0
  73. package/dist/menu/components/createControlledMenuList.js +55 -0
  74. package/dist/menu/components/createMenuItem.d.ts +67 -0
  75. package/dist/menu/components/createMenuItem.js +97 -0
  76. package/dist/menu/components/menuButton.js +12 -3
  77. package/dist/menu/components/menuItem.d.ts +1 -2
  78. package/dist/menu/components/menuItem.js +20 -74
  79. package/dist/menu/contexts/usePathContext.d.ts +2 -0
  80. package/dist/menu/contexts/usePathContext.js +9 -0
  81. package/dist/menu/controlledMenu.js +8 -175
  82. package/dist/menu/utils/buildMenuContent.d.ts +2 -0
  83. package/dist/menu/utils/buildMenuContent.js +38 -0
  84. package/dist/menu/utils/findContent.d.ts +2 -2
  85. package/dist/menu/utils/findContent.js +4 -3
  86. package/dist/menu/utils/getItemLabel.d.ts +2 -0
  87. package/dist/menu/utils/getItemLabel.js +8 -0
  88. package/dist/menu/utils/getSafeRel.d.ts +1 -0
  89. package/dist/menu/utils/getSafeRel.js +14 -0
  90. package/dist/menu/utils/isMenuItem.d.ts +2 -0
  91. package/dist/menu/utils/isMenuItem.js +13 -0
  92. package/dist/menu/utils/isSafeHref.d.ts +1 -0
  93. package/dist/menu/utils/isSafeHref.js +10 -0
  94. package/dist/menu/utils/normalizeSeparators.d.ts +2 -0
  95. package/dist/menu/utils/normalizeSeparators.js +23 -0
  96. package/dist/menu/utils/resolveKeys.d.ts +12 -0
  97. package/dist/menu/utils/resolveKeys.js +22 -0
  98. package/dist/menu/utils/useLastValidSheet.d.ts +7 -0
  99. package/dist/menu/utils/useLastValidSheet.js +30 -0
  100. package/dist/menu/utils/useMenuItemCore.d.ts +31 -0
  101. package/dist/menu/utils/useMenuItemCore.js +54 -0
  102. package/dist/menu/utils/useMenuItemKeyboardNav.d.ts +2 -0
  103. package/dist/menu/utils/useMenuItemKeyboardNav.js +15 -0
  104. package/dist/menu/utils/useMenuListKeyboardNav.d.ts +12 -0
  105. package/dist/menu/utils/useMenuListKeyboardNav.js +77 -0
  106. package/dist/menu/utils/useMenuPath.d.ts +6 -0
  107. package/dist/menu/utils/useMenuPath.js +35 -0
  108. package/dist/nav/navItem/navItem.js +10 -5
  109. package/dist/nav/navSection/navSection.js +7 -5
  110. package/dist/pagination/paginationArrow.js +10 -3
  111. package/dist/radioGroupRaw/radioGroupRaw.js +2 -1
  112. package/dist/rangeRaw/rangeRaw.js +0 -1
  113. package/dist/selectList/selectList.helpers.d.ts +1 -1
  114. package/dist/selectList/selectList.helpers.js +29 -4
  115. package/dist/selectList/selectList.js +3 -1
  116. package/dist/selectList/selectList.reducer.js +1 -2
  117. package/dist/selectList/selectListItem.js +4 -1
  118. package/dist/sortControl/sortControl.js +59 -4
  119. package/dist/table/children/useTableChildren.d.ts +1 -1
  120. package/dist/table/children/useTableChildren.js +3 -3
  121. package/dist/table/flexible/columnsList.js +4 -2
  122. package/dist/table/selectable/useSelectableRows.d.ts +8 -0
  123. package/dist/table/selectable/useSelectableRows.js +14 -6
  124. package/dist/table/table.js +1 -7
  125. package/dist/tabs/tabs.js +60 -58
  126. package/dist/tabs/tabsTestHelper.js +2 -2
  127. package/dist/timePickerRaw/timePickerRaw.js +1 -1
  128. package/dist/toggleButtonRaw/toggleButtonRaw.js +5 -2
  129. package/dist/utils/localization/translations/ar.json +3 -1
  130. package/dist/utils/localization/translations/cs.json +9 -5
  131. package/dist/utils/localization/translations/da-DK.json +9 -5
  132. package/dist/utils/localization/translations/de.json +9 -5
  133. package/dist/utils/localization/translations/en.json +5 -1
  134. package/dist/utils/localization/translations/es.json +9 -5
  135. package/dist/utils/localization/translations/fi-FI.json +9 -5
  136. package/dist/utils/localization/translations/fr-FR.json +9 -5
  137. package/dist/utils/localization/translations/fr.json +9 -5
  138. package/dist/utils/localization/translations/hu-HU.json +9 -5
  139. package/dist/utils/localization/translations/id.json +9 -5
  140. package/dist/utils/localization/translations/it.json +9 -5
  141. package/dist/utils/localization/translations/ja.json +9 -5
  142. package/dist/utils/localization/translations/ko-KR.json +9 -5
  143. package/dist/utils/localization/translations/ms.json +9 -5
  144. package/dist/utils/localization/translations/nb-NO.json +9 -5
  145. package/dist/utils/localization/translations/nl.json +9 -5
  146. package/dist/utils/localization/translations/pl.json +9 -5
  147. package/dist/utils/localization/translations/pt-BR.json +9 -5
  148. package/dist/utils/localization/translations/pt-PT.json +9 -5
  149. package/dist/utils/localization/translations/ro-RO.json +9 -5
  150. package/dist/utils/localization/translations/sk-SK.json +9 -5
  151. package/dist/utils/localization/translations/sv.json +9 -5
  152. package/dist/utils/localization/translations/th.json +9 -5
  153. package/dist/utils/localization/translations/tr.json +9 -5
  154. package/dist/utils/localization/translations/zh-Hans.json +9 -5
  155. package/dist/utils/localization/translations/zh-TW.json +9 -5
  156. package/dist/utils/localization/useDirectionalIcon.d.ts +3 -0
  157. package/dist/utils/localization/useDirectionalIcon.js +9 -0
  158. package/dist/utils/positioningUtils/alignments.d.ts +2 -2
  159. package/dist/utils/positioningUtils/alignments.js +2 -2
  160. package/dist/utils/positioningUtils/calculatePosition.js +4 -6
  161. package/esm/calendar/calendar.js +7 -4
  162. package/esm/card/components/title.js +4 -1
  163. package/esm/card/components/titleLink.js +5 -2
  164. package/esm/chart/barChart/getDefaultOptions.d.ts +2 -1
  165. package/esm/chart/barChart/getDefaultOptions.js +5 -2
  166. package/esm/chart/barChart.js +6 -4
  167. package/esm/chart/lineChart/getDefaultOptions.d.ts +2 -1
  168. package/esm/chart/lineChart/getDefaultOptions.js +5 -2
  169. package/esm/chart/lineChart.js +4 -2
  170. package/esm/checkboxListWithAction/checkboxListWithAction.js +4 -1
  171. package/esm/commonHelpers/arrowNavigation/components/arrowButton/arrowButton.js +4 -1
  172. package/esm/controlledPopup/controlledPopup.d.ts +1 -0
  173. package/esm/controlledPopup/controlledPopup.js +3 -1
  174. package/esm/dataGrid/cell/cell.d.ts +2 -1
  175. package/esm/dataGrid/cell/cell.js +2 -2
  176. package/esm/dataGrid/dataGrid.js +7 -4
  177. package/esm/dataGrid/listColumn.d.ts +2 -0
  178. package/esm/dataGrid/row/row.d.ts +2 -1
  179. package/esm/dataGrid/row/row.js +13 -9
  180. package/esm/dataGrid/withFlexibleColumns/components/columnSettingsList.js +2 -1
  181. package/esm/dataGrid/withSelectableRows/components/bulkActions/bulkActions.d.ts +4 -0
  182. package/esm/dateRangeInner/dateRangeInner.js +5 -2
  183. package/esm/dateRangeRaw/dateRangeRaw.js +5 -2
  184. package/esm/dateRangeRaw/utils/parseLabel.js +1 -1
  185. package/esm/dropdownRaw/dropdownRaw.js +12 -6
  186. package/esm/fileUpload/components/dropZoneContent.js +100 -100
  187. package/esm/fileUpload/fileUpload.js +100 -100
  188. package/esm/filters/components/filtersSearchList.js +4 -1
  189. package/esm/filtersBar/filtersContainer/filtersContainer.js +62 -61
  190. package/esm/formStepperButtons/formStepperButtons.js +4 -1
  191. package/esm/groupsFilterRaw/groupsFilterAdjustmentState.js +4 -1
  192. package/esm/groupsFilterRaw/groupsFilterInitialState.js +4 -1
  193. package/esm/header/headerBack.js +4 -1
  194. package/esm/icons/iconAlignLeft.js +1 -3
  195. package/esm/icons/iconAlignmentLeft.js +1 -3
  196. package/esm/icons/iconAlignmentRight.js +1 -3
  197. package/esm/icons/iconArrowBottomLeft.js +1 -3
  198. package/esm/icons/iconArrowBottomRight.js +1 -3
  199. package/esm/icons/iconArrowLeftPath.js +1 -3
  200. package/esm/icons/iconArrowRight.js +1 -3
  201. package/esm/icons/iconArrowRightCircle.js +1 -3
  202. package/esm/icons/iconArrowRightPath.js +1 -3
  203. package/esm/icons/iconArrowTopLeft.js +1 -3
  204. package/esm/icons/iconArrowTopRight.js +1 -3
  205. package/esm/icons/iconChevronDoubleRight.js +1 -3
  206. package/esm/icons/iconChevronRight.js +1 -3
  207. package/esm/icons/iconChevronRightSmall.js +1 -3
  208. package/esm/icons/iconCornerDownLeft.js +1 -3
  209. package/esm/icons/iconCornerDownRight.js +1 -3
  210. package/esm/icons/iconCornerLeftDown.js +1 -3
  211. package/esm/icons/iconCornerLeftUp.js +1 -3
  212. package/esm/icons/iconCornerRightDown.js +1 -3
  213. package/esm/icons/iconCornerRightUp.js +1 -3
  214. package/esm/icons/iconCornerUpLeft.js +1 -3
  215. package/esm/icons/iconCornerUpRight.js +1 -3
  216. package/esm/index.d.ts +1 -0
  217. package/esm/index.js +1 -0
  218. package/esm/lineChartMini/lineChartMini.js +15 -3
  219. package/esm/list/itemData/itemDataInternal.js +4 -1
  220. package/esm/list/list.d.ts +1 -0
  221. package/esm/list/list.js +2 -2
  222. package/esm/list/listItem/listItem.d.ts +1 -3
  223. package/esm/list/listItem/listItem.js +6 -5
  224. package/esm/menu/components/controlledMenuList/controlledMenuList.d.ts +27 -0
  225. package/esm/menu/components/controlledMenuList/controlledMenuList.js +123 -0
  226. package/esm/menu/components/createControlledMenuList.d.ts +37 -0
  227. package/esm/menu/components/createControlledMenuList.js +51 -0
  228. package/esm/menu/components/createMenuItem.d.ts +67 -0
  229. package/esm/menu/components/createMenuItem.js +93 -0
  230. package/esm/menu/components/menuButton.js +12 -3
  231. package/esm/menu/components/menuItem.d.ts +1 -2
  232. package/esm/menu/components/menuItem.js +20 -74
  233. package/esm/menu/contexts/usePathContext.d.ts +2 -0
  234. package/esm/menu/contexts/usePathContext.js +5 -0
  235. package/esm/menu/controlledMenu.js +10 -177
  236. package/esm/menu/utils/buildMenuContent.d.ts +2 -0
  237. package/esm/menu/utils/buildMenuContent.js +34 -0
  238. package/esm/menu/utils/findContent.d.ts +2 -2
  239. package/esm/menu/utils/findContent.js +4 -3
  240. package/esm/menu/utils/getItemLabel.d.ts +2 -0
  241. package/esm/menu/utils/getItemLabel.js +4 -0
  242. package/esm/menu/utils/getSafeRel.d.ts +1 -0
  243. package/esm/menu/utils/getSafeRel.js +10 -0
  244. package/esm/menu/utils/isMenuItem.d.ts +2 -0
  245. package/esm/menu/utils/isMenuItem.js +9 -0
  246. package/esm/menu/utils/isSafeHref.d.ts +1 -0
  247. package/esm/menu/utils/isSafeHref.js +6 -0
  248. package/esm/menu/utils/normalizeSeparators.d.ts +2 -0
  249. package/esm/menu/utils/normalizeSeparators.js +19 -0
  250. package/esm/menu/utils/resolveKeys.d.ts +12 -0
  251. package/esm/menu/utils/resolveKeys.js +18 -0
  252. package/esm/menu/utils/useLastValidSheet.d.ts +7 -0
  253. package/esm/menu/utils/useLastValidSheet.js +26 -0
  254. package/esm/menu/utils/useMenuItemCore.d.ts +31 -0
  255. package/esm/menu/utils/useMenuItemCore.js +50 -0
  256. package/esm/menu/utils/useMenuItemKeyboardNav.d.ts +2 -0
  257. package/esm/menu/utils/useMenuItemKeyboardNav.js +11 -0
  258. package/esm/menu/utils/useMenuListKeyboardNav.d.ts +12 -0
  259. package/esm/menu/utils/useMenuListKeyboardNav.js +73 -0
  260. package/esm/menu/utils/useMenuPath.d.ts +6 -0
  261. package/esm/menu/utils/useMenuPath.js +31 -0
  262. package/esm/nav/navItem/navItem.js +10 -5
  263. package/esm/nav/navSection/navSection.js +7 -5
  264. package/esm/pagination/paginationArrow.js +10 -3
  265. package/esm/radioGroupRaw/radioGroupRaw.js +2 -1
  266. package/esm/rangeRaw/rangeRaw.js +0 -1
  267. package/esm/selectList/selectList.helpers.d.ts +1 -1
  268. package/esm/selectList/selectList.helpers.js +29 -4
  269. package/esm/selectList/selectList.js +3 -1
  270. package/esm/selectList/selectList.reducer.js +1 -2
  271. package/esm/selectList/selectListItem.js +4 -1
  272. package/esm/sortControl/sortControl.js +59 -4
  273. package/esm/table/children/useTableChildren.d.ts +1 -1
  274. package/esm/table/children/useTableChildren.js +3 -3
  275. package/esm/table/flexible/columnsList.js +4 -2
  276. package/esm/table/selectable/useSelectableRows.d.ts +8 -0
  277. package/esm/table/selectable/useSelectableRows.js +14 -6
  278. package/esm/table/table.js +1 -7
  279. package/esm/tabs/tabs.js +60 -58
  280. package/esm/tabs/tabsTestHelper.js +2 -2
  281. package/esm/testHelpers/mockAbsoluteAlignment.d.ts +1 -0
  282. package/esm/testHelpers/mockAbsoluteAlignment.js +10 -0
  283. package/esm/timePickerRaw/timePickerRaw.js +1 -1
  284. package/esm/toggleButtonRaw/toggleButtonRaw.js +5 -2
  285. package/esm/utils/localization/translations/ar.json +3 -1
  286. package/esm/utils/localization/translations/cs.json +9 -5
  287. package/esm/utils/localization/translations/da-DK.json +9 -5
  288. package/esm/utils/localization/translations/de.json +9 -5
  289. package/esm/utils/localization/translations/en.json +5 -1
  290. package/esm/utils/localization/translations/es.json +9 -5
  291. package/esm/utils/localization/translations/fi-FI.json +9 -5
  292. package/esm/utils/localization/translations/fr-FR.json +9 -5
  293. package/esm/utils/localization/translations/fr.json +9 -5
  294. package/esm/utils/localization/translations/hu-HU.json +9 -5
  295. package/esm/utils/localization/translations/id.json +9 -5
  296. package/esm/utils/localization/translations/it.json +9 -5
  297. package/esm/utils/localization/translations/ja.json +9 -5
  298. package/esm/utils/localization/translations/ko-KR.json +9 -5
  299. package/esm/utils/localization/translations/ms.json +9 -5
  300. package/esm/utils/localization/translations/nb-NO.json +9 -5
  301. package/esm/utils/localization/translations/nl.json +9 -5
  302. package/esm/utils/localization/translations/pl.json +9 -5
  303. package/esm/utils/localization/translations/pt-BR.json +9 -5
  304. package/esm/utils/localization/translations/pt-PT.json +9 -5
  305. package/esm/utils/localization/translations/ro-RO.json +9 -5
  306. package/esm/utils/localization/translations/sk-SK.json +9 -5
  307. package/esm/utils/localization/translations/sv.json +9 -5
  308. package/esm/utils/localization/translations/th.json +9 -5
  309. package/esm/utils/localization/translations/tr.json +9 -5
  310. package/esm/utils/localization/translations/zh-Hans.json +9 -5
  311. package/esm/utils/localization/translations/zh-TW.json +9 -5
  312. package/esm/utils/localization/useDirectionalIcon.d.ts +3 -0
  313. package/esm/utils/localization/useDirectionalIcon.js +5 -0
  314. package/esm/utils/positioningUtils/alignments.d.ts +2 -2
  315. package/esm/utils/positioningUtils/alignments.js +2 -2
  316. package/esm/utils/positioningUtils/calculatePosition.js +4 -6
  317. package/package.json +123 -122
@@ -5,18 +5,24 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const classNames_1 = require("../../commonHelpers/classNames/classNames");
7
7
  const iconChevronRight_1 = require("../../icons/iconChevronRight");
8
+ const iconChevronLeft_1 = require("../../icons/iconChevronLeft");
9
+ const useDirectionalIcon_1 = require("../../utils/localization/useDirectionalIcon");
8
10
  const useDriveClassName_1 = require("../../utils/theme/useDriveClassName");
9
11
  const useDrive_1 = require("../../utils/theme/useDrive");
10
12
  const getMenuButtonState_1 = require("../utils/getMenuButtonState");
13
+ const isSafeHref_1 = require("../utils/isSafeHref");
14
+ const getSafeRel_1 = require("../utils/getSafeRel");
11
15
  const MenuButton = ({ id, onClick, hasChildren, disabled, icon, name, link, target, rel, className = "", active = null, ref }) => {
12
16
  const { hasState, isActive } = (0, getMenuButtonState_1.getMenuButtonState)(active, disabled);
13
17
  const driveMenuButtonActionClasses = (0, useDriveClassName_1.useDriveClassName)("zen-menu-button__action");
14
18
  const isDrive = (0, useDrive_1.useDrive)();
19
+ const ChevronIcon = (0, useDirectionalIcon_1.useDirectionalIcon)(iconChevronRight_1.IconChevronRight, iconChevronLeft_1.IconChevronLeft);
15
20
  const linkEvents = (0, react_1.useMemo)(() => ({
16
21
  onKeyDown: e => {
17
22
  if (e.key === " ") {
18
23
  e.preventDefault();
19
24
  const linkEl = e.target;
25
+ linkEl.dataset.spaceDown = "1";
20
26
  linkEl.classList.add("zen-menu-button__action--active");
21
27
  }
22
28
  },
@@ -25,7 +31,10 @@ const MenuButton = ({ id, onClick, hasChildren, disabled, icon, name, link, targ
25
31
  e.preventDefault();
26
32
  const linkEl = e.target;
27
33
  linkEl.classList.remove("zen-menu-button__action--active");
28
- linkEl.click();
34
+ if (linkEl.dataset.spaceDown) {
35
+ delete linkEl.dataset.spaceDown;
36
+ linkEl.click();
37
+ }
29
38
  }
30
39
  }
31
40
  }), []);
@@ -43,13 +52,13 @@ const MenuButton = ({ id, onClick, hasChildren, disabled, icon, name, link, targ
43
52
  (0, react_1.createElement)(icon, {
44
53
  size: isDrive ? "huge" : "large",
45
54
  className: (0, classNames_1.classNames)(["zen-caption__pre-content", "zen-menu-button__icon"])
46
- }), (0, jsx_runtime_1.jsx)("span", { className: "zen-menu-button__action-text", children: name }), !!hasChildren && ((0, jsx_runtime_1.jsx)(iconChevronRight_1.IconChevronRight, { size: isDrive ? "huge" : "large", className: (0, classNames_1.classNames)(["zen-caption__pre-content", "zen-menu-button__more-icon"]) }))] }));
55
+ }), (0, jsx_runtime_1.jsx)("span", { className: "zen-menu-button__action-text", children: name }), !!hasChildren && ((0, jsx_runtime_1.jsx)(ChevronIcon, { size: isDrive ? "huge" : "large", className: (0, classNames_1.classNames)(["zen-caption__pre-content", "zen-menu-button__more-icon"]) }))] }));
47
56
  const linkTemplate = ((0, jsx_runtime_1.jsxs)("a", Object.assign({ "data-id": id, role: "menuitem", className: (0, classNames_1.classNames)([
48
57
  "zen-menu-button__action",
49
58
  "zen-caption",
50
59
  disabled ? "zen-menu-button__action--disabled" : "",
51
60
  driveMenuButtonActionClasses || ""
52
- ]), href: disabled ? undefined : link, "aria-disabled": disabled, onClick: onClickHandler, target: target, rel: rel }, linkEvents, { children: [!!icon &&
61
+ ]), href: disabled || !(0, isSafeHref_1.isSafeHref)(link) ? undefined : link, "aria-disabled": disabled, onClick: onClickHandler, target: target, rel: (0, getSafeRel_1.getSafeRel)(rel, target) }, linkEvents, { children: [!!icon &&
53
62
  (0, react_1.createElement)(icon, {
54
63
  size: isDrive ? "huge" : "large",
55
64
  className: "zen-caption__pre-content"
@@ -2,6 +2,7 @@ import { FC, ReactElement } from "react";
2
2
  import { IMenuButton } from "./menuButton";
3
3
  import "./menuItem.less";
4
4
  import { TAlignment } from "../../absolute/absolute";
5
+ export { isMenuItem } from "../utils/isMenuItem";
5
6
  interface IMenuItemInternal {
6
7
  isMobile?: boolean;
7
8
  setIsOpen?: (v: boolean) => void;
@@ -12,6 +13,4 @@ export interface IMenuControlledItem extends IMenuItem {
12
13
  export interface IMenuItem extends IMenuButton {
13
14
  alignment?: TAlignment;
14
15
  }
15
- export declare const isMenuItem: (element: ReactElement | undefined) => boolean;
16
16
  export declare const MenuItem: FC<Omit<IMenuItem & IMenuControlledItem & IMenuItemInternal, "hasChildren">>;
17
- export {};
@@ -2,37 +2,30 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MenuItem = exports.isMenuItem = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
- /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument, @typescript-eslint/naming-convention */
5
+ /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument */
6
6
  const react_1 = require("react");
7
7
  const menuButton_1 = require("./menuButton");
8
- const controlledMenu_1 = require("../controlledMenu");
9
8
  const controlledPopup_1 = require("../../controlledPopup/controlledPopup");
10
- const pathContext_1 = require("../contexts/pathContext");
11
9
  const classNames_1 = require("../../commonHelpers/classNames/classNames");
12
- const generateId_1 = require("../../commonHelpers/generateId");
13
- const headerContext_1 = require("../../header/headerContext");
14
- const menuSeparator_1 = require("./menuSeparator");
15
- const isMenuItem = (element) => {
16
- if (!element || !element.type) {
17
- return false;
18
- }
19
- if (element.type === controlledMenu_1.ControlledMenu.Item) {
20
- return true;
21
- }
22
- if ((typeof element.type === "object" || typeof element.type === "function") && "displayName" in element.type) {
23
- return element.type.displayName === "MenuItem";
24
- }
25
- return false;
26
- };
27
- exports.isMenuItem = isMenuItem;
10
+ const useMenuItemCore_1 = require("../utils/useMenuItemCore");
11
+ var isMenuItem_1 = require("../utils/isMenuItem");
12
+ Object.defineProperty(exports, "isMenuItem", { enumerable: true, get: function () { return isMenuItem_1.isMenuItem; } });
28
13
  const MenuItem = ({ id, children, name, icon, disabled, onClick, link, target, rel, isMobile = false, setIsOpen, trigger, className, active, alignment }) => {
29
- const aligmentContext = (0, react_1.useContext)(headerContext_1.MenuAlignmentContext);
30
- const contentAlignment = alignment || aligmentContext.alignment || "right-top";
31
- const { path, onOpenBranch, closeBranch, navigatedViaKeyboardRef } = (0, react_1.useContext)(pathContext_1.PathContext);
32
- const memoizedDesktopActionOnClick = (0, react_1.useCallback)((itemId, e) => {
14
+ const { ref, isOpen, hasChildren, content, openedViaKeyboard, contentAlignment, path, onOpenBranch, handleOpenChange } = (0, useMenuItemCore_1.useMenuItemCore)({
15
+ id,
16
+ children,
17
+ className,
18
+ alignment,
19
+ isMobile,
20
+ setIsOpen,
21
+ onClick
22
+ });
23
+ // MenuButton.onClick signature is (id, e) — adapt the hook's (e)-only handler
24
+ const memoizedDesktopActionOnClick = (0, react_1.useCallback)((_, e) => {
33
25
  setIsOpen === null || setIsOpen === void 0 ? void 0 : setIsOpen(false);
34
- onClick === null || onClick === void 0 ? void 0 : onClick(itemId, e);
35
- }, [setIsOpen, onClick]);
26
+ onClick === null || onClick === void 0 ? void 0 : onClick(id, e);
27
+ }, [setIsOpen, onClick, id]);
28
+ // MenuItem-specific callbacks (not provided by hook)
36
29
  const memoizedMobileActionOnClick = (0, react_1.useCallback)((itemId, e) => {
37
30
  onOpenBranch(id);
38
31
  !link && (onClick === null || onClick === void 0 ? void 0 : onClick(itemId, e));
@@ -50,54 +43,7 @@ const MenuItem = ({ id, children, name, icon, disabled, onClick, link, target, r
50
43
  }
51
44
  onClick === null || onClick === void 0 ? void 0 : onClick(id, e);
52
45
  }, [onClick, onOpenBranch, id, trigger]);
53
- const memoizedOnOpenChange = (0, react_1.useCallback)(() => {
54
- closeBranch();
55
- }, [closeBranch]);
56
- const ref = (0, react_1.useRef)(null);
57
- const content = (0, react_1.useMemo)(() => {
58
- const cont = [];
59
- react_1.Children.map(children, (child) => {
60
- if (!child) {
61
- return;
62
- }
63
- if (typeof child === "string") {
64
- cont.push((0, jsx_runtime_1.jsx)("li", { className: (0, classNames_1.classNames)(["zen-menu-item__content", className !== null && className !== void 0 ? className : ""]), role: "presentation", children: child }, (0, generateId_1.generateId)()));
65
- return;
66
- }
67
- if ((0, react_1.isValidElement)(child) && (0, menuSeparator_1.isSeparator)(child)) {
68
- const clone = (0, react_1.cloneElement)(child, {
69
- key: child.props.key || (0, generateId_1.generateId)()
70
- });
71
- cont.push(clone);
72
- return;
73
- }
74
- if ((0, exports.isMenuItem)(child)) {
75
- const childProps = child.props;
76
- const clone = (0, react_1.cloneElement)(child, {
77
- isMobile,
78
- key: childProps.id,
79
- setIsOpen
80
- });
81
- cont.push(clone);
82
- return;
83
- }
84
- const childProps = child.props;
85
- cont.push((0, jsx_runtime_1.jsx)("li", { className: (0, classNames_1.classNames)(["zen-menu-item__content", className !== null && className !== void 0 ? className : ""]), role: "presentation", children: child }, childProps.id || childProps["data-id"] || (0, generateId_1.generateId)()));
86
- });
87
- return cont;
88
- }, [children, isMobile, setIsOpen, className]);
89
- const isOpen = (0, react_1.useMemo)(() => path.includes(id), [path, id]);
90
- // Track previous isOpen state to detect when submenu opens
91
- const wasOpenRef = (0, react_1.useRef)(false);
92
- const localOpenedViaKeyboardRef = (0, react_1.useRef)(false);
93
- // Capture keyboard navigation state synchronously when isOpen transitions to true
94
- if (isOpen && !wasOpenRef.current && navigatedViaKeyboardRef) {
95
- localOpenedViaKeyboardRef.current = navigatedViaKeyboardRef.current;
96
- navigatedViaKeyboardRef.current = false; // Reset for next navigation
97
- }
98
- wasOpenRef.current = isOpen;
99
- const openedViaKeyboard = localOpenedViaKeyboardRef.current;
100
- if (content.length === 0) {
46
+ if (!hasChildren) {
101
47
  return ((0, jsx_runtime_1.jsx)(menuButton_1.MenuButton, { id: id, name: name, icon: icon, disabled: disabled, link: link, target: target, rel: rel, onClick: memoizedDesktopActionOnClick, className: className, active: active, hasChildren: false }, id));
102
48
  }
103
49
  if (isMobile) {
@@ -113,7 +59,7 @@ const MenuItem = ({ id, children, name, icon, disabled, onClick, link, target, r
113
59
  else {
114
60
  popupTrigger = ((0, jsx_runtime_1.jsx)(menuButton_1.MenuButton, { id: id, ref: ref, name: name, icon: icon, disabled: disabled, hasChildren: true, onClick: memoizedTriggerOnClick, active: active }, id));
115
61
  }
116
- return ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [popupTrigger, (0, jsx_runtime_1.jsx)(controlledPopup_1.ControlledPopup, { className: (0, classNames_1.classNames)([`zen-controlled-menu-submenu--${path.length}`]), useTrapFocusWithTrigger: openedViaKeyboard ? "on" : "withTrigger", alignment: contentAlignment, triggerRef: ref, isOpen: isOpen, onOpenChange: memoizedOnOpenChange, ariaLabel: popupTrigger.props.name, recalculateOnScroll: true, children: (0, jsx_runtime_1.jsx)("ul", { role: "menu", className: "zen-menu-item", children: content }) })] }, id));
62
+ return ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [popupTrigger, (0, jsx_runtime_1.jsx)(controlledPopup_1.ControlledPopup, { className: (0, classNames_1.classNames)([`zen-controlled-menu-submenu--${path.length}`]), useTrapFocusWithTrigger: openedViaKeyboard ? "on" : "withTrigger", alignment: contentAlignment, triggerRef: ref, isOpen: isOpen, onOpenChange: handleOpenChange, ariaLabel: popupTrigger.props.name, recalculateOnScroll: true, children: (0, jsx_runtime_1.jsx)("ul", { role: "menu", className: "zen-menu-item", children: content }) })] }, id));
117
63
  };
118
64
  exports.MenuItem = MenuItem;
119
65
  exports.MenuItem.displayName = "MenuItem";
@@ -0,0 +1,2 @@
1
+ import { IPathContext } from "./pathContext";
2
+ export declare function usePathContext(): IPathContext;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.usePathContext = void 0;
4
+ const react_1 = require("react");
5
+ const pathContext_1 = require("./pathContext");
6
+ function usePathContext() {
7
+ return (0, react_1.useContext)(pathContext_1.PathContext);
8
+ }
9
+ exports.usePathContext = usePathContext;
@@ -2,47 +2,28 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TRANSLATIONS = exports.ControlledMenu = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
- /* eslint-disable @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument */
6
5
  const react_1 = require("react");
7
- const menuItem_1 = require("./components/menuItem");
8
6
  const classNames_1 = require("../commonHelpers/classNames/classNames");
9
- const findContent_1 = require("./utils/findContent");
10
- const findFirstFocusable_1 = require("./utils/findFirstFocusable");
11
- const findLastFocusable_1 = require("./utils/findLastFocusable");
12
- const findNextFocusable_1 = require("./utils/findNextFocusable");
13
- const isButton_1 = require("./utils/isButton");
14
- const isLink_1 = require("./utils/isLink");
15
- const findPrevFocusable_1 = require("./utils/findPrevFocusable");
16
- const menuButton_1 = require("./components/menuButton");
17
- const iconArrowLeft_1 = require("../icons/iconArrowLeft");
18
7
  const controlledPopup_1 = require("../controlledPopup/controlledPopup");
19
8
  const mobileSheet_1 = require("../mobileSheet/mobileSheet");
20
9
  const deviceType_1 = require("../commonHelpers/hooks/deviceType");
21
10
  const useDeviceType_1 = require("../commonHelpers/hooks/useDeviceType");
22
- const generateId_1 = require("../commonHelpers/generateId");
23
- const pathProvider_1 = require("./contexts/pathProvider");
24
- const menuSeparator_1 = require("./components/menuSeparator");
25
11
  const focusableSelector_1 = require("../utils/focusableSelector");
12
+ const controlledMenuList_1 = require("./components/controlledMenuList/controlledMenuList");
13
+ const EmbeddedMenuList = controlledMenuList_1.ControlledMenuList;
26
14
  const ControlledMenu = ({ children, isOpen, setIsOpen, triggerRef, ariaLabel, ariaLabelledby, id, title, className = "", listClassName = "", paddingX = 0, paddingY = 0, alignment, closeOnScroll = true }) => {
27
15
  const [deviceType, setDeviceType] = (0, react_1.useState)(deviceType_1.DeviceType.Desktop);
28
16
  const isMobile = deviceType === deviceType_1.DeviceType.Mobile;
29
17
  const memoizedOnChange = (0, react_1.useCallback)(setIsOpen, [setIsOpen]);
30
18
  (0, useDeviceType_1.useDeviceType)(setDeviceType);
31
19
  const menuListRef = (0, react_1.useRef)(null);
32
- const [path, setPath] = (0, react_1.useState)([]);
33
- // Track if the trigger was activated via keyboard
34
20
  const openedViaKeyboardRef = (0, react_1.useRef)(false);
35
- // Track if submenu was navigated via keyboard (ArrowRight)
36
- const navigatedViaKeyboardRef = (0, react_1.useRef)(false);
37
- // Track if keyboard is actively being used for navigation (vs mouse/touch)
38
- const keyboardActiveRef = (0, react_1.useRef)(false);
39
- // Listen for keyboard activation on trigger
40
21
  (0, react_1.useEffect)(() => {
41
22
  const trigger = triggerRef.current;
42
23
  if (!trigger)
43
24
  return undefined;
44
25
  const handleKeyDown = (e) => {
45
- if (e.key === "Enter" || e.key === " ") {
26
+ if (e.key === "Enter" || e.key === " " || e.key === "ArrowRight") {
46
27
  openedViaKeyboardRef.current = true;
47
28
  }
48
29
  };
@@ -56,12 +37,6 @@ const ControlledMenu = ({ children, isOpen, setIsOpen, triggerRef, ariaLabel, ar
56
37
  trigger.removeEventListener("mousedown", handleMouseDown);
57
38
  };
58
39
  }, [triggerRef]);
59
- (0, react_1.useEffect)(() => {
60
- if (path.length && !isOpen) {
61
- setPath([]);
62
- }
63
- }, [isOpen, path, setPath]);
64
- // Focus the menu list container or first item when menu opens (for keyboard navigation)
65
40
  (0, react_1.useEffect)(() => {
66
41
  var _a;
67
42
  if (isOpen && !isMobile && menuListRef.current) {
@@ -73,157 +48,15 @@ const ControlledMenu = ({ children, isOpen, setIsOpen, triggerRef, ariaLabel, ar
73
48
  }
74
49
  }
75
50
  }, [isOpen, isMobile]);
76
- const onOpenBranch = (0, react_1.useCallback)((branchId) => {
77
- if (!branchId) {
78
- return;
79
- }
80
- if (!path.includes(branchId)) {
81
- setPath([...path, branchId]);
82
- return;
83
- }
84
- if (path.includes(branchId)) {
85
- setPath(v => {
86
- const newPath = [...v];
87
- newPath.pop();
88
- return newPath;
89
- });
90
- }
91
- }, [setPath, path]);
92
- const closeBranch = (0, react_1.useCallback)(() => {
93
- setPath(v => {
94
- const newPath = [...v];
95
- newPath.pop();
96
- return newPath;
97
- });
98
- }, [setPath]);
99
- const [content, parent] = (0, react_1.useMemo)(() => {
100
- let par = null;
101
- let currentChildren = children;
102
- if (isMobile && path.length > 0) {
103
- const el = (0, findContent_1.findContent)(children, exports.ControlledMenu.Item, path[path.length - 1]);
104
- if (el || (0, react_1.isValidElement)(el)) {
105
- const elProps = el.props;
106
- currentChildren = elProps.children;
107
- par = el;
108
- }
109
- }
110
- let cont = [];
111
- react_1.Children.map(currentChildren, (child) => {
112
- if (!child) {
113
- return;
114
- }
115
- if (typeof child === "string") {
116
- cont.push((0, jsx_runtime_1.jsx)("li", { role: "presentation", className: (0, classNames_1.classNames)(["zen-menu-item__content"]), children: child }, (0, generateId_1.generateId)()));
117
- return;
118
- }
119
- if ((0, react_1.isValidElement)(child) && (0, menuSeparator_1.isSeparator)(child)) {
120
- const clone = (0, react_1.cloneElement)(child, {
121
- key: child.props.key || (0, generateId_1.generateId)()
122
- });
123
- cont.push(clone);
124
- return;
125
- }
126
- if ((0, react_1.isValidElement)(child) && (0, menuItem_1.isMenuItem)(child)) {
127
- const clone = (0, react_1.cloneElement)(child, {
128
- isMobile,
129
- key: child.props.id,
130
- setIsOpen,
131
- onClick: child.props.onClick
132
- });
133
- cont.push(clone);
134
- return;
135
- }
136
- const childProps = child.props;
137
- cont.push((0, jsx_runtime_1.jsx)("li", { className: (0, classNames_1.classNames)(["zen-menu-item__content"]), role: "presentation", children: child }, childProps.id || childProps["data-id"] || (0, generateId_1.generateId)()));
138
- });
139
- while (cont[0] && (0, menuSeparator_1.isSeparator)(cont[0])) {
140
- cont.shift();
141
- }
142
- while (cont[cont.length - 1] && (0, menuSeparator_1.isSeparator)(cont[cont.length - 1])) {
143
- cont.pop();
144
- }
145
- cont = cont.filter((el, indx, arr) => {
146
- if ((0, menuSeparator_1.isSeparator)(el) && arr[indx - 1] && (0, menuSeparator_1.isSeparator)(arr[indx - 1])) {
147
- return false;
148
- }
149
- return true;
150
- });
151
- return [cont, par];
152
- }, [children, isMobile, path, setIsOpen]);
153
- // Handle keyboard navigation when no menu item is focused (e.g., when menu just opened)
154
- const handleUnfocusedKeyDown = (e, menuList) => {
155
- var _a, _b;
156
- if (e.key === "ArrowDown" || e.key === "Home") {
157
- e.preventDefault();
158
- (_a = (0, findFirstFocusable_1.findFirstFocusable)(menuList)) === null || _a === void 0 ? void 0 : _a.focus();
159
- return true;
160
- }
161
- if (e.key === "ArrowUp" || e.key === "End") {
162
- e.preventDefault();
163
- (_b = (0, findLastFocusable_1.findLastFocusable)(menuList)) === null || _b === void 0 ? void 0 : _b.focus();
164
- return true;
165
- }
166
- return false;
167
- };
168
- const onMouseDown = () => {
169
- keyboardActiveRef.current = false;
170
- };
171
- const onKeyDown = e => {
172
- var _a, _b, _c, _d;
173
- keyboardActiveRef.current = true;
174
- const target = e.target;
175
- const currentTarget = e.currentTarget;
176
- if (!(0, isButton_1.isButton)(target) && !(0, isLink_1.isLink)(target)) {
177
- if (target === currentTarget) {
178
- const menuList = currentTarget.querySelector("ul");
179
- if (menuList) {
180
- handleUnfocusedKeyDown(e, menuList);
181
- }
182
- }
183
- return;
184
- }
185
- if (e.key === "ArrowDown") {
186
- e.preventDefault();
187
- (_a = (0, findNextFocusable_1.findNextFocusable)(target)) === null || _a === void 0 ? void 0 : _a.focus();
188
- return;
189
- }
190
- if (e.key === "ArrowUp") {
191
- e.preventDefault();
192
- (_b = (0, findPrevFocusable_1.findPrevFocusable)(target)) === null || _b === void 0 ? void 0 : _b.focus();
193
- return;
194
- }
195
- if (e.key === "Home") {
196
- e.preventDefault();
197
- (_c = (0, findFirstFocusable_1.findFirstFocusable)(target)) === null || _c === void 0 ? void 0 : _c.focus();
198
- return;
199
- }
200
- if (e.key === "End") {
201
- e.preventDefault();
202
- (_d = (0, findLastFocusable_1.findLastFocusable)(target)) === null || _d === void 0 ? void 0 : _d.focus();
203
- return;
204
- }
205
- if ((0, isButton_1.isButton)(target) &&
206
- (e.key === "ArrowRight" || e.key === "Enter" || e.key === " ") &&
207
- target.classList.contains("zen-menu-button__action--has-children")) {
208
- e.preventDefault();
209
- navigatedViaKeyboardRef.current = true;
210
- target.click();
211
- }
212
- };
213
- const renderMenuList = () => ((0, jsx_runtime_1.jsx)("div", { ref: menuListRef, tabIndex: -1, onKeyDown: onKeyDown, onMouseDown: onMouseDown, className: (0, classNames_1.classNames)(["zen-action-list", className]), children: (0, jsx_runtime_1.jsxs)("ul", { role: "menu", className: (0, classNames_1.classNames)(["zen-menu-item", className, listClassName]), children: [parent ? ((0, jsx_runtime_1.jsx)(menuButton_1.MenuButton, { id: "root", name: parent.props.name || "", icon: iconArrowLeft_1.IconArrowLeft, onClick: closeBranch, hasChildren: false, disabled: false }, "root")) : null, content] }) }));
214
51
  const hideMenu = (0, react_1.useCallback)(() => {
215
- closeBranch();
216
52
  setIsOpen(false);
217
- }, [closeBranch, setIsOpen]);
53
+ }, [setIsOpen]);
218
54
  if (isMobile) {
219
- return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(pathProvider_1.PathProvider, { path: path, onOpenBranch: onOpenBranch, closeBranch: closeBranch, navigatedViaKeyboardRef: navigatedViaKeyboardRef, keyboardActiveRef: keyboardActiveRef, children: (0, jsx_runtime_1.jsxs)(mobileSheet_1.MobileSheet, { label: title, isOpen: isOpen, triggerRef: triggerRef, onHidePanel: hideMenu, onCloseClick: hideMenu, children: [(0, jsx_runtime_1.jsx)(mobileSheet_1.MobileSheet.Title, { children: title }), (0, jsx_runtime_1.jsx)(mobileSheet_1.MobileSheet.Content, { children: renderMenuList() })] }) }) }));
55
+ return ((0, jsx_runtime_1.jsxs)(mobileSheet_1.MobileSheet, { label: title, isOpen: isOpen, triggerRef: triggerRef, onHidePanel: hideMenu, onCloseClick: hideMenu, children: [(0, jsx_runtime_1.jsx)(mobileSheet_1.MobileSheet.Title, { children: title }), (0, jsx_runtime_1.jsx)(mobileSheet_1.MobileSheet.Content, { children: (0, jsx_runtime_1.jsx)(EmbeddedMenuList, { ref: menuListRef, setIsOpen: setIsOpen, isOpen: isOpen, className: className, listClassName: listClassName, children: children }) })] }));
220
56
  }
221
- return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(pathProvider_1.PathProvider, { path: path, onOpenBranch: onOpenBranch, closeBranch: closeBranch, navigatedViaKeyboardRef: navigatedViaKeyboardRef, keyboardActiveRef: keyboardActiveRef, children: (0, jsx_runtime_1.jsx)(controlledPopup_1.ControlledPopup, { id: id, useTrapFocusWithTrigger: "on", className: (0, classNames_1.classNames)(["zen-controlled-menu", className]), onOpenChange: memoizedOnChange, isOpen: isOpen, triggerRef: triggerRef, paddingX: paddingX, paddingY: paddingY, alignment: alignment, ariaLabelledby: ariaLabelledby, ariaLabel: ariaLabel || title, closeOnScroll: closeOnScroll,
222
- // focusOnOpen is false - ControlledMenu handles focus based on input method
223
- // (keyboard vs mouse) in its own useEffect
224
- focusOnOpen: false, children: renderMenuList() }) }) }));
57
+ return ((0, jsx_runtime_1.jsx)(controlledPopup_1.ControlledPopup, { id: id, useTrapFocusWithTrigger: "on", className: (0, classNames_1.classNames)(["zen-controlled-menu", className]), onOpenChange: memoizedOnChange, isOpen: isOpen, triggerRef: triggerRef, paddingX: paddingX, paddingY: paddingY, alignment: alignment, ariaLabelledby: ariaLabelledby, ariaLabel: ariaLabel || title, recalculateOnScroll: true, focusOnOpen: false, closeOnScroll: closeOnScroll, children: (0, jsx_runtime_1.jsx)(EmbeddedMenuList, { ref: menuListRef, setIsOpen: setIsOpen, isOpen: isOpen, className: className, listClassName: listClassName, children: children }) }));
225
58
  };
226
59
  exports.ControlledMenu = ControlledMenu;
227
- exports.ControlledMenu.Item = menuItem_1.MenuItem;
228
- exports.ControlledMenu.Separator = menuSeparator_1.MenuSeparator;
60
+ exports.ControlledMenu.Item = controlledMenuList_1.ControlledMenuList.Item;
61
+ exports.ControlledMenu.Separator = controlledMenuList_1.ControlledMenuList.Separator;
229
62
  exports.TRANSLATIONS = ["Back"];
@@ -0,0 +1,2 @@
1
+ import { ReactNode } from "react";
2
+ export declare function buildMenuContent(children: ReactNode, isMobile: boolean, setIsOpen: ((v: boolean) => void) | undefined, className: string | undefined): ReactNode[];
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildMenuContent = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument */
6
+ const react_1 = require("react");
7
+ const classNames_1 = require("../../commonHelpers/classNames/classNames");
8
+ const menuSeparator_1 = require("../components/menuSeparator");
9
+ const isMenuItem_1 = require("./isMenuItem");
10
+ const generateId_1 = require("../../commonHelpers/generateId");
11
+ function buildMenuContent(children, isMobile, setIsOpen, className) {
12
+ const cont = [];
13
+ react_1.Children.map(children, (child) => {
14
+ if (!child) {
15
+ return;
16
+ }
17
+ if (typeof child === "string") {
18
+ cont.push((0, jsx_runtime_1.jsx)("li", { className: (0, classNames_1.classNames)(["zen-menu-item__content", className !== null && className !== void 0 ? className : ""]), role: "presentation", children: child }, (0, generateId_1.generateId)()));
19
+ return;
20
+ }
21
+ if ((0, react_1.isValidElement)(child) && (0, menuSeparator_1.isSeparator)(child)) {
22
+ const clone = (0, react_1.cloneElement)(child, { key: child.props.key || (0, generateId_1.generateId)() });
23
+ cont.push(clone);
24
+ return;
25
+ }
26
+ if ((0, isMenuItem_1.isMenuItem)(child)) {
27
+ const childProps = child.props;
28
+ const clone = (0, react_1.cloneElement)(child, { isMobile, key: childProps.id, setIsOpen });
29
+ cont.push(clone);
30
+ return;
31
+ }
32
+ // eslint-disable-next-line @typescript-eslint/naming-convention
33
+ const childProps = child.props;
34
+ cont.push((0, jsx_runtime_1.jsx)("li", { className: (0, classNames_1.classNames)(["zen-menu-item__content", className !== null && className !== void 0 ? className : ""]), role: "presentation", children: child }, childProps.id || childProps["data-id"] || (0, generateId_1.generateId)()));
35
+ });
36
+ return cont;
37
+ }
38
+ exports.buildMenuContent = buildMenuContent;
@@ -1,2 +1,2 @@
1
- import React, { ReactNode, ReactElement } from "react";
2
- export declare const findContent: (children: ReactNode, targetComponent: React.FC | React.ComponentClass, id?: string) => ReactElement | null;
1
+ import { ReactNode, ReactElement } from "react";
2
+ export declare const findContent: (children: ReactNode, matcher: (child: ReactElement) => boolean, id?: string) => ReactElement | null;
@@ -5,19 +5,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.findContent = void 0;
7
7
  const react_1 = __importDefault(require("react"));
8
- const findContent = (children, targetComponent, id) => {
8
+ const findContent = (children, matcher, id) => {
9
9
  let found = null;
10
10
  react_1.default.Children.forEach(children, (child) => {
11
11
  if (found || !react_1.default.isValidElement(child)) {
12
12
  return;
13
13
  }
14
14
  const childProps = child.props;
15
- if (id ? child.type === targetComponent && childProps.id === id : child.type === targetComponent) {
15
+ const matches = matcher(child);
16
+ if (id ? matches && childProps.id === id : matches) {
16
17
  found = child;
17
18
  return;
18
19
  }
19
20
  if (childProps.children) {
20
- found = (0, exports.findContent)(childProps.children, targetComponent, id);
21
+ found = (0, exports.findContent)(childProps.children, matcher, id);
21
22
  }
22
23
  });
23
24
  return found;
@@ -0,0 +1,2 @@
1
+ import { ReactElement } from "react";
2
+ export declare const getItemLabel: (el: ReactElement | null) => string;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getItemLabel = void 0;
4
+ const getItemLabel = (el) => {
5
+ const props = el === null || el === void 0 ? void 0 : el.props;
6
+ return (props === null || props === void 0 ? void 0 : props.name) || (props === null || props === void 0 ? void 0 : props.title) || "";
7
+ };
8
+ exports.getItemLabel = getItemLabel;
@@ -0,0 +1 @@
1
+ export declare const getSafeRel: (rel?: string, target?: string) => string | undefined;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSafeRel = void 0;
4
+ const getSafeRel = (rel, target) => {
5
+ if (target !== "_blank")
6
+ return rel;
7
+ const parts = rel ? rel.split(/\s+/) : [];
8
+ if (!parts.includes("noopener"))
9
+ parts.push("noopener");
10
+ if (!parts.includes("noreferrer"))
11
+ parts.push("noreferrer");
12
+ return parts.join(" ");
13
+ };
14
+ exports.getSafeRel = getSafeRel;
@@ -0,0 +1,2 @@
1
+ import { ReactElement } from "react";
2
+ export declare const isMenuItem: (element: ReactElement | undefined) => boolean;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isMenuItem = void 0;
4
+ const isMenuItem = (element) => {
5
+ if (!element || !element.type) {
6
+ return false;
7
+ }
8
+ if ((typeof element.type === "object" || typeof element.type === "function") && "displayName" in element.type) {
9
+ return element.type.displayName === "MenuItem";
10
+ }
11
+ return false;
12
+ };
13
+ exports.isMenuItem = isMenuItem;
@@ -0,0 +1 @@
1
+ export declare const isSafeHref: (href?: string) => boolean;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isSafeHref = void 0;
4
+ const isSafeHref = (href) => {
5
+ if (!href)
6
+ return false;
7
+ const lower = href.toLowerCase().trimStart();
8
+ return !lower.startsWith("javascript:") && !lower.startsWith("data:") && !lower.startsWith("vbscript:");
9
+ };
10
+ exports.isSafeHref = isSafeHref;
@@ -0,0 +1,2 @@
1
+ import { ReactElement } from "react";
2
+ export declare const normalizeSeparators: (items: ReactElement[]) => ReactElement[];
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeSeparators = void 0;
4
+ const menuSeparator_1 = require("../components/menuSeparator");
5
+ const normalizeSeparators = (items) => {
6
+ // Find the first non-separator index
7
+ let start = 0;
8
+ while (start < items.length && (0, menuSeparator_1.isSeparator)(items[start])) {
9
+ start++;
10
+ }
11
+ // Find the last non-separator index
12
+ let end = items.length - 1;
13
+ while (end >= start && (0, menuSeparator_1.isSeparator)(items[end])) {
14
+ end--;
15
+ }
16
+ // If all items are separators or array is empty
17
+ if (start > end) {
18
+ return [];
19
+ }
20
+ // Slice to remove leading/trailing separators and filter consecutive duplicates
21
+ return items.slice(start, end + 1).filter((el, i, arr) => !((0, menuSeparator_1.isSeparator)(el) && arr[i - 1] && (0, menuSeparator_1.isSeparator)(arr[i - 1])));
22
+ };
23
+ exports.normalizeSeparators = normalizeSeparators;
@@ -0,0 +1,12 @@
1
+ export declare const verticalKeys: {
2
+ keyNext: string;
3
+ keyPrev: string;
4
+ keyOpenNested: string;
5
+ keyBack: string;
6
+ };
7
+ export declare const resolveKeys: (target: HTMLElement, isHorizontal: boolean) => {
8
+ keyNext: string;
9
+ keyPrev: string;
10
+ keyOpenNested: string;
11
+ keyBack: string;
12
+ };
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveKeys = exports.verticalKeys = void 0;
4
+ exports.verticalKeys = {
5
+ keyNext: "ArrowDown",
6
+ keyPrev: "ArrowUp",
7
+ keyOpenNested: "ArrowRight",
8
+ keyBack: "ArrowLeft"
9
+ };
10
+ const resolveKeys = (target, isHorizontal) => {
11
+ const inSubMenu = isHorizontal && !!target.closest('[class*="zen-controlled-menu-submenu"]');
12
+ if (inSubMenu) {
13
+ return exports.verticalKeys;
14
+ }
15
+ return {
16
+ keyNext: isHorizontal ? "ArrowRight" : "ArrowDown",
17
+ keyPrev: isHorizontal ? "ArrowLeft" : "ArrowUp",
18
+ keyOpenNested: isHorizontal ? "ArrowUp" : "ArrowRight",
19
+ keyBack: isHorizontal ? "ArrowDown" : "ArrowLeft"
20
+ };
21
+ };
22
+ exports.resolveKeys = resolveKeys;