@salt-ds/lab 1.0.0-alpha.95 → 1.0.0-alpha.97

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 (220) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/css/salt-lab.css +70 -249
  3. package/dist-cjs/common-hooks/useSelection.js +6 -3
  4. package/dist-cjs/common-hooks/useSelection.js.map +1 -1
  5. package/dist-cjs/index.js +12 -14
  6. package/dist-cjs/index.js.map +1 -1
  7. package/dist-cjs/list/useList.js +7 -1
  8. package/dist-cjs/list/useList.js.map +1 -1
  9. package/dist-cjs/mega-menu/MegaMenu.js +8 -14
  10. package/dist-cjs/mega-menu/MegaMenu.js.map +1 -1
  11. package/dist-cjs/mega-menu/MegaMenuActions.css.js +6 -0
  12. package/dist-cjs/mega-menu/MegaMenuActions.css.js.map +1 -0
  13. package/dist-cjs/mega-menu/MegaMenuActions.js +33 -0
  14. package/dist-cjs/mega-menu/MegaMenuActions.js.map +1 -0
  15. package/dist-cjs/mega-menu/MegaMenuAside.css.js +6 -0
  16. package/dist-cjs/mega-menu/MegaMenuAside.css.js.map +1 -0
  17. package/dist-cjs/mega-menu/MegaMenuAside.js +33 -0
  18. package/dist-cjs/mega-menu/MegaMenuAside.js.map +1 -0
  19. package/dist-cjs/mega-menu/MegaMenuContent.css.js +6 -0
  20. package/dist-cjs/mega-menu/MegaMenuContent.css.js.map +1 -0
  21. package/dist-cjs/mega-menu/MegaMenuContent.js +25 -0
  22. package/dist-cjs/mega-menu/MegaMenuContent.js.map +1 -0
  23. package/dist-cjs/mega-menu/MegaMenuContext.js.map +1 -1
  24. package/dist-cjs/mega-menu/MegaMenuGroup.css.js +1 -1
  25. package/dist-cjs/mega-menu/MegaMenuGroup.js +10 -25
  26. package/dist-cjs/mega-menu/MegaMenuGroup.js.map +1 -1
  27. package/dist-cjs/mega-menu/MegaMenuGroupContext.js +17 -0
  28. package/dist-cjs/mega-menu/MegaMenuGroupContext.js.map +1 -0
  29. package/dist-cjs/mega-menu/MegaMenuGroupHeading.css.js +6 -0
  30. package/dist-cjs/mega-menu/MegaMenuGroupHeading.css.js.map +1 -0
  31. package/dist-cjs/mega-menu/MegaMenuGroupHeading.js +39 -0
  32. package/dist-cjs/mega-menu/MegaMenuGroupHeading.js.map +1 -0
  33. package/dist-cjs/mega-menu/MegaMenuGroups.css.js +1 -1
  34. package/dist-cjs/mega-menu/MegaMenuGroups.js.map +1 -1
  35. package/dist-cjs/mega-menu/MegaMenuList.css.js +6 -0
  36. package/dist-cjs/mega-menu/MegaMenuList.css.js.map +1 -0
  37. package/dist-cjs/mega-menu/MegaMenuList.js +43 -0
  38. package/dist-cjs/mega-menu/MegaMenuList.js.map +1 -0
  39. package/dist-cjs/mega-menu/MegaMenuListItem.css.js +6 -0
  40. package/dist-cjs/mega-menu/MegaMenuListItem.css.js.map +1 -0
  41. package/dist-cjs/mega-menu/MegaMenuListItem.js +45 -0
  42. package/dist-cjs/mega-menu/MegaMenuListItem.js.map +1 -0
  43. package/dist-cjs/mega-menu/MegaMenuPanel.css.js +1 -1
  44. package/dist-cjs/mega-menu/MegaMenuPanel.js +27 -47
  45. package/dist-cjs/mega-menu/MegaMenuPanel.js.map +1 -1
  46. package/dist-cjs/mega-menu/MegaMenuTrigger.js +16 -18
  47. package/dist-cjs/mega-menu/MegaMenuTrigger.js.map +1 -1
  48. package/dist-cjs/mega-menu/useMegaMenuNavigation.js +282 -0
  49. package/dist-cjs/mega-menu/useMegaMenuNavigation.js.map +1 -0
  50. package/dist-cjs/mega-menu/usePageMargin.js +22 -0
  51. package/dist-cjs/mega-menu/usePageMargin.js.map +1 -0
  52. package/dist-es/common-hooks/useSelection.js +6 -3
  53. package/dist-es/common-hooks/useSelection.js.map +1 -1
  54. package/dist-es/index.js +6 -7
  55. package/dist-es/index.js.map +1 -1
  56. package/dist-es/list/useList.js +7 -1
  57. package/dist-es/list/useList.js.map +1 -1
  58. package/dist-es/mega-menu/MegaMenu.js +9 -15
  59. package/dist-es/mega-menu/MegaMenu.js.map +1 -1
  60. package/dist-es/mega-menu/MegaMenuActions.css.js +4 -0
  61. package/dist-es/mega-menu/MegaMenuActions.css.js.map +1 -0
  62. package/dist-es/mega-menu/MegaMenuActions.js +31 -0
  63. package/dist-es/mega-menu/MegaMenuActions.js.map +1 -0
  64. package/dist-es/mega-menu/MegaMenuAside.css.js +4 -0
  65. package/dist-es/mega-menu/MegaMenuAside.css.js.map +1 -0
  66. package/dist-es/mega-menu/MegaMenuAside.js +31 -0
  67. package/dist-es/mega-menu/MegaMenuAside.js.map +1 -0
  68. package/dist-es/mega-menu/MegaMenuContent.css.js +4 -0
  69. package/dist-es/mega-menu/MegaMenuContent.css.js.map +1 -0
  70. package/dist-es/mega-menu/{MegaMenuHeader.js → MegaMenuContent.js} +8 -8
  71. package/dist-es/mega-menu/MegaMenuContent.js.map +1 -0
  72. package/dist-es/mega-menu/MegaMenuContext.js.map +1 -1
  73. package/dist-es/mega-menu/MegaMenuGroup.css.js +1 -1
  74. package/dist-es/mega-menu/MegaMenuGroup.js +13 -28
  75. package/dist-es/mega-menu/MegaMenuGroup.js.map +1 -1
  76. package/dist-es/mega-menu/MegaMenuGroupContext.js +14 -0
  77. package/dist-es/mega-menu/MegaMenuGroupContext.js.map +1 -0
  78. package/dist-es/mega-menu/MegaMenuGroupHeading.css.js +4 -0
  79. package/dist-es/mega-menu/MegaMenuGroupHeading.css.js.map +1 -0
  80. package/dist-es/mega-menu/MegaMenuGroupHeading.js +37 -0
  81. package/dist-es/mega-menu/MegaMenuGroupHeading.js.map +1 -0
  82. package/dist-es/mega-menu/MegaMenuGroups.css.js +1 -1
  83. package/dist-es/mega-menu/MegaMenuGroups.js.map +1 -1
  84. package/dist-es/mega-menu/MegaMenuList.css.js +4 -0
  85. package/dist-es/mega-menu/MegaMenuList.css.js.map +1 -0
  86. package/dist-es/mega-menu/MegaMenuList.js +41 -0
  87. package/dist-es/mega-menu/MegaMenuList.js.map +1 -0
  88. package/dist-es/mega-menu/MegaMenuListItem.css.js +4 -0
  89. package/dist-es/mega-menu/MegaMenuListItem.css.js.map +1 -0
  90. package/dist-es/mega-menu/MegaMenuListItem.js +43 -0
  91. package/dist-es/mega-menu/MegaMenuListItem.js.map +1 -0
  92. package/dist-es/mega-menu/MegaMenuPanel.css.js +1 -1
  93. package/dist-es/mega-menu/MegaMenuPanel.js +30 -50
  94. package/dist-es/mega-menu/MegaMenuPanel.js.map +1 -1
  95. package/dist-es/mega-menu/MegaMenuTrigger.js +14 -16
  96. package/dist-es/mega-menu/MegaMenuTrigger.js.map +1 -1
  97. package/dist-es/mega-menu/useMegaMenuNavigation.js +278 -0
  98. package/dist-es/mega-menu/useMegaMenuNavigation.js.map +1 -0
  99. package/dist-es/mega-menu/usePageMargin.js +20 -0
  100. package/dist-es/mega-menu/usePageMargin.js.map +1 -0
  101. package/dist-types/index.d.ts +0 -1
  102. package/dist-types/mega-menu/MegaMenu.d.ts +11 -2
  103. package/dist-types/mega-menu/MegaMenuActions.d.ts +10 -0
  104. package/dist-types/mega-menu/MegaMenuAside.d.ts +9 -0
  105. package/dist-types/mega-menu/MegaMenuContent.d.ts +9 -0
  106. package/dist-types/mega-menu/MegaMenuContext.d.ts +6 -7
  107. package/dist-types/mega-menu/MegaMenuGroup.d.ts +4 -3
  108. package/dist-types/mega-menu/MegaMenuGroupContext.d.ts +12 -0
  109. package/dist-types/mega-menu/MegaMenuGroupHeading.d.ts +13 -0
  110. package/dist-types/mega-menu/MegaMenuGroups.d.ts +3 -3
  111. package/dist-types/mega-menu/MegaMenuList.d.ts +16 -0
  112. package/dist-types/mega-menu/MegaMenuListItem.d.ts +25 -0
  113. package/dist-types/mega-menu/MegaMenuPanel.d.ts +2 -2
  114. package/dist-types/mega-menu/MegaMenuTrigger.d.ts +1 -0
  115. package/dist-types/mega-menu/index.d.ts +6 -4
  116. package/dist-types/mega-menu/useMegaMenuNavigation.d.ts +16 -0
  117. package/dist-types/mega-menu/usePageMargin.d.ts +6 -0
  118. package/package.json +2 -2
  119. package/dist-cjs/mega-menu/MegaMenuHeader.css.js +0 -6
  120. package/dist-cjs/mega-menu/MegaMenuHeader.css.js.map +0 -1
  121. package/dist-cjs/mega-menu/MegaMenuHeader.js +0 -25
  122. package/dist-cjs/mega-menu/MegaMenuHeader.js.map +0 -1
  123. package/dist-cjs/mega-menu/MegaMenuItem.css.js +0 -6
  124. package/dist-cjs/mega-menu/MegaMenuItem.css.js.map +0 -1
  125. package/dist-cjs/mega-menu/MegaMenuItem.js +0 -53
  126. package/dist-cjs/mega-menu/MegaMenuItem.js.map +0 -1
  127. package/dist-cjs/mega-menu/MegaMenuSupportingActions.css.js +0 -6
  128. package/dist-cjs/mega-menu/MegaMenuSupportingActions.css.js.map +0 -1
  129. package/dist-cjs/mega-menu/MegaMenuSupportingActions.js +0 -31
  130. package/dist-cjs/mega-menu/MegaMenuSupportingActions.js.map +0 -1
  131. package/dist-cjs/mega-menu/MegaMenuSupportingContent.css.js +0 -6
  132. package/dist-cjs/mega-menu/MegaMenuSupportingContent.css.js.map +0 -1
  133. package/dist-cjs/mega-menu/MegaMenuSupportingContent.js +0 -31
  134. package/dist-cjs/mega-menu/MegaMenuSupportingContent.js.map +0 -1
  135. package/dist-cjs/mega-menu/useMegaMenuKeyboard.js +0 -209
  136. package/dist-cjs/mega-menu/useMegaMenuKeyboard.js.map +0 -1
  137. package/dist-cjs/toolbar-next/ToolbarContentNext.css.js +0 -6
  138. package/dist-cjs/toolbar-next/ToolbarContentNext.css.js.map +0 -1
  139. package/dist-cjs/toolbar-next/ToolbarContentNext.js +0 -32
  140. package/dist-cjs/toolbar-next/ToolbarContentNext.js.map +0 -1
  141. package/dist-cjs/toolbar-next/ToolbarNext.css.js +0 -6
  142. package/dist-cjs/toolbar-next/ToolbarNext.css.js.map +0 -1
  143. package/dist-cjs/toolbar-next/ToolbarNext.js +0 -394
  144. package/dist-cjs/toolbar-next/ToolbarNext.js.map +0 -1
  145. package/dist-cjs/toolbar-next/ToolbarNextOverflow.css.js +0 -6
  146. package/dist-cjs/toolbar-next/ToolbarNextOverflow.css.js.map +0 -1
  147. package/dist-cjs/toolbar-next/ToolbarNextOverflow.js +0 -706
  148. package/dist-cjs/toolbar-next/ToolbarNextOverflow.js.map +0 -1
  149. package/dist-cjs/toolbar-next/ToolbarNextOverflowFloatingBoundary.js +0 -165
  150. package/dist-cjs/toolbar-next/ToolbarNextOverflowFloatingBoundary.js.map +0 -1
  151. package/dist-cjs/toolbar-next/TooltrayNext.css.js +0 -6
  152. package/dist-cjs/toolbar-next/TooltrayNext.css.js.map +0 -1
  153. package/dist-cjs/toolbar-next/TooltrayNext.js +0 -55
  154. package/dist-cjs/toolbar-next/TooltrayNext.js.map +0 -1
  155. package/dist-cjs/toolbar-next/toolbarNextKeyboardUtils.js +0 -409
  156. package/dist-cjs/toolbar-next/toolbarNextKeyboardUtils.js.map +0 -1
  157. package/dist-cjs/toolbar-next/toolbarNextUtils.js +0 -215
  158. package/dist-cjs/toolbar-next/toolbarNextUtils.js.map +0 -1
  159. package/dist-cjs/toolbar-next/useToolbarNextKeyboardNavigation.js +0 -312
  160. package/dist-cjs/toolbar-next/useToolbarNextKeyboardNavigation.js.map +0 -1
  161. package/dist-cjs/toolbar-next/useToolbarNextOverflow.js +0 -743
  162. package/dist-cjs/toolbar-next/useToolbarNextOverflow.js.map +0 -1
  163. package/dist-es/mega-menu/MegaMenuHeader.css.js +0 -4
  164. package/dist-es/mega-menu/MegaMenuHeader.css.js.map +0 -1
  165. package/dist-es/mega-menu/MegaMenuHeader.js.map +0 -1
  166. package/dist-es/mega-menu/MegaMenuItem.css.js +0 -4
  167. package/dist-es/mega-menu/MegaMenuItem.css.js.map +0 -1
  168. package/dist-es/mega-menu/MegaMenuItem.js +0 -51
  169. package/dist-es/mega-menu/MegaMenuItem.js.map +0 -1
  170. package/dist-es/mega-menu/MegaMenuSupportingActions.css.js +0 -4
  171. package/dist-es/mega-menu/MegaMenuSupportingActions.css.js.map +0 -1
  172. package/dist-es/mega-menu/MegaMenuSupportingActions.js +0 -29
  173. package/dist-es/mega-menu/MegaMenuSupportingActions.js.map +0 -1
  174. package/dist-es/mega-menu/MegaMenuSupportingContent.css.js +0 -4
  175. package/dist-es/mega-menu/MegaMenuSupportingContent.css.js.map +0 -1
  176. package/dist-es/mega-menu/MegaMenuSupportingContent.js +0 -29
  177. package/dist-es/mega-menu/MegaMenuSupportingContent.js.map +0 -1
  178. package/dist-es/mega-menu/useMegaMenuKeyboard.js +0 -205
  179. package/dist-es/mega-menu/useMegaMenuKeyboard.js.map +0 -1
  180. package/dist-es/toolbar-next/ToolbarContentNext.css.js +0 -4
  181. package/dist-es/toolbar-next/ToolbarContentNext.css.js.map +0 -1
  182. package/dist-es/toolbar-next/ToolbarContentNext.js +0 -30
  183. package/dist-es/toolbar-next/ToolbarContentNext.js.map +0 -1
  184. package/dist-es/toolbar-next/ToolbarNext.css.js +0 -4
  185. package/dist-es/toolbar-next/ToolbarNext.css.js.map +0 -1
  186. package/dist-es/toolbar-next/ToolbarNext.js +0 -392
  187. package/dist-es/toolbar-next/ToolbarNext.js.map +0 -1
  188. package/dist-es/toolbar-next/ToolbarNextOverflow.css.js +0 -4
  189. package/dist-es/toolbar-next/ToolbarNextOverflow.css.js.map +0 -1
  190. package/dist-es/toolbar-next/ToolbarNextOverflow.js +0 -701
  191. package/dist-es/toolbar-next/ToolbarNextOverflow.js.map +0 -1
  192. package/dist-es/toolbar-next/ToolbarNextOverflowFloatingBoundary.js +0 -159
  193. package/dist-es/toolbar-next/ToolbarNextOverflowFloatingBoundary.js.map +0 -1
  194. package/dist-es/toolbar-next/TooltrayNext.css.js +0 -4
  195. package/dist-es/toolbar-next/TooltrayNext.css.js.map +0 -1
  196. package/dist-es/toolbar-next/TooltrayNext.js +0 -53
  197. package/dist-es/toolbar-next/TooltrayNext.js.map +0 -1
  198. package/dist-es/toolbar-next/toolbarNextKeyboardUtils.js +0 -390
  199. package/dist-es/toolbar-next/toolbarNextKeyboardUtils.js.map +0 -1
  200. package/dist-es/toolbar-next/toolbarNextUtils.js +0 -211
  201. package/dist-es/toolbar-next/toolbarNextUtils.js.map +0 -1
  202. package/dist-es/toolbar-next/useToolbarNextKeyboardNavigation.js +0 -310
  203. package/dist-es/toolbar-next/useToolbarNextKeyboardNavigation.js.map +0 -1
  204. package/dist-es/toolbar-next/useToolbarNextOverflow.js +0 -741
  205. package/dist-es/toolbar-next/useToolbarNextOverflow.js.map +0 -1
  206. package/dist-types/mega-menu/MegaMenuHeader.d.ts +0 -8
  207. package/dist-types/mega-menu/MegaMenuItem.d.ts +0 -13
  208. package/dist-types/mega-menu/MegaMenuSupportingActions.d.ts +0 -8
  209. package/dist-types/mega-menu/MegaMenuSupportingContent.d.ts +0 -8
  210. package/dist-types/mega-menu/useMegaMenuKeyboard.d.ts +0 -30
  211. package/dist-types/toolbar-next/ToolbarContentNext.d.ts +0 -11
  212. package/dist-types/toolbar-next/ToolbarNext.d.ts +0 -12
  213. package/dist-types/toolbar-next/ToolbarNextOverflow.d.ts +0 -34
  214. package/dist-types/toolbar-next/ToolbarNextOverflowFloatingBoundary.d.ts +0 -16
  215. package/dist-types/toolbar-next/TooltrayNext.d.ts +0 -37
  216. package/dist-types/toolbar-next/index.d.ts +0 -3
  217. package/dist-types/toolbar-next/toolbarNextKeyboardUtils.d.ts +0 -39
  218. package/dist-types/toolbar-next/toolbarNextUtils.d.ts +0 -42
  219. package/dist-types/toolbar-next/useToolbarNextKeyboardNavigation.d.ts +0 -42
  220. package/dist-types/toolbar-next/useToolbarNextOverflow.d.ts +0 -37
@@ -0,0 +1,45 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var core = require('@salt-ds/core');
5
+ var styles = require('@salt-ds/styles');
6
+ var window = require('@salt-ds/window');
7
+ var clsx = require('clsx');
8
+ var react = require('react');
9
+ var MegaMenuListItem$1 = require('./MegaMenuListItem.css.js');
10
+ var useMegaMenu = require('./useMegaMenu.js');
11
+
12
+ const withBaseName = core.makePrefixer("saltMegaMenuListItem");
13
+ function MegaMenuListItemAction(props) {
14
+ return core.renderProps("a", props);
15
+ }
16
+ const MegaMenuListItem = react.forwardRef(function MegaMenuListItem2({ children, className, onClick, render, href, current, ...rest }, ref) {
17
+ const targetWindow = window.useWindow();
18
+ const megaMenu = useMegaMenu.useMegaMenu();
19
+ styles.useComponentCssInjection({
20
+ testId: "salt-mega-menu-list-item",
21
+ css: MegaMenuListItem$1,
22
+ window: targetWindow
23
+ });
24
+ const handleClick = (event) => {
25
+ onClick == null ? void 0 : onClick(event);
26
+ megaMenu.setOpen(false);
27
+ };
28
+ return /* @__PURE__ */ jsxRuntime.jsx("li", { ref, className: clsx.clsx(withBaseName(), className), ...rest, children: /* @__PURE__ */ jsxRuntime.jsx(
29
+ MegaMenuListItemAction,
30
+ {
31
+ className: withBaseName("wrapper"),
32
+ href,
33
+ onClick: handleClick,
34
+ "aria-current": current ? "page" : void 0,
35
+ render,
36
+ children: react.Children.map(
37
+ children,
38
+ (child) => typeof child === "string" || typeof child === "number" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: withBaseName("content"), children: child }) : child
39
+ )
40
+ }
41
+ ) });
42
+ });
43
+
44
+ exports.MegaMenuListItem = MegaMenuListItem;
45
+ //# sourceMappingURL=MegaMenuListItem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MegaMenuListItem.js","sources":["../src/mega-menu/MegaMenuListItem.tsx"],"sourcesContent":["import { makePrefixer, type RenderPropsType, renderProps } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n Children,\n type ComponentPropsWithoutRef,\n forwardRef,\n type MouseEventHandler,\n type ReactNode,\n} from \"react\";\nimport megaMenuListItemCss from \"./MegaMenuListItem.css\";\nimport { useMegaMenu } from \"./useMegaMenu\";\n\nconst withBaseName = makePrefixer(\"saltMegaMenuListItem\");\n\n// biome-ignore lint/suspicious/noExplicitAny: We don't know the exact type here\nfunction MegaMenuListItemAction(props: ComponentPropsWithoutRef<any>) {\n return renderProps(\"a\", props);\n}\n\nexport interface MegaMenuListItemProps\n extends Omit<ComponentPropsWithoutRef<\"li\">, \"onClick\"> {\n /**\n * The content of the mega menu item.\n */\n children?: ReactNode;\n /**\n * Whether the item is the current page. Sets `aria-current=\"page\"`\n */\n current?: boolean;\n /**\n * Href passed to the link action element.\n */\n href?: string;\n /**\n * Called when the item's action is activated, before the menu closes.\n */\n onClick?: MouseEventHandler<HTMLAnchorElement>;\n /**\n * Render prop to enable customization of the underlying action element (e.g. a router `Link`).\n */\n render?: RenderPropsType[\"render\"];\n}\n\nexport const MegaMenuListItem = forwardRef<\n HTMLLIElement,\n MegaMenuListItemProps\n>(function MegaMenuListItem(\n { children, className, onClick, render, href, current, ...rest },\n ref,\n) {\n const targetWindow = useWindow();\n const megaMenu = useMegaMenu();\n\n useComponentCssInjection({\n testId: \"salt-mega-menu-list-item\",\n css: megaMenuListItemCss,\n window: targetWindow,\n });\n\n const handleClick: MouseEventHandler<HTMLAnchorElement> = (event) => {\n onClick?.(event);\n megaMenu.setOpen(false);\n };\n\n return (\n <li ref={ref} className={clsx(withBaseName(), className)} {...rest}>\n <MegaMenuListItemAction\n className={withBaseName(\"wrapper\")}\n href={href}\n onClick={handleClick}\n aria-current={current ? \"page\" : undefined}\n render={render}\n >\n {Children.map(children, (child) =>\n typeof child === \"string\" || typeof child === \"number\" ? (\n <span className={withBaseName(\"content\")}>{child}</span>\n ) : (\n child\n ),\n )}\n </MegaMenuListItemAction>\n </li>\n );\n});\n"],"names":["makePrefixer","renderProps","forwardRef","MegaMenuListItem","useWindow","useMegaMenu","useComponentCssInjection","megaMenuListItemCss","jsx","clsx","Children"],"mappings":";;;;;;;;;;;AAcA,MAAM,YAAA,GAAeA,kBAAa,sBAAsB,CAAA;AAGxD,SAAS,uBAAuB,KAAA,EAAsC;AACpE,EAAA,OAAOC,gBAAA,CAAY,KAAK,KAAK,CAAA;AAC/B;AA0BO,MAAM,gBAAA,GAAmBC,gBAAA,CAG9B,SAASC,iBAAAA,CACT,EAAE,QAAA,EAAU,SAAA,EAAW,OAAA,EAAS,MAAA,EAAQ,IAAA,EAAM,OAAA,EAAS,GAAG,IAAA,IAC1D,GAAA,EACA;AACA,EAAA,MAAM,eAAeC,gBAAA,EAAU;AAC/B,EAAA,MAAM,WAAWC,uBAAA,EAAY;AAE7B,EAAAC,+BAAA,CAAyB;AAAA,IACvB,MAAA,EAAQ,0BAAA;AAAA,IACR,GAAA,EAAKC,kBAAA;AAAA,IACL,MAAA,EAAQ;AAAA,GACT,CAAA;AAED,EAAA,MAAM,WAAA,GAAoD,CAAC,KAAA,KAAU;AACnE,IAAA,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAU,KAAA,CAAA;AACV,IAAA,QAAA,CAAS,QAAQ,KAAK,CAAA;AAAA,EACxB,CAAA;AAEA,EAAA,uBACEC,cAAA,CAAC,IAAA,EAAA,EAAG,GAAA,EAAU,SAAA,EAAWC,SAAA,CAAK,cAAa,EAAG,SAAS,CAAA,EAAI,GAAG,IAAA,EAC5D,QAAA,kBAAAD,cAAA;AAAA,IAAC,sBAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,aAAa,SAAS,CAAA;AAAA,MACjC,IAAA;AAAA,MACA,OAAA,EAAS,WAAA;AAAA,MACT,cAAA,EAAc,UAAU,MAAA,GAAS,MAAA;AAAA,MACjC,MAAA;AAAA,MAEC,QAAA,EAAAE,cAAA,CAAS,GAAA;AAAA,QAAI,QAAA;AAAA,QAAU,CAAC,KAAA,KACvB,OAAO,KAAA,KAAU,YAAY,OAAO,KAAA,KAAU,QAAA,mBAC5CF,cAAA,CAAC,UAAK,SAAA,EAAW,YAAA,CAAa,SAAS,CAAA,EAAI,iBAAM,CAAA,GAEjD;AAAA;AAEJ;AAAA,GACF,EACF,CAAA;AAEJ,CAAC;;;;"}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var css_248z = ".saltMegaMenuPanel {\n display: flex;\n flex-wrap: wrap;\n inline-size: var(--saltMegaMenuPanel-inlineSize, fit-content);\n max-inline-size: var(--saltMegaMenuPanel-maxInlineSize, var(--saltMegaMenuPanel-availableWidth, calc(100vw - var(--salt-spacing-600))));\n max-height: 90%;\n overflow-x: hidden;\n overflow-y: auto;\n box-sizing: border-box;\n border-radius: var(--salt-palette-corner);\n border: var(--salt-size-fixed-100) var(--salt-borderStyle-solid) var(--salt-container-primary-borderColor);\n background: var(--salt-container-primary-background);\n box-shadow: var(--salt-overlayable-shadow-popout);\n}\n";
3
+ var css_248z = ".saltMegaMenuPanel {\n /* Single horizontal row: optional side content, the center navigation area,\n optional side content. Position is derived from source order alone, so\n authors need no wrapper scaffolding. */\n --saltMegaMenuPanel-availableWidth: calc(100vw - var(--salt-spacing-600));\n display: flex;\n align-items: stretch;\n inline-size: var(--saltMegaMenuPanel-inlineSize, fit-content);\n max-inline-size: var(--saltMegaMenuPanel-maxInlineSize, var(--saltMegaMenuPanel-availableWidth));\n max-block-size: 90vh;\n overflow-x: hidden;\n overflow-y: auto;\n box-sizing: border-box;\n border-radius: var(--salt-palette-corner, 0);\n border: var(--salt-size-fixed-100) var(--salt-borderStyle-solid) var(--salt-container-primary-borderColor);\n background: var(--salt-container-primary-background);\n box-shadow: var(--salt-overlayable-shadow-modal);\n}\n";
4
4
 
5
5
  module.exports = css_248z;
6
6
  //# sourceMappingURL=MegaMenuPanel.css.js.map
@@ -9,6 +9,8 @@ var clsx = require('clsx');
9
9
  var react = require('react');
10
10
  var MegaMenuPanel$1 = require('./MegaMenuPanel.css.js');
11
11
  var useMegaMenu = require('./useMegaMenu.js');
12
+ var useMegaMenuNavigation = require('./useMegaMenuNavigation.js');
13
+ var usePageMargin = require('./usePageMargin.js');
12
14
 
13
15
  const withBaseName = core.makePrefixer("saltMegaMenuPanel");
14
16
  const MegaMenuPanel = react.forwardRef(
@@ -26,51 +28,36 @@ const MegaMenuPanel = react.forwardRef(
26
28
  placement,
27
29
  getFloatingProps,
28
30
  setFloating,
29
- focusFirstItemOnOpen,
31
+ focusFirstItemOnOpenRef,
30
32
  setPanelId
31
33
  } = useMegaMenu.useMegaMenu();
32
34
  const id = core.useId(idProp);
33
- react.useEffect(() => {
34
- setPanelId(id);
35
- return () => setPanelId(void 0);
35
+ core.useIsomorphicLayoutEffect(() => {
36
+ if (id) setPanelId(id);
36
37
  }, [id, setPanelId]);
37
- const [pageMargin, setPageMargin] = react.useState(0);
38
- react.useEffect(() => {
39
- if (!targetWindow) return;
40
- const referenceEl = floatingRootContext.elements.domReference;
41
- const host = referenceEl ?? targetWindow.document.body;
42
- const doc = targetWindow.document;
43
- const measure = () => {
44
- const probe = doc.createElement("div");
45
- probe.style.cssText = "position:absolute;visibility:hidden;pointer-events:none;width:var(--saltMegaMenuPanel-pageMargin, var(--salt-layout-page-margin));";
46
- host.appendChild(probe);
47
- const width = probe.getBoundingClientRect().width;
48
- probe.remove();
49
- setPageMargin((prev) => prev === width ? prev : width);
50
- };
51
- measure();
52
- targetWindow.addEventListener("resize", measure);
53
- return () => targetWindow.removeEventListener("resize", measure);
54
- }, [targetWindow, floatingRootContext]);
38
+ const { domReference } = floatingRootContext.elements;
39
+ const referenceEl = domReference instanceof HTMLElement ? domReference : null;
40
+ const pageMargin = usePageMargin.usePageMargin(referenceEl);
55
41
  const floatingUIResult = core.useFloatingUI({
56
42
  rootContext: floatingRootContext,
43
+ open: isOpen,
57
44
  placement,
58
45
  middleware: [
59
46
  react$1.offset(1),
60
47
  react$1.flip({ padding: pageMargin }),
61
- react$1.shift({ padding: pageMargin, limiter: react$1.limitShift() }),
62
- react$1.size({
63
- padding: pageMargin,
64
- apply({ availableWidth, elements }) {
65
- elements.floating.style.setProperty(
66
- "--saltMegaMenuPanel-availableWidth",
67
- `${availableWidth}px`
68
- );
69
- }
70
- })
48
+ react$1.shift({ padding: pageMargin, limiter: react$1.limitShift() })
71
49
  ]
72
50
  });
73
- const floatingProps = getFloatingProps();
51
+ const floatingEl = floatingRootContext.elements.floating;
52
+ const { isPositioned } = floatingUIResult;
53
+ react.useEffect(() => {
54
+ if (focusFirstItemOnOpenRef.current && isPositioned && floatingEl) {
55
+ useMegaMenuNavigation.focusFirstItem(floatingEl);
56
+ focusFirstItemOnOpenRef.current = false;
57
+ }
58
+ }, [focusFirstItemOnOpenRef, isPositioned, floatingEl]);
59
+ const floatingProps = getFloatingProps(rest);
60
+ const handleRef = core.useForkRef(setFloating, ref);
74
61
  return /* @__PURE__ */ jsxRuntime.jsx(
75
62
  FloatingComponent,
76
63
  {
@@ -81,24 +68,17 @@ const MegaMenuPanel = react.forwardRef(
81
68
  focusManagerProps: {
82
69
  context: floatingUIResult.context,
83
70
  modal: false,
84
- initialFocus: focusFirstItemOnOpen ? 0 : -1,
71
+ initialFocus: -1,
85
72
  returnFocus: true,
86
73
  closeOnFocusOut: false,
87
74
  guards: false
88
75
  },
89
- ref: setFloating,
90
- children: /* @__PURE__ */ jsxRuntime.jsx(
91
- "div",
92
- {
93
- className: clsx.clsx(withBaseName(), className),
94
- id,
95
- role: "region",
96
- ref,
97
- ...floatingProps,
98
- ...rest,
99
- children
100
- }
101
- )
76
+ className: clsx.clsx(withBaseName(), className),
77
+ id,
78
+ role: "region",
79
+ ...floatingProps,
80
+ ref: handleRef,
81
+ children
102
82
  }
103
83
  );
104
84
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MegaMenuPanel.js","sources":["../src/mega-menu/MegaMenuPanel.tsx"],"sourcesContent":["import { flip, limitShift, offset, shift, size } from \"@floating-ui/react\";\nimport {\n makePrefixer,\n useFloatingComponent,\n useFloatingUI,\n useId,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n forwardRef,\n type HTMLAttributes,\n type ReactNode,\n useEffect,\n useState,\n} from \"react\";\nimport megaMenuPanelCss from \"./MegaMenuPanel.css\";\nimport { useMegaMenu } from \"./useMegaMenu\";\n\nconst withBaseName = makePrefixer(\"saltMegaMenuPanel\");\n\nexport interface MegaMenuPanelProps extends HTMLAttributes<HTMLDivElement> {\n /**\n * The content of the mega menu panel.\n */\n children?: ReactNode;\n}\n\nexport const MegaMenuPanel = forwardRef<HTMLDivElement, MegaMenuPanelProps>(\n function MegaMenuPanel({ children, className, id: idProp, ...rest }, ref) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-mega-menu-panel\",\n css: megaMenuPanelCss,\n window: targetWindow,\n });\n\n const { Component: FloatingComponent } = useFloatingComponent();\n const {\n openState: isOpen,\n floatingRootContext,\n placement,\n getFloatingProps,\n setFloating,\n focusFirstItemOnOpen,\n setPanelId,\n } = useMegaMenu();\n\n const id = useId(idProp);\n\n // Register the panel id in context so the trigger can reference it via aria-controls.\n useEffect(() => {\n setPanelId(id);\n return () => setPanelId(undefined);\n }, [id, setPanelId]);\n\n // Resolve the panel's page-margin to a pixel value to override the margin as required.\n const [pageMargin, setPageMargin] = useState(0);\n useEffect(() => {\n if (!targetWindow) return;\n const referenceEl = floatingRootContext.elements.domReference as\n | HTMLElement\n | null\n | undefined;\n const host = referenceEl ?? targetWindow.document.body;\n const doc = targetWindow.document;\n const measure = () => {\n const probe = doc.createElement(\"div\");\n probe.style.cssText =\n \"position:absolute;visibility:hidden;pointer-events:none;width:var(--saltMegaMenuPanel-pageMargin, var(--salt-layout-page-margin));\";\n host.appendChild(probe);\n const width = probe.getBoundingClientRect().width;\n probe.remove();\n setPageMargin((prev) => (prev === width ? prev : width));\n };\n measure();\n targetWindow.addEventListener(\"resize\", measure);\n return () => targetWindow.removeEventListener(\"resize\", measure);\n }, [targetWindow, floatingRootContext]);\n\n const floatingUIResult = useFloatingUI({\n rootContext: floatingRootContext,\n placement,\n middleware: [\n offset(1),\n flip({ padding: pageMargin }),\n shift({ padding: pageMargin, limiter: limitShift() }),\n size({\n padding: pageMargin,\n apply({ availableWidth, elements }) {\n elements.floating.style.setProperty(\n \"--saltMegaMenuPanel-availableWidth\",\n `${availableWidth}px`,\n );\n },\n }),\n ],\n });\n\n const floatingProps = getFloatingProps();\n\n return (\n <FloatingComponent\n open={isOpen}\n position={floatingUIResult.strategy}\n top={floatingUIResult.y ?? 0}\n left={floatingUIResult.x ?? 0}\n focusManagerProps={{\n context: floatingUIResult.context,\n modal: false,\n initialFocus: focusFirstItemOnOpen ? 0 : -1,\n returnFocus: true,\n closeOnFocusOut: false,\n guards: false,\n }}\n ref={setFloating}\n >\n <div\n className={clsx(withBaseName(), className)}\n id={id}\n role=\"region\"\n ref={ref}\n {...floatingProps}\n {...rest}\n >\n {children}\n </div>\n </FloatingComponent>\n );\n },\n);\n"],"names":["makePrefixer","forwardRef","MegaMenuPanel","useWindow","useComponentCssInjection","megaMenuPanelCss","useFloatingComponent","useMegaMenu","useId","useEffect","useState","useFloatingUI","offset","flip","shift","limitShift","size","jsx","clsx"],"mappings":"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"}
1
+ {"version":3,"file":"MegaMenuPanel.js","sources":["../src/mega-menu/MegaMenuPanel.tsx"],"sourcesContent":["import { flip, limitShift, offset, shift } from \"@floating-ui/react\";\nimport {\n makePrefixer,\n useFloatingComponent,\n useFloatingUI,\n useForkRef,\n useId,\n useIsomorphicLayoutEffect,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type ReactNode,\n useEffect,\n} from \"react\";\nimport megaMenuPanelCss from \"./MegaMenuPanel.css\";\nimport { useMegaMenu } from \"./useMegaMenu\";\nimport { focusFirstItem } from \"./useMegaMenuNavigation\";\nimport { usePageMargin } from \"./usePageMargin\";\n\nconst withBaseName = makePrefixer(\"saltMegaMenuPanel\");\n\nexport interface MegaMenuPanelProps extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * The content of the mega menu panel.\n */\n children?: ReactNode;\n}\n\nexport const MegaMenuPanel = forwardRef<HTMLDivElement, MegaMenuPanelProps>(\n function MegaMenuPanel({ children, className, id: idProp, ...rest }, ref) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-mega-menu-panel\",\n css: megaMenuPanelCss,\n window: targetWindow,\n });\n\n const { Component: FloatingComponent } = useFloatingComponent();\n const {\n openState: isOpen,\n floatingRootContext,\n placement,\n getFloatingProps,\n setFloating,\n focusFirstItemOnOpenRef,\n setPanelId,\n } = useMegaMenu();\n\n const id = useId(idProp);\n\n // Register the panel's id so the trigger's aria-controls stays in sync.\n useIsomorphicLayoutEffect(() => {\n if (id) setPanelId(id);\n }, [id, setPanelId]);\n\n const { domReference } = floatingRootContext.elements;\n const referenceEl =\n domReference instanceof HTMLElement ? domReference : null;\n const pageMargin = usePageMargin(referenceEl);\n\n const floatingUIResult = useFloatingUI({\n rootContext: floatingRootContext,\n open: isOpen,\n placement,\n middleware: [\n offset(1),\n flip({ padding: pageMargin }),\n shift({ padding: pageMargin, limiter: limitShift() }),\n ],\n });\n\n // Focus the first item on ArrowDown open, after floating-ui has positioned the panel\n const floatingEl = floatingRootContext.elements.floating;\n const { isPositioned } = floatingUIResult;\n useEffect(() => {\n if (focusFirstItemOnOpenRef.current && isPositioned && floatingEl) {\n focusFirstItem(floatingEl);\n focusFirstItemOnOpenRef.current = false;\n }\n }, [focusFirstItemOnOpenRef, isPositioned, floatingEl]);\n\n const floatingProps = getFloatingProps(rest);\n const handleRef = useForkRef<HTMLDivElement>(setFloating, ref);\n\n return (\n <FloatingComponent\n open={isOpen}\n position={floatingUIResult.strategy}\n top={floatingUIResult.y ?? 0}\n left={floatingUIResult.x ?? 0}\n focusManagerProps={{\n context: floatingUIResult.context,\n modal: false,\n initialFocus: -1,\n returnFocus: true,\n closeOnFocusOut: false,\n guards: false,\n }}\n className={clsx(withBaseName(), className)}\n id={id}\n role=\"region\"\n {...floatingProps}\n ref={handleRef}\n >\n {children}\n </FloatingComponent>\n );\n },\n);\n"],"names":["makePrefixer","forwardRef","MegaMenuPanel","useWindow","useComponentCssInjection","megaMenuPanelCss","useFloatingComponent","useMegaMenu","useId","useIsomorphicLayoutEffect","usePageMargin","useFloatingUI","offset","flip","shift","limitShift","useEffect","focusFirstItem","useForkRef","jsx","clsx"],"mappings":"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"}
@@ -4,25 +4,25 @@ var jsxRuntime = require('react/jsx-runtime');
4
4
  var core = require('@salt-ds/core');
5
5
  var react = require('react');
6
6
  var useMegaMenu = require('./useMegaMenu.js');
7
- var useMegaMenuKeyboard = require('./useMegaMenuKeyboard.js');
7
+ var useMegaMenuNavigation = require('./useMegaMenuNavigation.js');
8
8
 
9
9
  function getAdjacentTrigger(currentTarget, direction) {
10
10
  const li = currentTarget.closest("li");
11
11
  if (!li) return null;
12
12
  const sibling = direction === "next" ? li.nextElementSibling : li.previousElementSibling;
13
13
  if (!(sibling instanceof HTMLElement)) return null;
14
- return sibling.querySelector(useMegaMenuKeyboard.FOCUSABLE_SELECTOR);
14
+ return sibling.querySelector(useMegaMenuNavigation.FOCUSABLE_SELECTOR);
15
15
  }
16
16
  const MegaMenuTrigger = react.forwardRef(
17
17
  function MegaMenuTrigger2(props, ref) {
18
- const { children, ...rest } = props;
18
+ const { children } = props;
19
19
  const megaMenu = useMegaMenu.useMegaMenu();
20
20
  const {
21
21
  getReferenceProps,
22
22
  setReference,
23
23
  setOpen,
24
24
  openState,
25
- setFocusFirstItemOnOpen,
25
+ focusFirstItemOnOpenRef,
26
26
  floatingRootContext,
27
27
  panelId
28
28
  } = megaMenu;
@@ -35,7 +35,7 @@ const MegaMenuTrigger = react.forwardRef(
35
35
  const adjacent = getAdjacentTrigger(event.currentTarget, direction);
36
36
  if (adjacent) {
37
37
  if (openState) setOpen(false);
38
- setFocusFirstItemOnOpen(false);
38
+ focusFirstItemOnOpenRef.current = false;
39
39
  adjacent.focus();
40
40
  }
41
41
  return;
@@ -43,22 +43,22 @@ const MegaMenuTrigger = react.forwardRef(
43
43
  if (openState && (key === "ArrowDown" || key === "Tab" && !shiftKey)) {
44
44
  event.preventDefault();
45
45
  const floating = floatingRootContext.elements.floating;
46
- if (floating) useMegaMenuKeyboard.focusFirstItem(floating);
46
+ if (floating) useMegaMenuNavigation.focusFirstItem(floating);
47
+ return;
48
+ }
49
+ if (openState && key === "Tab" && shiftKey) {
50
+ focusFirstItemOnOpenRef.current = false;
51
+ setOpen(false);
47
52
  return;
48
53
  }
49
54
  if (!openState && key === "ArrowDown") {
50
55
  event.preventDefault();
51
- setFocusFirstItemOnOpen(true);
56
+ focusFirstItemOnOpenRef.current = true;
52
57
  setOpen(true);
53
58
  return;
54
59
  }
55
60
  },
56
- [
57
- openState,
58
- setOpen,
59
- setFocusFirstItemOnOpen,
60
- floatingRootContext.elements.floating
61
- ]
61
+ [openState, setOpen, floatingRootContext.elements.floating]
62
62
  );
63
63
  const handleFloatingRef = core.useForkRef(
64
64
  core.getRefFromChildren(children),
@@ -74,12 +74,10 @@ const MegaMenuTrigger = react.forwardRef(
74
74
  return react.cloneElement(children, {
75
75
  ...core.mergeProps(
76
76
  getReferenceProps({
77
- // For NavigationItem, sync via the `expanded` prop (which maps to aria-expanded internally).
78
- // For all other elements, set aria-expanded directly.
77
+ // NavigationItem maps `expanded` to aria-expanded; others get it directly.
79
78
  ...shouldSyncExpanded ? { expanded: openState } : { "aria-expanded": openState },
80
- ...panelId && openState ? { "aria-controls": panelId } : null,
81
- onKeyDown: handleKeyDown,
82
- ...rest
79
+ ...openState ? { "aria-controls": panelId } : null,
80
+ onKeyDown: handleKeyDown
83
81
  }),
84
82
  children.props
85
83
  ),
@@ -1 +1 @@
1
- {"version":3,"file":"MegaMenuTrigger.js","sources":["../src/mega-menu/MegaMenuTrigger.tsx"],"sourcesContent":["import {\n getRefFromChildren,\n mergeProps,\n NavigationItem,\n useForkRef,\n} from \"@salt-ds/core\";\nimport {\n cloneElement,\n forwardRef,\n isValidElement,\n type KeyboardEvent,\n type ReactNode,\n type Ref,\n useCallback,\n} from \"react\";\nimport { useMegaMenu } from \"./useMegaMenu\";\nimport { FOCUSABLE_SELECTOR, focusFirstItem } from \"./useMegaMenuKeyboard\";\n\nexport interface MegaMenuTriggerProps {\n /**\n * The trigger element for the mega menu, typically a `NavigationItem` or `Button`.\n */\n children?: ReactNode;\n}\n\nfunction getAdjacentTrigger(\n currentTarget: HTMLElement,\n direction: \"next\" | \"previous\",\n): HTMLElement | null {\n const li = currentTarget.closest(\"li\");\n if (!li) return null;\n const sibling =\n direction === \"next\" ? li.nextElementSibling : li.previousElementSibling;\n if (!(sibling instanceof HTMLElement)) return null;\n return sibling.querySelector<HTMLElement>(FOCUSABLE_SELECTOR);\n}\n\nexport const MegaMenuTrigger = forwardRef<HTMLElement, MegaMenuTriggerProps>(\n function MegaMenuTrigger(props, ref) {\n const { children, ...rest } = props;\n const megaMenu = useMegaMenu();\n\n const {\n getReferenceProps,\n setReference,\n setOpen,\n openState,\n setFocusFirstItemOnOpen,\n floatingRootContext,\n panelId,\n } = megaMenu;\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLElement>) => {\n const { key, shiftKey } = event;\n\n // ArrowLeft/Right: move to adjacent trigger in nav bar\n if (key === \"ArrowRight\" || key === \"ArrowLeft\") {\n event.preventDefault();\n const direction = key === \"ArrowRight\" ? \"next\" : \"previous\";\n const adjacent = getAdjacentTrigger(event.currentTarget, direction);\n if (adjacent) {\n if (openState) setOpen(false);\n setFocusFirstItemOnOpen(false);\n adjacent.focus();\n }\n return;\n }\n\n // When menu is open: ArrowDown or Tab moves focus into the menu\n if (\n openState &&\n (key === \"ArrowDown\" || (key === \"Tab\" && !shiftKey))\n ) {\n event.preventDefault();\n const floating = floatingRootContext.elements\n .floating as HTMLElement | null;\n if (floating) focusFirstItem(floating);\n return;\n }\n\n // When menu is closed: ArrowDown opens and focuses first item\n if (!openState && key === \"ArrowDown\") {\n event.preventDefault();\n setFocusFirstItemOnOpen(true);\n setOpen(true);\n return;\n }\n },\n [\n openState,\n setOpen,\n setFocusFirstItemOnOpen,\n floatingRootContext.elements.floating,\n ],\n );\n\n const handleFloatingRef = useForkRef(\n getRefFromChildren(children),\n setReference,\n );\n const handleRef = useForkRef(handleFloatingRef, ref);\n\n if (!children || !isValidElement<{ ref?: Ref<unknown> }>(children)) {\n return <>{children}</>;\n }\n\n const childProps = children.props as Record<string, unknown>;\n const isNavigationItemChild = children.type === NavigationItem;\n const shouldSyncExpanded =\n isNavigationItemChild || childProps.expanded !== undefined;\n\n return cloneElement(children, {\n ...mergeProps(\n getReferenceProps({\n // For NavigationItem, sync via the `expanded` prop (which maps to aria-expanded internally).\n // For all other elements, set aria-expanded directly.\n ...(shouldSyncExpanded\n ? { expanded: openState }\n : { \"aria-expanded\": openState }),\n ...(panelId && openState ? { \"aria-controls\": panelId } : null),\n onKeyDown: handleKeyDown,\n ...rest,\n }),\n children.props,\n ),\n ref: handleRef,\n });\n },\n);\n"],"names":["FOCUSABLE_SELECTOR","forwardRef","MegaMenuTrigger","useMegaMenu","useCallback","useForkRef","getRefFromChildren","isValidElement","NavigationItem","cloneElement","mergeProps"],"mappings":"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"}
1
+ {"version":3,"file":"MegaMenuTrigger.js","sources":["../src/mega-menu/MegaMenuTrigger.tsx"],"sourcesContent":["import {\n getRefFromChildren,\n mergeProps,\n NavigationItem,\n useForkRef,\n} from \"@salt-ds/core\";\nimport {\n cloneElement,\n forwardRef,\n isValidElement,\n type KeyboardEvent,\n type ReactNode,\n type Ref,\n useCallback,\n} from \"react\";\nimport { useMegaMenu } from \"./useMegaMenu\";\nimport { FOCUSABLE_SELECTOR, focusFirstItem } from \"./useMegaMenuNavigation\";\n\nexport interface MegaMenuTriggerProps {\n /**\n * The trigger element for the mega menu, typically a `NavigationItem` or `Button`.\n * Wrap each mega menu in its own `<li>` — arrow-key navigation between triggers depends on it.\n */\n children?: ReactNode;\n}\n\nfunction getAdjacentTrigger(\n currentTarget: HTMLElement,\n direction: \"next\" | \"previous\",\n): HTMLElement | null {\n const li = currentTarget.closest(\"li\");\n if (!li) return null;\n const sibling =\n direction === \"next\" ? li.nextElementSibling : li.previousElementSibling;\n if (!(sibling instanceof HTMLElement)) return null;\n return sibling.querySelector<HTMLElement>(FOCUSABLE_SELECTOR);\n}\n\nexport const MegaMenuTrigger = forwardRef<HTMLElement, MegaMenuTriggerProps>(\n function MegaMenuTrigger(props, ref) {\n const { children } = props;\n const megaMenu = useMegaMenu();\n\n const {\n getReferenceProps,\n setReference,\n setOpen,\n openState,\n focusFirstItemOnOpenRef,\n floatingRootContext,\n panelId,\n } = megaMenu;\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLElement>) => {\n const { key, shiftKey } = event;\n\n // ArrowLeft/Right: move to adjacent trigger in nav bar\n if (key === \"ArrowRight\" || key === \"ArrowLeft\") {\n event.preventDefault();\n const direction = key === \"ArrowRight\" ? \"next\" : \"previous\";\n const adjacent = getAdjacentTrigger(event.currentTarget, direction);\n if (adjacent) {\n if (openState) setOpen(false);\n focusFirstItemOnOpenRef.current = false;\n adjacent.focus();\n }\n return;\n }\n\n // When menu is open: ArrowDown or Tab moves focus into the menu\n if (\n openState &&\n (key === \"ArrowDown\" || (key === \"Tab\" && !shiftKey))\n ) {\n event.preventDefault();\n const floating = floatingRootContext.elements\n .floating as HTMLElement | null;\n if (floating) focusFirstItem(floating);\n return;\n }\n\n // When menu is open: Shift+Tab mirrors arrow left\n if (openState && key === \"Tab\" && shiftKey) {\n focusFirstItemOnOpenRef.current = false;\n setOpen(false);\n return;\n }\n\n // When menu is closed: ArrowDown opens and focuses first item\n if (!openState && key === \"ArrowDown\") {\n event.preventDefault();\n focusFirstItemOnOpenRef.current = true;\n setOpen(true);\n return;\n }\n },\n [openState, setOpen, floatingRootContext.elements.floating],\n );\n\n const handleFloatingRef = useForkRef(\n getRefFromChildren(children),\n setReference,\n );\n const handleRef = useForkRef(handleFloatingRef, ref);\n\n if (!children || !isValidElement<{ ref?: Ref<unknown> }>(children)) {\n return <>{children}</>;\n }\n\n const childProps = children.props as Record<string, unknown>;\n const isNavigationItemChild = children.type === NavigationItem;\n const shouldSyncExpanded =\n isNavigationItemChild || childProps.expanded !== undefined;\n\n return cloneElement(children, {\n ...mergeProps(\n getReferenceProps({\n // NavigationItem maps `expanded` to aria-expanded; others get it directly.\n ...(shouldSyncExpanded\n ? { expanded: openState }\n : { \"aria-expanded\": openState }),\n ...(openState ? { \"aria-controls\": panelId } : null),\n onKeyDown: handleKeyDown,\n }),\n children.props,\n ),\n ref: handleRef,\n });\n },\n);\n"],"names":["FOCUSABLE_SELECTOR","forwardRef","MegaMenuTrigger","useMegaMenu","useCallback","useForkRef","getRefFromChildren","isValidElement","NavigationItem","cloneElement","mergeProps"],"mappings":"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"}
@@ -0,0 +1,282 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+
5
+ const COLUMN_SELECTOR = "[data-mega-menu-column]";
6
+ const ACTIONS_SELECTOR = "[data-mega-menu-actions]";
7
+ const FOCUSABLE_SELECTOR = 'a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"])';
8
+ const SELF_CONSUMING_SELECTOR = 'input, textarea, select, [contenteditable], [role="combobox"], [role="listbox"], [role="slider"], [role="spinbutton"], [role="textbox"]';
9
+ const HIDDEN_ANCESTOR_SELECTOR = '[aria-hidden="true"], [inert]';
10
+ function queryFocusables(root) {
11
+ return Array.from(
12
+ root.querySelectorAll(FOCUSABLE_SELECTOR)
13
+ ).filter((el) => !el.closest(HIDDEN_ANCESTOR_SELECTOR));
14
+ }
15
+ function firstFocusable(root) {
16
+ return root ? queryFocusables(root)[0] ?? null : null;
17
+ }
18
+ function buildModel(panel) {
19
+ const columns = Array.from(
20
+ panel.querySelectorAll(COLUMN_SELECTOR)
21
+ ).filter((el) => queryFocusables(el).length > 0);
22
+ const actions = Array.from(
23
+ panel.querySelectorAll(ACTIONS_SELECTOR)
24
+ ).filter((el) => queryFocusables(el).length > 0);
25
+ return { columns, actions };
26
+ }
27
+ function focusTrigger(context) {
28
+ var _a;
29
+ const reference = context.elements.reference;
30
+ (_a = firstFocusable(reference) ?? reference) == null ? void 0 : _a.focus();
31
+ }
32
+ function focusNextTriggerAndClose(context) {
33
+ const reference = context.elements.reference;
34
+ const trigger = firstFocusable(reference) ?? reference;
35
+ const li = trigger == null ? void 0 : trigger.closest("li");
36
+ const next = (li == null ? void 0 : li.nextElementSibling) instanceof HTMLElement ? firstFocusable(li.nextElementSibling) : null;
37
+ if (next) {
38
+ context.onOpenChange(false);
39
+ next.focus();
40
+ return true;
41
+ }
42
+ return false;
43
+ }
44
+ function columnsStacked(columns) {
45
+ if (columns.length < 2) return false;
46
+ const first = columns[0].getBoundingClientRect();
47
+ const second = columns[1].getBoundingClientRect();
48
+ return second.top >= first.bottom - 1;
49
+ }
50
+ function handleLinear(key, cell, panel, context) {
51
+ var _a, _b;
52
+ const cells = queryFocusables(panel);
53
+ const index = cells.indexOf(cell);
54
+ if (index === -1) return false;
55
+ switch (key) {
56
+ case "ArrowDown":
57
+ case "ArrowRight": {
58
+ if (index < cells.length - 1) {
59
+ cells[index + 1].focus();
60
+ }
61
+ return true;
62
+ }
63
+ case "ArrowUp":
64
+ case "ArrowLeft": {
65
+ if (index > 0) {
66
+ cells[index - 1].focus();
67
+ } else {
68
+ focusTrigger(context);
69
+ }
70
+ return true;
71
+ }
72
+ case "Home": {
73
+ (_a = cells[0]) == null ? void 0 : _a.focus();
74
+ return true;
75
+ }
76
+ case "End": {
77
+ (_b = cells[cells.length - 1]) == null ? void 0 : _b.focus();
78
+ return true;
79
+ }
80
+ default:
81
+ return false;
82
+ }
83
+ }
84
+ function handleArrow(key, cell, panel, context) {
85
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
86
+ const { columns, actions } = buildModel(panel);
87
+ if (columnsStacked(columns)) {
88
+ return handleLinear(key, cell, panel, context);
89
+ }
90
+ const column = cell.closest(COLUMN_SELECTOR);
91
+ const actionsEl = cell.closest(ACTIONS_SELECTOR);
92
+ if (column) {
93
+ const colIndex = columns.indexOf(column);
94
+ const cells = queryFocusables(column);
95
+ const rowIndex = cells.indexOf(cell);
96
+ switch (key) {
97
+ case "ArrowDown": {
98
+ if (rowIndex < cells.length - 1) {
99
+ cells[rowIndex + 1].focus();
100
+ } else if (colIndex < columns.length - 1) {
101
+ (_a = firstFocusable(columns[colIndex + 1])) == null ? void 0 : _a.focus();
102
+ } else if (actions.length > 0) {
103
+ (_b = firstFocusable(actions[0])) == null ? void 0 : _b.focus();
104
+ } else {
105
+ focusNextTriggerAndClose(context);
106
+ }
107
+ return true;
108
+ }
109
+ case "ArrowUp": {
110
+ if (rowIndex > 0) {
111
+ cells[rowIndex - 1].focus();
112
+ } else {
113
+ focusTrigger(context);
114
+ }
115
+ return true;
116
+ }
117
+ case "ArrowRight": {
118
+ if (colIndex < columns.length - 1) {
119
+ (_c = firstFocusable(columns[colIndex + 1])) == null ? void 0 : _c.focus();
120
+ return true;
121
+ }
122
+ if (rowIndex === cells.length - 1 && focusNextTriggerAndClose(context)) {
123
+ return true;
124
+ }
125
+ focusTrigger(context);
126
+ return true;
127
+ }
128
+ case "ArrowLeft": {
129
+ if (colIndex > 0) {
130
+ (_d = firstFocusable(columns[colIndex - 1])) == null ? void 0 : _d.focus();
131
+ } else {
132
+ focusTrigger(context);
133
+ }
134
+ return true;
135
+ }
136
+ case "Home": {
137
+ (_e = cells[0]) == null ? void 0 : _e.focus();
138
+ return true;
139
+ }
140
+ case "End": {
141
+ (_f = cells[cells.length - 1]) == null ? void 0 : _f.focus();
142
+ return true;
143
+ }
144
+ default:
145
+ return false;
146
+ }
147
+ }
148
+ if (actionsEl) {
149
+ const cells = queryFocusables(actionsEl);
150
+ const index = cells.indexOf(cell);
151
+ switch (key) {
152
+ case "ArrowRight": {
153
+ if (index < cells.length - 1) {
154
+ cells[index + 1].focus();
155
+ } else if (!focusNextTriggerAndClose(context)) {
156
+ focusTrigger(context);
157
+ }
158
+ return true;
159
+ }
160
+ case "ArrowLeft": {
161
+ if (index > 0) {
162
+ cells[index - 1].focus();
163
+ } else if (cell === firstFocusable(panel)) {
164
+ focusTrigger(context);
165
+ }
166
+ return true;
167
+ }
168
+ case "ArrowUp": {
169
+ if (columns.length > 0) {
170
+ const lastColumnCells = queryFocusables(columns[columns.length - 1]);
171
+ (_g = lastColumnCells[lastColumnCells.length - 1]) == null ? void 0 : _g.focus();
172
+ } else {
173
+ focusTrigger(context);
174
+ }
175
+ return true;
176
+ }
177
+ case "ArrowDown": {
178
+ if (index === cells.length - 1) {
179
+ focusNextTriggerAndClose(context);
180
+ }
181
+ return true;
182
+ }
183
+ case "Home": {
184
+ (_h = cells[0]) == null ? void 0 : _h.focus();
185
+ return true;
186
+ }
187
+ case "End": {
188
+ (_i = cells[cells.length - 1]) == null ? void 0 : _i.focus();
189
+ return true;
190
+ }
191
+ default:
192
+ return false;
193
+ }
194
+ }
195
+ return false;
196
+ }
197
+ function focusNextAfterPanel(context, panel) {
198
+ var _a;
199
+ const reference = context.elements.reference;
200
+ const refFocusable = firstFocusable(reference) ?? reference;
201
+ const nextLi = (_a = refFocusable == null ? void 0 : refFocusable.closest("li")) == null ? void 0 : _a.nextElementSibling;
202
+ const nextSibling = nextLi instanceof HTMLElement ? firstFocusable(nextLi) : null;
203
+ const nextOutside = nextSibling || (() => {
204
+ const allFocusable = queryFocusables(
205
+ panel.ownerDocument.documentElement
206
+ ).filter((el) => !panel.contains(el));
207
+ const idx = refFocusable ? allFocusable.indexOf(refFocusable) : -1;
208
+ return idx >= 0 ? allFocusable[idx + 1] : void 0;
209
+ })();
210
+ if (nextOutside) {
211
+ const view = panel.ownerDocument.defaultView;
212
+ view == null ? void 0 : view.requestAnimationFrame(() => {
213
+ view == null ? void 0 : view.requestAnimationFrame(() => {
214
+ nextOutside.focus();
215
+ });
216
+ });
217
+ }
218
+ }
219
+ function useMegaMenuNavigation(context, props = {}) {
220
+ const { enabled = true } = props;
221
+ const { open, onOpenChange } = context;
222
+ return react.useMemo(() => {
223
+ if (!enabled) {
224
+ return {};
225
+ }
226
+ return {
227
+ floating: {
228
+ onKeyDown(event) {
229
+ var _a, _b;
230
+ if (!open) return;
231
+ const panel = event.currentTarget;
232
+ const target = event.target;
233
+ const { key } = event;
234
+ const isArrowOrEdge = key === "ArrowUp" || key === "ArrowDown" || key === "ArrowLeft" || key === "ArrowRight" || key === "Home" || key === "End";
235
+ if (isArrowOrEdge && target.closest(SELF_CONSUMING_SELECTOR)) {
236
+ return;
237
+ }
238
+ const cell = target.closest(FOCUSABLE_SELECTOR);
239
+ if (key === "Tab") {
240
+ const allCells = queryFocusables(panel);
241
+ const linearIndex = cell ? allCells.indexOf(cell) : -1;
242
+ if (linearIndex === -1) return;
243
+ event.preventDefault();
244
+ if (event.shiftKey) {
245
+ if (linearIndex === 0) {
246
+ focusTrigger(context);
247
+ } else {
248
+ (_a = allCells[linearIndex - 1]) == null ? void 0 : _a.focus();
249
+ }
250
+ } else if (linearIndex === allCells.length - 1) {
251
+ onOpenChange(false);
252
+ focusNextAfterPanel(context, panel);
253
+ } else {
254
+ (_b = allCells[linearIndex + 1]) == null ? void 0 : _b.focus();
255
+ }
256
+ return;
257
+ }
258
+ if (!cell || !isArrowOrEdge) return;
259
+ if (handleArrow(key, cell, panel, context)) {
260
+ event.preventDefault();
261
+ }
262
+ }
263
+ }
264
+ };
265
+ }, [enabled, open, context, onOpenChange]);
266
+ }
267
+ function focusFirstItem(panel, attempt = 0) {
268
+ const firstItem = firstFocusable(panel);
269
+ if (firstItem) {
270
+ firstItem.focus();
271
+ return;
272
+ }
273
+ const view = panel.ownerDocument.defaultView;
274
+ if (attempt < 3 && view) {
275
+ view.requestAnimationFrame(() => focusFirstItem(panel, attempt + 1));
276
+ }
277
+ }
278
+
279
+ exports.FOCUSABLE_SELECTOR = FOCUSABLE_SELECTOR;
280
+ exports.focusFirstItem = focusFirstItem;
281
+ exports.useMegaMenuNavigation = useMegaMenuNavigation;
282
+ //# sourceMappingURL=useMegaMenuNavigation.js.map