@navikt/ds-react 7.2.1 → 7.3.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 (209) hide show
  1. package/cjs/accordion/AccordionHeader.js +1 -1
  2. package/cjs/accordion/AccordionHeader.js.map +1 -1
  3. package/cjs/alert/Alert.d.ts +0 -3
  4. package/cjs/alert/Alert.js +11 -17
  5. package/cjs/alert/Alert.js.map +1 -1
  6. package/cjs/chips/Removable.d.ts +5 -5
  7. package/cjs/chips/Removable.js +4 -2
  8. package/cjs/chips/Removable.js.map +1 -1
  9. package/cjs/collapsible/Collapsible.context.d.ts +1 -1
  10. package/cjs/date/datepicker/DatePicker.d.ts +2 -2
  11. package/cjs/date/monthpicker/MonthPicker.d.ts +2 -2
  12. package/cjs/form/file-upload/FileUpload.context.d.ts +1 -1
  13. package/cjs/index.d.ts +1 -0
  14. package/cjs/index.js +4 -2
  15. package/cjs/index.js.map +1 -1
  16. package/cjs/layout/base/BasePrimitive.d.ts +3 -0
  17. package/cjs/layout/base/BasePrimitive.js.map +1 -1
  18. package/cjs/layout/box/Box.d.ts +2 -2
  19. package/cjs/layout/box/Box.js.map +1 -1
  20. package/cjs/layout/grid/HGrid.d.ts +2 -2
  21. package/cjs/layout/grid/HGrid.js.map +1 -1
  22. package/cjs/layout/stack/Stack.d.ts +2 -2
  23. package/cjs/layout/stack/Stack.js.map +1 -1
  24. package/cjs/modal/ModalHeader.js +6 -1
  25. package/cjs/modal/ModalHeader.js.map +1 -1
  26. package/cjs/modal/dialog-polyfill.js +2 -2
  27. package/cjs/modal/dialog-polyfill.js.map +1 -1
  28. package/cjs/overlays/action-menu/ActionMenu.d.ts +310 -0
  29. package/cjs/overlays/action-menu/ActionMenu.js +227 -0
  30. package/cjs/overlays/action-menu/ActionMenu.js.map +1 -0
  31. package/cjs/overlays/action-menu/index.d.ts +1 -0
  32. package/cjs/overlays/action-menu/index.js +19 -0
  33. package/cjs/overlays/action-menu/index.js.map +1 -0
  34. package/cjs/overlays/floating/Floating.js +9 -10
  35. package/cjs/overlays/floating/Floating.js.map +1 -1
  36. package/cjs/overlays/floating/Floating.utils.d.ts +3 -5
  37. package/cjs/overlays/floating/Floating.utils.js +0 -2
  38. package/cjs/overlays/floating/Floating.utils.js.map +1 -1
  39. package/cjs/overlays/floating-menu/Menu.d.ts +15 -21
  40. package/cjs/overlays/floating-menu/Menu.js +119 -230
  41. package/cjs/overlays/floating-menu/Menu.js.map +1 -1
  42. package/cjs/overlays/floating-menu/parts/RovingFocus.d.ts +1 -1
  43. package/cjs/overlays/floating-menu/parts/RovingFocus.js.map +1 -1
  44. package/cjs/pagination/Pagination.d.ts +1 -6
  45. package/cjs/pagination/Pagination.js.map +1 -1
  46. package/cjs/provider/i18n/LanguageProvider.d.ts +3 -3
  47. package/cjs/stepper/context.d.ts +1 -1
  48. package/cjs/table/Body.d.ts +2 -4
  49. package/cjs/table/Body.js.map +1 -1
  50. package/cjs/table/ColumnHeader.d.ts +1 -2
  51. package/cjs/table/ColumnHeader.js.map +1 -1
  52. package/cjs/table/ExpandableRow.d.ts +1 -2
  53. package/cjs/table/ExpandableRow.js.map +1 -1
  54. package/cjs/table/Header.d.ts +2 -4
  55. package/cjs/table/Header.js.map +1 -1
  56. package/cjs/table/HeaderCell.d.ts +1 -2
  57. package/cjs/table/HeaderCell.js.map +1 -1
  58. package/cjs/table/Row.d.ts +1 -2
  59. package/cjs/table/Row.js.map +1 -1
  60. package/cjs/tabs/Tabs.context.d.ts +1 -1
  61. package/cjs/toggle-group/ToggleGroup.context.d.ts +1 -1
  62. package/cjs/util/i18n/get.d.ts +2 -2
  63. package/cjs/util/i18n/get.js.map +1 -1
  64. package/cjs/util/i18n/i18n.context.d.ts +2 -3
  65. package/cjs/util/i18n/i18n.context.js.map +1 -1
  66. package/cjs/util/i18n/i18n.types.d.ts +5 -9
  67. package/cjs/util/i18n/locales/en.d.ts +39 -0
  68. package/cjs/util/i18n/locales/en.js +41 -0
  69. package/cjs/util/i18n/locales/en.js.map +1 -0
  70. package/cjs/util/i18n/locales/nb.d.ts +14 -0
  71. package/cjs/util/i18n/locales/nb.js +14 -0
  72. package/cjs/util/i18n/locales/nb.js.map +1 -1
  73. package/cjs/util/i18n/locales/nn.d.ts +39 -0
  74. package/cjs/util/i18n/locales/nn.js +41 -0
  75. package/cjs/util/i18n/locales/nn.js.map +1 -0
  76. package/cjs/util/requireReactElement.d.ts +2 -0
  77. package/cjs/util/requireReactElement.js +22 -0
  78. package/cjs/util/requireReactElement.js.map +1 -0
  79. package/cjs/util/virtualfocus/Context.d.ts +1 -1
  80. package/cjs/util/virtualfocus/parts/VirtualFocusContent.d.ts +1 -2
  81. package/cjs/util/virtualfocus/parts/VirtualFocusContent.js.map +1 -1
  82. package/esm/accordion/AccordionHeader.js +1 -1
  83. package/esm/accordion/AccordionHeader.js.map +1 -1
  84. package/esm/alert/Alert.d.ts +0 -3
  85. package/esm/alert/Alert.js +11 -17
  86. package/esm/alert/Alert.js.map +1 -1
  87. package/esm/chips/Removable.d.ts +5 -5
  88. package/esm/chips/Removable.js +4 -2
  89. package/esm/chips/Removable.js.map +1 -1
  90. package/esm/collapsible/Collapsible.context.d.ts +1 -1
  91. package/esm/date/datepicker/DatePicker.d.ts +2 -2
  92. package/esm/date/monthpicker/MonthPicker.d.ts +2 -2
  93. package/esm/form/file-upload/FileUpload.context.d.ts +1 -1
  94. package/esm/index.d.ts +1 -0
  95. package/esm/index.js +1 -0
  96. package/esm/index.js.map +1 -1
  97. package/esm/layout/base/BasePrimitive.d.ts +3 -0
  98. package/esm/layout/base/BasePrimitive.js.map +1 -1
  99. package/esm/layout/box/Box.d.ts +2 -2
  100. package/esm/layout/box/Box.js.map +1 -1
  101. package/esm/layout/grid/HGrid.d.ts +2 -2
  102. package/esm/layout/grid/HGrid.js.map +1 -1
  103. package/esm/layout/stack/Stack.d.ts +2 -2
  104. package/esm/layout/stack/Stack.js.map +1 -1
  105. package/esm/modal/ModalHeader.js +6 -1
  106. package/esm/modal/ModalHeader.js.map +1 -1
  107. package/esm/modal/dialog-polyfill.js +2 -2
  108. package/esm/modal/dialog-polyfill.js.map +1 -1
  109. package/esm/overlays/action-menu/ActionMenu.d.ts +310 -0
  110. package/esm/overlays/action-menu/ActionMenu.js +197 -0
  111. package/esm/overlays/action-menu/ActionMenu.js.map +1 -0
  112. package/esm/overlays/action-menu/index.d.ts +1 -0
  113. package/esm/overlays/action-menu/index.js +3 -0
  114. package/esm/overlays/action-menu/index.js.map +1 -0
  115. package/esm/overlays/floating/Floating.js +9 -10
  116. package/esm/overlays/floating/Floating.js.map +1 -1
  117. package/esm/overlays/floating/Floating.utils.d.ts +3 -5
  118. package/esm/overlays/floating/Floating.utils.js +0 -2
  119. package/esm/overlays/floating/Floating.utils.js.map +1 -1
  120. package/esm/overlays/floating-menu/Menu.d.ts +15 -21
  121. package/esm/overlays/floating-menu/Menu.js +119 -230
  122. package/esm/overlays/floating-menu/Menu.js.map +1 -1
  123. package/esm/overlays/floating-menu/parts/RovingFocus.d.ts +1 -1
  124. package/esm/overlays/floating-menu/parts/RovingFocus.js.map +1 -1
  125. package/esm/pagination/Pagination.d.ts +1 -6
  126. package/esm/pagination/Pagination.js.map +1 -1
  127. package/esm/provider/i18n/LanguageProvider.d.ts +3 -3
  128. package/esm/stepper/context.d.ts +1 -1
  129. package/esm/table/Body.d.ts +2 -4
  130. package/esm/table/Body.js.map +1 -1
  131. package/esm/table/ColumnHeader.d.ts +1 -2
  132. package/esm/table/ColumnHeader.js.map +1 -1
  133. package/esm/table/ExpandableRow.d.ts +1 -2
  134. package/esm/table/ExpandableRow.js.map +1 -1
  135. package/esm/table/Header.d.ts +2 -4
  136. package/esm/table/Header.js.map +1 -1
  137. package/esm/table/HeaderCell.d.ts +1 -2
  138. package/esm/table/HeaderCell.js.map +1 -1
  139. package/esm/table/Row.d.ts +1 -2
  140. package/esm/table/Row.js.map +1 -1
  141. package/esm/tabs/Tabs.context.d.ts +1 -1
  142. package/esm/toggle-group/ToggleGroup.context.d.ts +1 -1
  143. package/esm/util/i18n/get.d.ts +2 -2
  144. package/esm/util/i18n/get.js.map +1 -1
  145. package/esm/util/i18n/i18n.context.d.ts +2 -3
  146. package/esm/util/i18n/i18n.context.js.map +1 -1
  147. package/esm/util/i18n/i18n.types.d.ts +5 -9
  148. package/esm/util/i18n/locales/en.d.ts +39 -0
  149. package/esm/util/i18n/locales/en.js +39 -0
  150. package/esm/util/i18n/locales/en.js.map +1 -0
  151. package/esm/util/i18n/locales/nb.d.ts +14 -0
  152. package/esm/util/i18n/locales/nb.js +14 -0
  153. package/esm/util/i18n/locales/nb.js.map +1 -1
  154. package/esm/util/i18n/locales/nn.d.ts +39 -0
  155. package/esm/util/i18n/locales/nn.js +39 -0
  156. package/esm/util/i18n/locales/nn.js.map +1 -0
  157. package/esm/util/requireReactElement.d.ts +2 -0
  158. package/esm/util/requireReactElement.js +15 -0
  159. package/esm/util/requireReactElement.js.map +1 -0
  160. package/esm/util/virtualfocus/Context.d.ts +1 -1
  161. package/esm/util/virtualfocus/parts/VirtualFocusContent.d.ts +1 -2
  162. package/esm/util/virtualfocus/parts/VirtualFocusContent.js.map +1 -1
  163. package/package.json +15 -7
  164. package/src/accordion/AccordionHeader.tsx +0 -1
  165. package/src/alert/Alert.tsx +11 -20
  166. package/src/chips/Removable.tsx +13 -9
  167. package/src/date/datepicker/DatePicker.tsx +2 -2
  168. package/src/date/monthpicker/MonthPicker.tsx +2 -2
  169. package/src/form/checkbox/Checkbox.test.tsx +2 -3
  170. package/src/form/confirmation-panel/ConfirmationPanel.test.tsx +1 -2
  171. package/src/form/radio/Radio.test.tsx +4 -5
  172. package/src/index.ts +1 -0
  173. package/src/layout/base/BasePrimitive.tsx +3 -0
  174. package/src/layout/box/Box.tsx +35 -36
  175. package/src/layout/grid/HGrid.tsx +26 -27
  176. package/src/layout/stack/Stack.tsx +53 -54
  177. package/src/modal/ModalHeader.tsx +6 -0
  178. package/src/modal/dialog-polyfill.ts +2 -2
  179. package/src/overlays/action-menu/ActionMenu.tsx +971 -0
  180. package/src/overlays/action-menu/index.ts +29 -0
  181. package/src/overlays/floating/Floating.tsx +6 -12
  182. package/src/overlays/floating/Floating.utils.ts +2 -5
  183. package/src/overlays/floating-menu/Menu.tsx +183 -332
  184. package/src/overlays/floating-menu/parts/RovingFocus.tsx +3 -3
  185. package/src/pagination/Pagination.tsx +4 -1
  186. package/src/pagination/steps.test.ts +15 -16
  187. package/src/provider/i18n/LanguageProvider.tsx +3 -3
  188. package/src/table/Body.tsx +4 -6
  189. package/src/table/ColumnHeader.tsx +3 -4
  190. package/src/table/ExpandableRow.tsx +3 -4
  191. package/src/table/Header.tsx +4 -6
  192. package/src/table/HeaderCell.tsx +3 -4
  193. package/src/table/Row.tsx +3 -4
  194. package/src/util/i18n/get.ts +3 -3
  195. package/src/util/i18n/i18n.context.ts +2 -3
  196. package/src/util/i18n/i18n.types.ts +7 -11
  197. package/src/util/i18n/locales/en.ts +40 -0
  198. package/src/util/i18n/locales/nb.ts +23 -1
  199. package/src/util/i18n/locales/nn.ts +40 -0
  200. package/src/util/i18n/locales.test.tsx +23 -0
  201. package/src/util/requireReactElement.ts +25 -0
  202. package/src/util/virtualfocus/parts/VirtualFocusContent.tsx +4 -2
  203. package/cjs/util/i18n/merge.d.ts +0 -2
  204. package/cjs/util/i18n/merge.js +0 -28
  205. package/cjs/util/i18n/merge.js.map +0 -1
  206. package/esm/util/i18n/merge.d.ts +0 -2
  207. package/esm/util/i18n/merge.js +0 -25
  208. package/esm/util/i18n/merge.js.map +0 -1
  209. package/src/util/i18n/merge.ts +0 -35
@@ -1,8 +1,6 @@
1
1
  import type { Middleware, Placement } from "@floating-ui/react-dom";
2
- declare const SIDE_OPTIONS: readonly ["top", "right", "bottom", "left"];
3
- declare const ALIGN_OPTIONS: readonly ["start", "center", "end"];
4
- type Side = (typeof SIDE_OPTIONS)[number];
5
- type Align = (typeof ALIGN_OPTIONS)[number];
2
+ type Side = "top" | "right" | "bottom" | "left";
3
+ type Align = "start" | "center" | "end";
6
4
  type Measurable = {
7
5
  getBoundingClientRect(): DOMRect;
8
6
  };
@@ -13,6 +11,6 @@ declare function transformOrigin(options: {
13
11
  arrowWidth: number;
14
12
  arrowHeight: number;
15
13
  }): Middleware;
16
- declare function getSideAndAlignFromPlacement(placement: Placement): readonly ["left" | "right" | "top" | "bottom", "center" | "start" | "end"];
14
+ declare function getSideAndAlignFromPlacement(placement: Placement): readonly [Side, Align];
17
15
  export { getSideAndAlignFromPlacement, transformOrigin };
18
16
  export type { Side, Align, Measurable };
@@ -1,5 +1,3 @@
1
- const SIDE_OPTIONS = ["top", "right", "bottom", "left"];
2
- const ALIGN_OPTIONS = ["start", "center", "end"];
3
1
  /**
4
2
  * `transformOrigin` is a custom middleware for floating-ui that calculates the transform origin of the floating-element.
5
3
  */
@@ -1 +1 @@
1
- {"version":3,"file":"Floating.utils.js","sourceRoot":"","sources":["../../../src/overlays/floating/Floating.utils.ts"],"names":[],"mappings":"AAEA,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAU,CAAC;AACjE,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAU,CAAC;AAM1D;;GAEG;AACH,SAAS,eAAe,CAAC,OAGxB;IACC,OAAO;QACL,IAAI,EAAE,iBAAiB;QACvB,OAAO;QACP,EAAE,CAAC,IAAI;;YACL,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;YAElD,MAAM,iBAAiB,GAAG,CAAA,MAAA,cAAc,CAAC,KAAK,0CAAE,YAAY,MAAK,CAAC,CAAC;YACnE,MAAM,aAAa,GAAG,iBAAiB,CAAC;YACxC,MAAM,UAAU,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;YAC1D,MAAM,WAAW,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC;YAE5D,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,GAAG,4BAA4B,CAAC,SAAS,CAAC,CAAC;YAC1E,MAAM,YAAY,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,CAC9D,WAAW,CACZ,CAAC;YAEF,MAAM,YAAY,GAAG,CAAC,MAAA,MAAA,cAAc,CAAC,KAAK,0CAAE,CAAC,mCAAI,CAAC,CAAC,GAAG,UAAU,GAAG,CAAC,CAAC;YACrE,MAAM,YAAY,GAAG,CAAC,MAAA,MAAA,cAAc,CAAC,KAAK,0CAAE,CAAC,mCAAI,CAAC,CAAC,GAAG,WAAW,GAAG,CAAC,CAAC;YAEtE,IAAI,CAAC,GAAG,EAAE,CAAC;YACX,IAAI,CAAC,GAAG,EAAE,CAAC;YAEX,IAAI,UAAU,KAAK,QAAQ,EAAE,CAAC;gBAC5B,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,IAAI,CAAC;gBACvD,CAAC,GAAG,GAAG,CAAC,WAAW,IAAI,CAAC;YAC1B,CAAC;iBAAM,IAAI,UAAU,KAAK,KAAK,EAAE,CAAC;gBAChC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,IAAI,CAAC;gBACvD,CAAC,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,WAAW,IAAI,CAAC;YACjD,CAAC;iBAAM,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;gBAClC,CAAC,GAAG,GAAG,CAAC,WAAW,IAAI,CAAC;gBACxB,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,IAAI,CAAC;YACzD,CAAC;iBAAM,IAAI,UAAU,KAAK,MAAM,EAAE,CAAC;gBACjC,CAAC,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,GAAG,WAAW,IAAI,CAAC;gBAC9C,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,IAAI,CAAC;YACzD,CAAC;YACD,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,4BAA4B,CAAC,SAAoB;IACxD,MAAM,CAAC,IAAI,EAAE,KAAK,GAAG,QAAQ,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACtD,OAAO,CAAC,IAAY,EAAE,KAAc,CAAU,CAAC;AACjD,CAAC;AAED,OAAO,EAAE,4BAA4B,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"Floating.utils.js","sourceRoot":"","sources":["../../../src/overlays/floating/Floating.utils.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,SAAS,eAAe,CAAC,OAGxB;IACC,OAAO;QACL,IAAI,EAAE,iBAAiB;QACvB,OAAO;QACP,EAAE,CAAC,IAAI;;YACL,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;YAElD,MAAM,iBAAiB,GAAG,CAAA,MAAA,cAAc,CAAC,KAAK,0CAAE,YAAY,MAAK,CAAC,CAAC;YACnE,MAAM,aAAa,GAAG,iBAAiB,CAAC;YACxC,MAAM,UAAU,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;YAC1D,MAAM,WAAW,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC;YAE5D,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,GAAG,4BAA4B,CAAC,SAAS,CAAC,CAAC;YAC1E,MAAM,YAAY,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,CAC9D,WAAW,CACZ,CAAC;YAEF,MAAM,YAAY,GAAG,CAAC,MAAA,MAAA,cAAc,CAAC,KAAK,0CAAE,CAAC,mCAAI,CAAC,CAAC,GAAG,UAAU,GAAG,CAAC,CAAC;YACrE,MAAM,YAAY,GAAG,CAAC,MAAA,MAAA,cAAc,CAAC,KAAK,0CAAE,CAAC,mCAAI,CAAC,CAAC,GAAG,WAAW,GAAG,CAAC,CAAC;YAEtE,IAAI,CAAC,GAAG,EAAE,CAAC;YACX,IAAI,CAAC,GAAG,EAAE,CAAC;YAEX,IAAI,UAAU,KAAK,QAAQ,EAAE,CAAC;gBAC5B,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,IAAI,CAAC;gBACvD,CAAC,GAAG,GAAG,CAAC,WAAW,IAAI,CAAC;YAC1B,CAAC;iBAAM,IAAI,UAAU,KAAK,KAAK,EAAE,CAAC;gBAChC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,IAAI,CAAC;gBACvD,CAAC,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,WAAW,IAAI,CAAC;YACjD,CAAC;iBAAM,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;gBAClC,CAAC,GAAG,GAAG,CAAC,WAAW,IAAI,CAAC;gBACxB,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,IAAI,CAAC;YACzD,CAAC;iBAAM,IAAI,UAAU,KAAK,MAAM,EAAE,CAAC;gBACjC,CAAC,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,GAAG,WAAW,IAAI,CAAC;gBAC9C,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,IAAI,CAAC;YACzD,CAAC;YACD,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,4BAA4B,CAAC,SAAoB;IACxD,MAAM,CAAC,IAAI,EAAE,KAAK,GAAG,QAAQ,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACtD,OAAO,CAAC,IAAY,EAAE,KAAc,CAAU,CAAC;AACjD,CAAC;AAED,OAAO,EAAE,4BAA4B,EAAE,eAAe,EAAE,CAAC"}
@@ -21,7 +21,7 @@ interface MenuComponent extends React.FC<MenuProps> {
21
21
  CheckboxItem: typeof MenuCheckboxItem;
22
22
  RadioGroup: typeof MenuRadioGroup;
23
23
  RadioItem: typeof MenuRadioItem;
24
- Separator: typeof MenuSeparator;
24
+ Divider: typeof MenuDivider;
25
25
  Sub: typeof MenuSub;
26
26
  SubTrigger: typeof MenuSubTrigger;
27
27
  SubContent: typeof MenuSubContent;
@@ -30,9 +30,8 @@ interface MenuComponent extends React.FC<MenuProps> {
30
30
  declare const Menu: MenuComponent;
31
31
  type MenuAnchorProps = React.ComponentPropsWithoutRef<typeof Floating.Anchor>;
32
32
  declare const MenuAnchor: React.ForwardRefExoticComponent<MenuAnchorProps & React.RefAttributes<HTMLDivElement>>;
33
- interface MenuContentProps extends MenuContentInternalTypeProps {
34
- }
35
- declare const MenuContent: React.ForwardRefExoticComponent<MenuContentProps & React.RefAttributes<HTMLDivElement>>;
33
+ type MenuContentProps = MenuContentInternalTypeProps;
34
+ declare const MenuContent: React.ForwardRefExoticComponent<MenuContentInternalTypeProps & React.RefAttributes<HTMLDivElement>>;
36
35
  type FocusScopeProps = React.ComponentPropsWithoutRef<typeof FocusScope>;
37
36
  type DismissableLayerProps = React.ComponentPropsWithoutRef<typeof DismissableLayer>;
38
37
  type MenuContentInternalPrivateProps = {
@@ -51,9 +50,9 @@ interface MenuContentInternalProps extends MenuContentInternalPrivateProps, Omit
51
50
  onPointerDownOutside?: DismissableLayerProps["onPointerDownOutside"];
52
51
  onFocusOutside?: DismissableLayerProps["onFocusOutside"];
53
52
  onInteractOutside?: DismissableLayerProps["onInteractOutside"];
53
+ safeZone?: DismissableLayerProps["safeZone"];
54
54
  }
55
- interface MenuContentInternalTypeProps extends Omit<MenuContentInternalProps, keyof MenuContentInternalPrivateProps> {
56
- }
55
+ type MenuContentInternalTypeProps = Omit<MenuContentInternalProps, keyof MenuContentInternalPrivateProps>;
57
56
  type MenuItemElement = MenuItemInternalElement;
58
57
  interface MenuItemProps extends Omit<MenuItemInternalProps, "onSelect"> {
59
58
  onSelect?: (event: Event) => void;
@@ -63,9 +62,8 @@ type MenuItemInternalElement = SlottedDivElementRef;
63
62
  interface MenuItemInternalProps extends SlottedDivProps {
64
63
  disabled?: boolean;
65
64
  }
66
- interface MenuGroupProps extends SlottedDivProps {
67
- }
68
- declare const MenuGroup: React.ForwardRefExoticComponent<MenuGroupProps & React.RefAttributes<HTMLDivElement>>;
65
+ type MenuGroupProps = SlottedDivProps;
66
+ declare const MenuGroup: React.ForwardRefExoticComponent<SlottedDivProps & React.RefAttributes<HTMLDivElement>>;
69
67
  type PortalProps = React.ComponentPropsWithoutRef<typeof Portal>;
70
68
  type MenuPortalProps = PortalProps & {
71
69
  children: React.ReactElement;
@@ -76,9 +74,8 @@ interface MenuRadioGroupProps extends MenuGroupProps {
76
74
  onValueChange?: (value: string) => void;
77
75
  }
78
76
  declare const MenuRadioGroup: React.ForwardRefExoticComponent<MenuRadioGroupProps & React.RefAttributes<HTMLDivElement>>;
79
- interface MenuItemIndicatorProps extends SlottedDivProps {
80
- }
81
- declare const MenuItemIndicator: React.ForwardRefExoticComponent<MenuItemIndicatorProps & React.RefAttributes<HTMLDivElement>>;
77
+ type MenuItemIndicatorProps = SlottedDivProps;
78
+ declare const MenuItemIndicator: React.ForwardRefExoticComponent<SlottedDivProps & React.RefAttributes<HTMLDivElement>>;
82
79
  interface MenuRadioItemProps extends MenuItemProps {
83
80
  value: string;
84
81
  }
@@ -88,19 +85,16 @@ interface MenuCheckboxItemProps extends MenuItemProps {
88
85
  onCheckedChange?: (checked: boolean) => void;
89
86
  }
90
87
  declare const MenuCheckboxItem: React.ForwardRefExoticComponent<MenuCheckboxItemProps & React.RefAttributes<HTMLDivElement>>;
91
- interface MenuSeparatorProps extends SlottedDivProps {
92
- }
93
- declare const MenuSeparator: React.ForwardRefExoticComponent<MenuSeparatorProps & React.RefAttributes<HTMLDivElement>>;
88
+ type MenuDividerProps = SlottedDivProps;
89
+ declare const MenuDivider: React.ForwardRefExoticComponent<SlottedDivProps & React.RefAttributes<HTMLDivElement>>;
94
90
  interface MenuSubProps {
95
91
  children?: React.ReactNode;
96
92
  open?: boolean;
97
93
  onOpenChange?: (open: boolean) => void;
98
94
  }
99
95
  declare const MenuSub: React.FC<MenuSubProps>;
100
- interface MenuSubTriggerProps extends MenuItemInternalProps {
101
- }
102
- declare const MenuSubTrigger: React.ForwardRefExoticComponent<MenuSubTriggerProps & React.RefAttributes<HTMLDivElement>>;
103
- interface MenuSubContentProps extends Omit<MenuContentInternalProps, keyof MenuContentInternalPrivateProps | "onCloseAutoFocus" | "onEntryFocus" | "side" | "align"> {
104
- }
96
+ type MenuSubTriggerProps = MenuItemInternalProps;
97
+ declare const MenuSubTrigger: React.ForwardRefExoticComponent<MenuItemInternalProps & React.RefAttributes<HTMLDivElement>>;
98
+ type MenuSubContentProps = Omit<MenuContentInternalProps, keyof MenuContentInternalPrivateProps | "onCloseAutoFocus" | "onEntryFocus" | "side" | "align">;
105
99
  declare const MenuSubContent: React.ForwardRefExoticComponent<MenuSubContentProps & React.RefAttributes<HTMLDivElement>>;
106
- export { Menu, MenuAnchor, MenuCheckboxItem, MenuContent, MenuGroup, MenuItem, MenuItemIndicator, MenuPortal, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuSub, MenuSubContent, MenuSubTrigger, type MenuAnchorProps, type MenuCheckboxItemProps, type MenuContentProps, type MenuGroupProps, type MenuItemElement, type MenuItemIndicatorProps, type MenuPortalProps, type MenuProps, type MenuRadioGroupProps, type MenuRadioItemProps, type MenuSeparatorProps, type MenuSubContentProps, type MenuSubProps, type MenuSubTriggerProps, };
100
+ export { Menu, MenuAnchor, MenuCheckboxItem, MenuContent, MenuDivider, MenuGroup, MenuItem, MenuItemIndicator, MenuPortal, MenuRadioGroup, MenuRadioItem, MenuSub, MenuSubContent, MenuSubTrigger, type MenuAnchorProps, type MenuCheckboxItemProps, type MenuContentProps, type MenuDividerProps, type MenuGroupProps, type MenuItemElement, type MenuItemIndicatorProps, type MenuPortalProps, type MenuProps, type MenuRadioGroupProps, type MenuRadioItemProps, type MenuSubContentProps, type MenuSubProps, type MenuSubTriggerProps, };
@@ -9,7 +9,7 @@ var __rest = (this && this.__rest) || function (s, e) {
9
9
  }
10
10
  return t;
11
11
  };
12
- import React, { forwardRef, useCallback, useEffect, useRef, useState, } from "react";
12
+ import React, { forwardRef, useEffect, useRef, useState } from "react";
13
13
  import ReactDOM from "react-dom";
14
14
  import { Portal } from "../../portal/index.js";
15
15
  import { composeEventHandlers } from "../../util/composeEventHandlers.js";
@@ -24,9 +24,6 @@ import { SlottedDivElement, } from "./parts/SlottedDivElement.js";
24
24
  /* -------------------------------------------------------------------------- */
25
25
  /* Constants */
26
26
  /* -------------------------------------------------------------------------- */
27
- const SELECTION_KEYS = ["Enter", " "];
28
- const SUB_OPEN_KEYS = [...SELECTION_KEYS, "ArrowRight"];
29
- const SUB_CLOSE_KEYS = ["ArrowLeft"];
30
27
  const FIRST_KEYS = ["ArrowDown", "PageUp", "Home"];
31
28
  const LAST_KEYS = ["ArrowUp", "PageDown", "End"];
32
29
  const FIRST_LAST_KEYS = [...FIRST_KEYS, ...LAST_KEYS];
@@ -84,10 +81,6 @@ const Menu = MenuRoot;
84
81
  const MenuAnchor = forwardRef((props, forwardedRef) => {
85
82
  return React.createElement(Floating.Anchor, Object.assign({}, props, { ref: forwardedRef }));
86
83
  });
87
- const [MenuContentProvider, useMenuContentContext] = createContext({
88
- providerName: "MenuContentProvider",
89
- hookName: "useMenuContentContext",
90
- });
91
84
  const MenuContent = React.forwardRef((props, ref) => {
92
85
  const descendants = useMenuDescendants();
93
86
  const rootContext = useMenuRootContext();
@@ -110,97 +103,56 @@ const MenuRootContentModal = forwardRef((props, ref) => {
110
103
  onFocusOutside: composeEventHandlers(props.onFocusOutside, (event) => event.preventDefault(), { checkForDefaultPrevented: false }), onDismiss: () => context.onOpenChange(false) })));
111
104
  });
112
105
  const MenuContentInternal = forwardRef((_a, forwardedRef) => {
113
- var { onOpenAutoFocus, onCloseAutoFocus, disableOutsidePointerEvents, onEntryFocus, onEscapeKeyDown, onPointerDownOutside, onFocusOutside, onInteractOutside, onDismiss } = _a, rest = __rest(_a, ["onOpenAutoFocus", "onCloseAutoFocus", "disableOutsidePointerEvents", "onEntryFocus", "onEscapeKeyDown", "onPointerDownOutside", "onFocusOutside", "onInteractOutside", "onDismiss"]);
106
+ var { onOpenAutoFocus, onCloseAutoFocus, disableOutsidePointerEvents, onEntryFocus, onEscapeKeyDown, onPointerDownOutside, onFocusOutside, onInteractOutside, onDismiss, safeZone } = _a, rest = __rest(_a, ["onOpenAutoFocus", "onCloseAutoFocus", "disableOutsidePointerEvents", "onEntryFocus", "onEscapeKeyDown", "onPointerDownOutside", "onFocusOutside", "onInteractOutside", "onDismiss", "safeZone"]);
114
107
  const descendants = useMenuDescendantsContext();
115
108
  const context = useMenuContext();
116
109
  const rootContext = useMenuRootContext();
117
110
  const contentRef = useRef(null);
118
111
  const composedRefs = useMergeRefs(forwardedRef, contentRef, context.onContentChange);
119
- const pointerGraceTimerRef = React.useRef(0);
120
- const pointerGraceIntentRef = React.useRef(null);
121
- const pointerDirRef = React.useRef("right");
122
- const lastPointerXRef = React.useRef(0);
123
- const isPointerMovingToSubmenu = React.useCallback((event) => {
124
- var _a, _b;
125
- const isMovingTowards = pointerDirRef.current === ((_a = pointerGraceIntentRef.current) === null || _a === void 0 ? void 0 : _a.side);
126
- return (isMovingTowards &&
127
- isPointerInGraceArea(event, (_b = pointerGraceIntentRef.current) === null || _b === void 0 ? void 0 : _b.area));
128
- }, []);
129
- return (React.createElement(MenuContentProvider, { onItemEnter: React.useCallback((event) => {
130
- if (isPointerMovingToSubmenu(event))
131
- event.preventDefault();
132
- }, [isPointerMovingToSubmenu]), onItemLeave: React.useCallback((event) => {
112
+ return (React.createElement(FocusScope, { onMountHandler: composeEventHandlers(onOpenAutoFocus, (event) => {
133
113
  var _a;
134
- if (isPointerMovingToSubmenu(event))
135
- return;
136
- /**
137
- * Resets focus from current active item to content area
138
- * This is to prevent focus from being stuck on an item when we move pointer outside the menu or onto a disabled item
139
- */
140
- (_a = contentRef.current) === null || _a === void 0 ? void 0 : _a.focus();
141
- }, [isPointerMovingToSubmenu]), onPointerLeaveTrigger: React.useCallback((event) => {
142
- if (isPointerMovingToSubmenu(event))
143
- event.preventDefault();
144
- }, [isPointerMovingToSubmenu]), pointerGraceTimerRef: pointerGraceTimerRef, onPointerGraceIntentChange: React.useCallback((intent) => {
145
- pointerGraceIntentRef.current = intent;
146
- }, []) },
147
- React.createElement(FocusScope, { onMountHandler: composeEventHandlers(onOpenAutoFocus, (event) => {
148
- var _a;
149
- // when opening, explicitly focus the content area only and leave
150
- // `onEntryFocus` in control of focusing first item
151
- event.preventDefault();
152
- (_a = contentRef.current) === null || _a === void 0 ? void 0 : _a.focus({ preventScroll: true });
153
- }), onUnmountHandler: onCloseAutoFocus },
154
- React.createElement(DismissableLayer, { asChild: true, disableOutsidePointerEvents: disableOutsidePointerEvents, onEscapeKeyDown: onEscapeKeyDown, onPointerDownOutside: onPointerDownOutside, onFocusOutside: onFocusOutside, onInteractOutside: onInteractOutside, onDismiss: onDismiss },
155
- React.createElement(RovingFocus, { asChild: true, descendants: descendants, onEntryFocus: composeEventHandlers(onEntryFocus, (event) => {
156
- // only focus first item when using keyboard
157
- if (!rootContext.isUsingKeyboardRef.current)
158
- event.preventDefault();
159
- }) },
160
- React.createElement(Floating.Content, Object.assign({ role: "menu", "aria-orientation": "vertical", "data-state": getOpenState(context.open), "data-aksel-menu-content": "", dir: "ltr" }, rest, { ref: composedRefs, style: Object.assign({ outline: "none" }, rest.style), onKeyDown: composeEventHandlers(rest.onKeyDown, (event) => {
161
- var _a, _b, _c, _d;
162
- // submenu key events bubble through portals. We only care about keys in this menu.
163
- const target = event.target;
164
- const isKeyDownInside = target.closest("[data-aksel-menu-content]") ===
165
- event.currentTarget;
166
- if (isKeyDownInside) {
167
- // menus should not be navigated using tab key so we prevent it
168
- if (event.key === "Tab")
169
- event.preventDefault();
170
- }
171
- // focus first/last item based on key pressed
172
- const content = contentRef.current;
173
- if (event.target !== content)
174
- return;
175
- if (!FIRST_LAST_KEYS.includes(event.key))
176
- return;
177
- event.preventDefault();
178
- if (LAST_KEYS.includes(event.key)) {
179
- (_b = (_a = descendants.lastEnabled()) === null || _a === void 0 ? void 0 : _a.node) === null || _b === void 0 ? void 0 : _b.focus();
180
- return;
181
- }
182
- (_d = (_c = descendants.firstEnabled()) === null || _c === void 0 ? void 0 : _c.node) === null || _d === void 0 ? void 0 : _d.focus();
183
- }), onPointerMove: composeEventHandlers(rest.onPointerMove, whenMouse((event) => {
184
- const target = event.target;
185
- const pointerXHasChanged = lastPointerXRef.current !== event.clientX;
186
- // We don't use `event.movementX` for this check because Safari will
187
- // always return `0` on a pointer event.
188
- if (event.currentTarget.contains(target) &&
189
- pointerXHasChanged) {
190
- const newDir = event.clientX > lastPointerXRef.current
191
- ? "right"
192
- : "left";
193
- pointerDirRef.current = newDir;
194
- lastPointerXRef.current = event.clientX;
195
- }
196
- })) })))))));
114
+ // when opening, explicitly focus the content area only and leave
115
+ // `onEntryFocus` in control of focusing first item
116
+ event.preventDefault();
117
+ (_a = contentRef.current) === null || _a === void 0 ? void 0 : _a.focus({ preventScroll: true });
118
+ }), onUnmountHandler: onCloseAutoFocus },
119
+ React.createElement(DismissableLayer, { asChild: true, disableOutsidePointerEvents: disableOutsidePointerEvents, onEscapeKeyDown: onEscapeKeyDown, onPointerDownOutside: onPointerDownOutside, onFocusOutside: onFocusOutside, onInteractOutside: onInteractOutside, onDismiss: onDismiss, safeZone: safeZone },
120
+ React.createElement(RovingFocus, { asChild: true, descendants: descendants, onEntryFocus: composeEventHandlers(onEntryFocus, (event) => {
121
+ // only focus first item when using keyboard
122
+ if (!rootContext.isUsingKeyboardRef.current)
123
+ event.preventDefault();
124
+ }) },
125
+ React.createElement(Floating.Content, Object.assign({ role: "menu", "aria-orientation": "vertical", "data-state": getOpenState(context.open), "data-aksel-menu-content": "", dir: "ltr" }, rest, { ref: composedRefs, style: Object.assign({ outline: "none" }, rest.style), onKeyDown: composeEventHandlers(rest.onKeyDown, (event) => {
126
+ var _a, _b, _c, _d;
127
+ // submenu key events bubble through portals. We only care about keys in this menu.
128
+ const target = event.target;
129
+ const isKeyDownInside = target.closest("[data-aksel-menu-content]") ===
130
+ event.currentTarget;
131
+ if (isKeyDownInside) {
132
+ // menus should not be navigated using tab key so we prevent it
133
+ if (event.key === "Tab")
134
+ event.preventDefault();
135
+ }
136
+ // focus first/last item based on key pressed
137
+ const content = contentRef.current;
138
+ if (event.target !== content)
139
+ return;
140
+ if (!FIRST_LAST_KEYS.includes(event.key))
141
+ return;
142
+ event.preventDefault();
143
+ if (LAST_KEYS.includes(event.key)) {
144
+ (_b = (_a = descendants.lastEnabled()) === null || _a === void 0 ? void 0 : _a.node) === null || _b === void 0 ? void 0 : _b.focus();
145
+ return;
146
+ }
147
+ (_d = (_c = descendants.firstEnabled()) === null || _c === void 0 ? void 0 : _c.node) === null || _d === void 0 ? void 0 : _d.focus();
148
+ }) }))))));
197
149
  });
198
150
  /* -------------------------------------------------------------------------- */
199
151
  /* Menu item */
200
152
  /* -------------------------------------------------------------------------- */
201
153
  const ITEM_SELECT_EVENT = "menu.itemSelect";
202
154
  const MenuItem = forwardRef((_a, forwardedRef) => {
203
- var { disabled = false, onSelect, onClick, onPointerUp, onPointerDown, onKeyDown } = _a, rest = __rest(_a, ["disabled", "onSelect", "onClick", "onPointerUp", "onPointerDown", "onKeyDown"]);
155
+ var { disabled = false, onSelect, onClick, onPointerUp, onPointerDown, onKeyDown, onKeyUp } = _a, rest = __rest(_a, ["disabled", "onSelect", "onClick", "onPointerUp", "onPointerDown", "onKeyDown", "onKeyUp"]);
204
156
  const ref = useRef(null);
205
157
  const rootContext = useMenuRootContext();
206
158
  const composedRefs = useMergeRefs(forwardedRef, ref);
@@ -225,8 +177,32 @@ const MenuItem = forwardRef((_a, forwardedRef) => {
225
177
  rootContext.onClose();
226
178
  }
227
179
  }
180
+ else if (!disabled && menuItem) {
181
+ rootContext.onClose();
182
+ }
183
+ };
184
+ const handleKey = (event, key) => {
185
+ if (disabled || event.repeat) {
186
+ return;
187
+ }
188
+ if (key === event.key) {
189
+ event.currentTarget.click();
190
+ /**
191
+ * We prevent default browser behaviour for selection keys as they should only trigger
192
+ * selection.
193
+ * - Prevents space from scrolling the page.
194
+ * - If keydown causes focus to move, prevents keydown from firing on the new target.
195
+ */
196
+ event.preventDefault();
197
+ }
228
198
  };
229
- return (React.createElement(MenuItemInternal, Object.assign({}, rest, { tabIndex: disabled ? -1 : 0, ref: composedRefs, disabled: disabled, onClick: composeEventHandlers(onClick, handleSelect), onPointerDown: composeEventHandlers(onPointerDown, () => {
199
+ return (React.createElement(MenuItemInternal, Object.assign({}, rest, { tabIndex: disabled ? -1 : 0, ref: composedRefs, disabled: disabled, onClick: composeEventHandlers(onClick, handleSelect, {
200
+ /**
201
+ * Nextjs prevents default on click when using Link component, so we have to force click-event
202
+ * https://github.com/vercel/next.js/blob/77dcd4c66a35d0e8ef639bda4d05873bd3c0f52d/packages/next/src/client/link.tsx#L211
203
+ */
204
+ checkForDefaultPrevented: false,
205
+ }), onPointerDown: composeEventHandlers(onPointerDown, () => {
230
206
  isPointerDownRef.current = true;
231
207
  }, { checkForDefaultPrevented: false }), onPointerUp: composeEventHandlers(onPointerUp, (event) => {
232
208
  var _a;
@@ -235,26 +211,19 @@ const MenuItem = forwardRef((_a, forwardedRef) => {
235
211
  // prevent Firefox from getting stuck in text selection mode when the menu closes.
236
212
  if (!isPointerDownRef.current)
237
213
  (_a = event.currentTarget) === null || _a === void 0 ? void 0 : _a.click();
238
- }), onKeyDown: composeEventHandlers(onKeyDown, (event) => {
239
- if (disabled) {
240
- return;
241
- }
242
- if (SELECTION_KEYS.includes(event.key)) {
243
- event.currentTarget.click();
244
- /**
245
- * We prevent default browser behaviour for selection keys as they should only trigger
246
- * selection.
247
- * - Prevents space from scrolling the page.
248
- * - If keydown causes focus to move, prevents keydown from firing on the new target.
249
- */
250
- event.preventDefault();
251
- }
252
- }) })));
214
+ }), onKeyDown: composeEventHandlers(onKeyDown, (event) => handleKey(event, "Enter")), onKeyUp: composeEventHandlers(onKeyUp, (event) => handleKey(event, " ")) })));
253
215
  });
254
216
  const MenuItemInternal = forwardRef((_a, forwardedRef) => {
255
217
  var { disabled = false, onPointerMove, onPointerLeave } = _a, rest = __rest(_a, ["disabled", "onPointerMove", "onPointerLeave"]);
256
- const { register } = useMenuDescendant({ disabled });
257
- const contentContext = useMenuContentContext();
218
+ const context = useMenuContext();
219
+ const { register } = useMenuDescendant({
220
+ disabled,
221
+ closeMenu: () => {
222
+ rest["data-submenu-trigger"] &&
223
+ context.open &&
224
+ context.onOpenChange(false);
225
+ },
226
+ });
258
227
  const ref = useRef(null);
259
228
  const composedRefs = useMergeRefs(forwardedRef, ref, register);
260
229
  return (React.createElement(SlottedDivElement, Object.assign({ role: "menuitem", "aria-disabled": disabled || undefined, "data-disabled": disabled ? "" : undefined, tabIndex: -1 }, rest, { style: Object.assign({ userSelect: "none" }, rest === null || rest === void 0 ? void 0 : rest.style), ref: composedRefs,
@@ -264,20 +233,18 @@ const MenuItemInternal = forwardRef((_a, forwardedRef) => {
264
233
  * This is mostly to handle edgecases where the user uses mouse and keyboard together.
265
234
  */
266
235
  onPointerMove: composeEventHandlers(onPointerMove, whenMouse((event) => {
236
+ var _a;
267
237
  if (disabled) {
268
238
  /**
269
239
  * In the edgecase the focus is still stuck on a previous item, we make sure to reset it
270
240
  * even when the disabled item can't be focused itself to reset it.
271
241
  */
272
- contentContext.onItemLeave(event);
242
+ (_a = context.content) === null || _a === void 0 ? void 0 : _a.focus();
273
243
  }
274
244
  else {
275
- contentContext.onItemEnter(event);
276
- if (!event.defaultPrevented) {
277
- event.currentTarget.focus();
278
- }
245
+ event.currentTarget.focus();
279
246
  }
280
- })), onPointerLeave: composeEventHandlers(onPointerLeave, whenMouse(contentContext.onItemLeave)) })));
247
+ })), onPointerLeave: composeEventHandlers(onPointerLeave, whenMouse(() => { var _a; return (_a = context.content) === null || _a === void 0 ? void 0 : _a.focus(); })) })));
281
248
  });
282
249
  const MenuGroup = forwardRef((props, ref) => {
283
250
  return React.createElement(SlottedDivElement, Object.assign({ role: "group" }, props, { ref: ref }));
@@ -330,7 +297,7 @@ const MenuCheckboxItem = forwardRef((_a, forwardedRef) => {
330
297
  return (React.createElement(MenuItemIndicatorProvider, { state: checked },
331
298
  React.createElement(MenuItem, Object.assign({ role: "menuitemcheckbox", "aria-checked": isIndeterminate(checked) ? "mixed" : checked }, rest, { ref: forwardedRef, "data-state": getCheckedState(checked), onSelect: composeEventHandlers(onSelect, () => onCheckedChange === null || onCheckedChange === void 0 ? void 0 : onCheckedChange(isIndeterminate(checked) ? true : !checked), { checkForDefaultPrevented: false }) }))));
332
299
  });
333
- const MenuSeparator = forwardRef((props, ref) => {
300
+ const MenuDivider = forwardRef((props, ref) => {
334
301
  return (React.createElement(SlottedDivElement, Object.assign({ role: "separator", "aria-orientation": "horizontal" }, props, { ref: ref })));
335
302
  });
336
303
  const [MenuSubProvider, useMenuSubContext] = createContext({
@@ -339,6 +306,7 @@ const [MenuSubProvider, useMenuSubContext] = createContext({
339
306
  });
340
307
  const MenuSub = ({ children, onOpenChange, open = false, }) => {
341
308
  const parentMenuContext = useMenuContext();
309
+ const { values } = useMenuDescendantsContext();
342
310
  const [trigger, setTrigger] = useState(null);
343
311
  const [content, setContent] = useState(null);
344
312
  const handleOpenChange = useCallbackRef(onOpenChange);
@@ -350,100 +318,51 @@ const MenuSub = ({ children, onOpenChange, open = false, }) => {
350
318
  return () => handleOpenChange(false);
351
319
  }, [parentMenuContext.open, handleOpenChange]);
352
320
  return (React.createElement(Floating, null,
353
- React.createElement(MenuProvider, { open: open, onOpenChange: handleOpenChange, content: content, onContentChange: setContent },
321
+ React.createElement(MenuProvider, { open: open, onOpenChange: (_open) => {
322
+ handleOpenChange(_open);
323
+ if (_open) {
324
+ /* Makes sure to close all adjacent submenus if they are open */
325
+ values().forEach((descendant) => {
326
+ if (descendant.node !== trigger) {
327
+ descendant.closeMenu();
328
+ }
329
+ });
330
+ }
331
+ }, content: content, onContentChange: setContent },
354
332
  React.createElement(MenuSubProvider, { contentId: useId(), triggerId: useId(), trigger: trigger, onTriggerChange: setTrigger }, children))));
355
333
  };
356
334
  const MenuSubTrigger = forwardRef((props, forwardedRef) => {
357
335
  const context = useMenuContext();
358
336
  const subContext = useMenuSubContext();
359
- const contentContext = useMenuContentContext();
360
- const openTimerRef = useRef(null);
361
- const { pointerGraceTimerRef, onPointerGraceIntentChange } = contentContext;
362
337
  const composedRefs = useMergeRefs(forwardedRef, subContext.onTriggerChange);
363
- const clearOpenTimer = useCallback(() => {
364
- if (openTimerRef.current) {
365
- window.clearTimeout(openTimerRef.current);
338
+ const handleKey = (event, keys) => {
339
+ var _a;
340
+ if (props.disabled) {
341
+ return;
366
342
  }
367
- openTimerRef.current = null;
368
- }, []);
369
- React.useEffect(() => clearOpenTimer, [clearOpenTimer]);
370
- React.useEffect(() => {
371
- const pointerGraceTimer = pointerGraceTimerRef.current;
372
- return () => {
373
- window.clearTimeout(pointerGraceTimer);
374
- onPointerGraceIntentChange(null);
375
- };
376
- }, [pointerGraceTimerRef, onPointerGraceIntentChange]);
343
+ if (keys.includes(event.key)) {
344
+ context.onOpenChange(true);
345
+ // The trigger may hold focus if opened via pointer interaction
346
+ // so we ensure content is given focus again when switching to keyboard.
347
+ (_a = context.content) === null || _a === void 0 ? void 0 : _a.focus();
348
+ // prevent window from scrolling
349
+ event.preventDefault();
350
+ }
351
+ };
377
352
  return (React.createElement(MenuAnchor, { asChild: true },
378
- React.createElement(MenuItemInternal, Object.assign({ id: subContext.triggerId, "aria-haspopup": "menu", "aria-expanded": context.open, "aria-controls": subContext.contentId, "data-state": getOpenState(context.open) }, props, { ref: composedRefs,
379
- /**
380
- * onClick is added to solve edgecase where the user clicks the trigger,
381
- * but the focus is outside browser-window or viewport at first.
382
- */
383
- onClick: (event) => {
384
- var _a;
385
- (_a = props.onClick) === null || _a === void 0 ? void 0 : _a.call(props, event);
386
- if (props.disabled || event.defaultPrevented)
387
- return;
388
- event.currentTarget.focus();
389
- if (!context.open)
390
- context.onOpenChange(true);
391
- }, onPointerMove: composeEventHandlers(props.onPointerMove, whenMouse((event) => {
392
- if (event.defaultPrevented)
393
- return;
394
- if (!props.disabled && !context.open && !openTimerRef.current) {
395
- contentContext.onPointerGraceIntentChange(null);
396
- openTimerRef.current = window.setTimeout(() => {
397
- context.onOpenChange(true);
398
- clearOpenTimer();
399
- }, 100);
400
- }
401
- })), onPointerLeave: composeEventHandlers(props.onPointerLeave, whenMouse((event) => {
402
- var _a, _b;
403
- clearOpenTimer();
404
- const contentRect = (_a = context.content) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
405
- if (contentRect) {
406
- const side = (_b = context.content) === null || _b === void 0 ? void 0 : _b.dataset.side;
407
- const rightSide = side === "right";
408
- const bleed = rightSide ? -5 : +5;
409
- const contentNearEdge = contentRect[rightSide ? "left" : "right"];
410
- const contentFarEdge = contentRect[rightSide ? "right" : "left"];
411
- contentContext.onPointerGraceIntentChange({
412
- area: [
413
- // Apply a bleed on clientX to ensure that our exit point is
414
- // consistently within polygon bounds
415
- { x: event.clientX + bleed, y: event.clientY },
416
- { x: contentNearEdge, y: contentRect.top },
417
- { x: contentFarEdge, y: contentRect.top },
418
- { x: contentFarEdge, y: contentRect.bottom },
419
- { x: contentNearEdge, y: contentRect.bottom },
420
- ],
421
- side,
422
- });
423
- window.clearTimeout(pointerGraceTimerRef.current);
424
- pointerGraceTimerRef.current = window.setTimeout(() => contentContext.onPointerGraceIntentChange(null), 300);
425
- }
426
- else {
427
- contentContext.onPointerLeaveTrigger(event);
428
- if (event.defaultPrevented)
429
- return;
430
- // There's 100ms where the user may leave an item before the submenu was opened.
431
- contentContext.onPointerGraceIntentChange(null);
432
- }
433
- })), onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
353
+ React.createElement(MenuItemInternal, Object.assign({ id: subContext.triggerId, "aria-haspopup": "menu", "aria-expanded": context.open, "aria-controls": subContext.contentId, "data-state": getOpenState(context.open) }, props, { ref: composedRefs, "data-submenu-trigger": true, onClick: (event) => {
434
354
  var _a;
435
- if (props.disabled) {
355
+ if (props.disabled || event.defaultPrevented) {
436
356
  return;
437
357
  }
438
- if (SUB_OPEN_KEYS.includes(event.key)) {
439
- context.onOpenChange(true);
440
- // The trigger may hold focus if opened via pointer interaction
441
- // so we ensure content is given focus again when switching to keyboard.
442
- (_a = context.content) === null || _a === void 0 ? void 0 : _a.focus();
443
- // prevent window from scrolling
444
- event.preventDefault();
445
- }
446
- }) }))));
358
+ (_a = props.onClick) === null || _a === void 0 ? void 0 : _a.call(props, event);
359
+ /*
360
+ * Solves edgecase where the user clicks the trigger,
361
+ * but the focus is outside browser-window or viewport at first.
362
+ */
363
+ event.currentTarget.focus();
364
+ context.onOpenChange(!context.open);
365
+ }, onKeyDown: composeEventHandlers(props.onKeyDown, (event) => handleKey(event, ["Enter", "ArrowRight"])), onKeyUp: composeEventHandlers(props.onKeyUp, (event) => handleKey(event, [" "])) }))));
447
366
  });
448
367
  const MenuSubContent = forwardRef((props, forwardedRef) => {
449
368
  const descendants = useMenuDescendants();
@@ -461,14 +380,8 @@ const MenuSubContent = forwardRef((props, forwardedRef) => {
461
380
  }
462
381
  event.preventDefault();
463
382
  },
464
- // The menu might close because of focusing another menu item in the parent menu. We
465
- // don't want it to refocus the trigger in that case so we handle trigger focus ourselves.
466
- onCloseAutoFocus: (event) => event.preventDefault(), onFocusOutside: composeEventHandlers(props.onFocusOutside, (event) => {
467
- // We prevent closing when the trigger is focused to avoid triggering a re-open animation
468
- // on pointer interaction.
469
- if (event.target !== subContext.trigger)
470
- context.onOpenChange(false);
471
- }), onEscapeKeyDown: composeEventHandlers(props.onEscapeKeyDown, (event) => {
383
+ /* Since we manually focus Subtrigger, we prevent use of auto-focus */
384
+ onCloseAutoFocus: (event) => event.preventDefault(), onEscapeKeyDown: composeEventHandlers(props.onEscapeKeyDown, (event) => {
472
385
  rootContext.onClose();
473
386
  // Ensure pressing escape in submenu doesn't escape full screen mode
474
387
  event.preventDefault();
@@ -476,7 +389,7 @@ const MenuSubContent = forwardRef((props, forwardedRef) => {
476
389
  var _a, _b;
477
390
  // Submenu key events bubble through portals. We only care about keys in this menu.
478
391
  const isKeyDownInside = event.currentTarget.contains(event.target);
479
- let isCloseKey = SUB_CLOSE_KEYS.includes(event.key);
392
+ let isCloseKey = event.key === "ArrowLeft";
480
393
  /* When submenu opens to the left, we allow closing it with ArrowRight */
481
394
  if (((_a = context.content) === null || _a === void 0 ? void 0 : _a.dataset.side) === "left") {
482
395
  isCloseKey = isCloseKey || event.key === "ArrowRight";
@@ -506,30 +419,6 @@ function getCheckedState(checked) {
506
419
  ? "checked"
507
420
  : "unchecked";
508
421
  }
509
- /**
510
- * Determine if a point is inside of a polygon.
511
- */
512
- function isPointInPolygon(point, polygon) {
513
- const { x, y } = point;
514
- let inside = false;
515
- for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
516
- const xi = polygon[i].x;
517
- const yi = polygon[i].y;
518
- const xj = polygon[j].x;
519
- const yj = polygon[j].y;
520
- // prettier-ignore
521
- const intersect = ((yi > y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
522
- if (intersect)
523
- inside = !inside;
524
- }
525
- return inside;
526
- }
527
- function isPointerInGraceArea(event, area) {
528
- if (!area)
529
- return false;
530
- const cursorPos = { x: event.clientX, y: event.clientY };
531
- return isPointInPolygon(cursorPos, area);
532
- }
533
422
  function whenMouse(handler) {
534
423
  return (event) => event.pointerType === "mouse" ? handler(event) : undefined;
535
424
  }
@@ -542,10 +431,10 @@ Menu.Item = MenuItem;
542
431
  Menu.CheckboxItem = MenuCheckboxItem;
543
432
  Menu.RadioGroup = MenuRadioGroup;
544
433
  Menu.RadioItem = MenuRadioItem;
545
- Menu.Separator = MenuSeparator;
434
+ Menu.Divider = MenuDivider;
546
435
  Menu.Sub = MenuSub;
547
436
  Menu.SubTrigger = MenuSubTrigger;
548
437
  Menu.SubContent = MenuSubContent;
549
438
  Menu.ItemIndicator = MenuItemIndicator;
550
- export { Menu, MenuAnchor, MenuCheckboxItem, MenuContent, MenuGroup, MenuItem, MenuItemIndicator, MenuPortal, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuSub, MenuSubContent, MenuSubTrigger, };
439
+ export { Menu, MenuAnchor, MenuCheckboxItem, MenuContent, MenuDivider, MenuGroup, MenuItem, MenuItemIndicator, MenuPortal, MenuRadioGroup, MenuRadioItem, MenuSub, MenuSubContent, MenuSubTrigger, };
551
440
  //# sourceMappingURL=Menu.js.map