react-aria 3.49.0 → 3.50.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 (244) hide show
  1. package/dist/private/autocomplete/useAutocomplete.cjs +16 -7
  2. package/dist/private/autocomplete/useAutocomplete.cjs.map +1 -1
  3. package/dist/private/autocomplete/useAutocomplete.js +16 -7
  4. package/dist/private/autocomplete/useAutocomplete.js.map +1 -1
  5. package/dist/private/autocomplete/useAutocomplete.mjs +16 -7
  6. package/dist/private/autocomplete/useAutocomplete.mjs.map +1 -1
  7. package/dist/private/breadcrumbs/useBreadcrumbs.cjs.map +1 -1
  8. package/dist/private/breadcrumbs/useBreadcrumbs.js.map +1 -1
  9. package/dist/private/breadcrumbs/useBreadcrumbs.mjs.map +1 -1
  10. package/dist/private/calendar/useCalendarBase.cjs.map +1 -1
  11. package/dist/private/calendar/useCalendarBase.js.map +1 -1
  12. package/dist/private/calendar/useCalendarBase.mjs.map +1 -1
  13. package/dist/private/calendar/useCalendarCell.cjs.map +1 -1
  14. package/dist/private/calendar/useCalendarCell.js.map +1 -1
  15. package/dist/private/calendar/useCalendarCell.mjs.map +1 -1
  16. package/dist/private/calendar/useCalendarYearPicker.cjs +4 -4
  17. package/dist/private/calendar/useCalendarYearPicker.cjs.map +1 -1
  18. package/dist/private/calendar/useCalendarYearPicker.js +4 -4
  19. package/dist/private/calendar/useCalendarYearPicker.js.map +1 -1
  20. package/dist/private/calendar/useCalendarYearPicker.mjs +4 -4
  21. package/dist/private/calendar/useCalendarYearPicker.mjs.map +1 -1
  22. package/dist/private/calendar/utils.cjs.map +1 -1
  23. package/dist/private/calendar/utils.js.map +1 -1
  24. package/dist/private/calendar/utils.mjs.map +1 -1
  25. package/dist/private/color/useColorArea.cjs.map +1 -1
  26. package/dist/private/color/useColorArea.js.map +1 -1
  27. package/dist/private/color/useColorArea.mjs.map +1 -1
  28. package/dist/private/color/useColorSwatch.cjs.map +1 -1
  29. package/dist/private/color/useColorSwatch.js.map +1 -1
  30. package/dist/private/color/useColorSwatch.mjs.map +1 -1
  31. package/dist/private/combobox/useComboBox.cjs +2 -0
  32. package/dist/private/combobox/useComboBox.cjs.map +1 -1
  33. package/dist/private/combobox/useComboBox.js +2 -0
  34. package/dist/private/combobox/useComboBox.js.map +1 -1
  35. package/dist/private/combobox/useComboBox.mjs +2 -0
  36. package/dist/private/combobox/useComboBox.mjs.map +1 -1
  37. package/dist/private/datepicker/useDateField.cjs.map +1 -1
  38. package/dist/private/datepicker/useDateField.js.map +1 -1
  39. package/dist/private/datepicker/useDateField.mjs.map +1 -1
  40. package/dist/private/datepicker/useDatePicker.cjs.map +1 -1
  41. package/dist/private/datepicker/useDatePicker.js.map +1 -1
  42. package/dist/private/datepicker/useDatePicker.mjs.map +1 -1
  43. package/dist/private/datepicker/useDateRangePicker.cjs.map +1 -1
  44. package/dist/private/datepicker/useDateRangePicker.js.map +1 -1
  45. package/dist/private/datepicker/useDateRangePicker.mjs.map +1 -1
  46. package/dist/private/datepicker/useDisplayNames.cjs +1 -2
  47. package/dist/private/datepicker/useDisplayNames.cjs.map +1 -1
  48. package/dist/private/datepicker/useDisplayNames.js +1 -2
  49. package/dist/private/datepicker/useDisplayNames.js.map +1 -1
  50. package/dist/private/datepicker/useDisplayNames.mjs +1 -2
  51. package/dist/private/datepicker/useDisplayNames.mjs.map +1 -1
  52. package/dist/private/dnd/DragManager.cjs +4 -1
  53. package/dist/private/dnd/DragManager.cjs.map +1 -1
  54. package/dist/private/dnd/DragManager.js +4 -1
  55. package/dist/private/dnd/DragManager.js.map +1 -1
  56. package/dist/private/dnd/DragManager.mjs +4 -1
  57. package/dist/private/dnd/DragManager.mjs.map +1 -1
  58. package/dist/private/dnd/useDrag.cjs.map +1 -1
  59. package/dist/private/dnd/useDrag.js.map +1 -1
  60. package/dist/private/dnd/useDrag.mjs.map +1 -1
  61. package/dist/private/dnd/useDraggableItem.cjs.map +1 -1
  62. package/dist/private/dnd/useDraggableItem.js.map +1 -1
  63. package/dist/private/dnd/useDraggableItem.mjs.map +1 -1
  64. package/dist/private/dnd/useDropIndicator.cjs.map +1 -1
  65. package/dist/private/dnd/useDropIndicator.js.map +1 -1
  66. package/dist/private/dnd/useDropIndicator.mjs.map +1 -1
  67. package/dist/private/dnd/useVirtualDrop.cjs.map +1 -1
  68. package/dist/private/dnd/useVirtualDrop.js.map +1 -1
  69. package/dist/private/dnd/useVirtualDrop.mjs.map +1 -1
  70. package/dist/private/dnd/utils.cjs +13 -3
  71. package/dist/private/dnd/utils.cjs.map +1 -1
  72. package/dist/private/dnd/utils.js +13 -3
  73. package/dist/private/dnd/utils.js.map +1 -1
  74. package/dist/private/dnd/utils.mjs +13 -3
  75. package/dist/private/dnd/utils.mjs.map +1 -1
  76. package/dist/private/form/useFormValidation.cjs +1 -1
  77. package/dist/private/form/useFormValidation.cjs.map +1 -1
  78. package/dist/private/form/useFormValidation.js +1 -1
  79. package/dist/private/form/useFormValidation.js.map +1 -1
  80. package/dist/private/form/useFormValidation.mjs +1 -1
  81. package/dist/private/form/useFormValidation.mjs.map +1 -1
  82. package/dist/private/grid/useGridSelectionAnnouncement.cjs.map +1 -1
  83. package/dist/private/grid/useGridSelectionAnnouncement.js.map +1 -1
  84. package/dist/private/grid/useGridSelectionAnnouncement.mjs.map +1 -1
  85. package/dist/private/grid/useGridSelectionCheckbox.cjs.map +1 -1
  86. package/dist/private/grid/useGridSelectionCheckbox.js.map +1 -1
  87. package/dist/private/grid/useGridSelectionCheckbox.mjs.map +1 -1
  88. package/dist/private/grid/useHighlightSelectionDescription.cjs.map +1 -1
  89. package/dist/private/grid/useHighlightSelectionDescription.js.map +1 -1
  90. package/dist/private/grid/useHighlightSelectionDescription.mjs.map +1 -1
  91. package/dist/private/gridlist/useGridList.cjs +2 -1
  92. package/dist/private/gridlist/useGridList.cjs.map +1 -1
  93. package/dist/private/gridlist/useGridList.js +2 -1
  94. package/dist/private/gridlist/useGridList.js.map +1 -1
  95. package/dist/private/gridlist/useGridList.mjs +2 -1
  96. package/dist/private/gridlist/useGridList.mjs.map +1 -1
  97. package/dist/private/gridlist/useGridListItem.cjs +62 -21
  98. package/dist/private/gridlist/useGridListItem.cjs.map +1 -1
  99. package/dist/private/gridlist/useGridListItem.js +63 -22
  100. package/dist/private/gridlist/useGridListItem.js.map +1 -1
  101. package/dist/private/gridlist/useGridListItem.mjs +62 -21
  102. package/dist/private/gridlist/useGridListItem.mjs.map +1 -1
  103. package/dist/private/interactions/createEventHandler.cjs +3 -0
  104. package/dist/private/interactions/createEventHandler.cjs.map +1 -1
  105. package/dist/private/interactions/createEventHandler.js +3 -0
  106. package/dist/private/interactions/createEventHandler.js.map +1 -1
  107. package/dist/private/interactions/createEventHandler.mjs +3 -0
  108. package/dist/private/interactions/createEventHandler.mjs.map +1 -1
  109. package/dist/private/interactions/useFocusVisible.cjs +16 -5
  110. package/dist/private/interactions/useFocusVisible.cjs.map +1 -1
  111. package/dist/private/interactions/useFocusVisible.js +16 -5
  112. package/dist/private/interactions/useFocusVisible.js.map +1 -1
  113. package/dist/private/interactions/useFocusVisible.mjs +16 -5
  114. package/dist/private/interactions/useFocusVisible.mjs.map +1 -1
  115. package/dist/private/menu/useMenu.cjs.map +1 -1
  116. package/dist/private/menu/useMenu.js.map +1 -1
  117. package/dist/private/menu/useMenu.mjs.map +1 -1
  118. package/dist/private/menu/useMenuItem.cjs +1 -1
  119. package/dist/private/menu/useMenuItem.cjs.map +1 -1
  120. package/dist/private/menu/useMenuItem.js +1 -1
  121. package/dist/private/menu/useMenuItem.js.map +1 -1
  122. package/dist/private/menu/useMenuItem.mjs +1 -1
  123. package/dist/private/menu/useMenuItem.mjs.map +1 -1
  124. package/dist/private/menu/useMenuTrigger.cjs.map +1 -1
  125. package/dist/private/menu/useMenuTrigger.js.map +1 -1
  126. package/dist/private/menu/useMenuTrigger.mjs.map +1 -1
  127. package/dist/private/menu/utils.cjs.map +1 -1
  128. package/dist/private/menu/utils.js.map +1 -1
  129. package/dist/private/menu/utils.mjs.map +1 -1
  130. package/dist/private/numberfield/useNumberField.cjs.map +1 -1
  131. package/dist/private/numberfield/useNumberField.js.map +1 -1
  132. package/dist/private/numberfield/useNumberField.mjs.map +1 -1
  133. package/dist/private/overlays/DismissButton.cjs.map +1 -1
  134. package/dist/private/overlays/DismissButton.js.map +1 -1
  135. package/dist/private/overlays/DismissButton.mjs.map +1 -1
  136. package/dist/private/overlays/calculatePosition.cjs +7 -7
  137. package/dist/private/overlays/calculatePosition.cjs.map +1 -1
  138. package/dist/private/overlays/calculatePosition.js +7 -7
  139. package/dist/private/overlays/calculatePosition.js.map +1 -1
  140. package/dist/private/overlays/calculatePosition.mjs +7 -7
  141. package/dist/private/overlays/calculatePosition.mjs.map +1 -1
  142. package/dist/private/overlays/useOverlayPosition.cjs +3 -2
  143. package/dist/private/overlays/useOverlayPosition.cjs.map +1 -1
  144. package/dist/private/overlays/useOverlayPosition.js +3 -2
  145. package/dist/private/overlays/useOverlayPosition.js.map +1 -1
  146. package/dist/private/overlays/useOverlayPosition.mjs +3 -2
  147. package/dist/private/overlays/useOverlayPosition.mjs.map +1 -1
  148. package/dist/private/searchfield/useSearchField.cjs.map +1 -1
  149. package/dist/private/searchfield/useSearchField.js.map +1 -1
  150. package/dist/private/searchfield/useSearchField.mjs.map +1 -1
  151. package/dist/private/select/useSelect.cjs +1 -2
  152. package/dist/private/select/useSelect.cjs.map +1 -1
  153. package/dist/private/select/useSelect.js +1 -2
  154. package/dist/private/select/useSelect.js.map +1 -1
  155. package/dist/private/select/useSelect.mjs +1 -2
  156. package/dist/private/select/useSelect.mjs.map +1 -1
  157. package/dist/private/selection/ListKeyboardDelegate.cjs +31 -3
  158. package/dist/private/selection/ListKeyboardDelegate.cjs.map +1 -1
  159. package/dist/private/selection/ListKeyboardDelegate.js +31 -3
  160. package/dist/private/selection/ListKeyboardDelegate.js.map +1 -1
  161. package/dist/private/selection/ListKeyboardDelegate.mjs +31 -3
  162. package/dist/private/selection/ListKeyboardDelegate.mjs.map +1 -1
  163. package/dist/private/selection/useSelectableCollection.cjs +20 -14
  164. package/dist/private/selection/useSelectableCollection.cjs.map +1 -1
  165. package/dist/private/selection/useSelectableCollection.js +26 -19
  166. package/dist/private/selection/useSelectableCollection.js.map +1 -1
  167. package/dist/private/selection/useSelectableCollection.mjs +20 -14
  168. package/dist/private/selection/useSelectableCollection.mjs.map +1 -1
  169. package/dist/private/selection/useTypeSelect.cjs +50 -18
  170. package/dist/private/selection/useTypeSelect.cjs.map +1 -1
  171. package/dist/private/selection/useTypeSelect.js +51 -19
  172. package/dist/private/selection/useTypeSelect.js.map +1 -1
  173. package/dist/private/selection/useTypeSelect.mjs +51 -19
  174. package/dist/private/selection/useTypeSelect.mjs.map +1 -1
  175. package/dist/private/spinbutton/useSpinButton.cjs.map +1 -1
  176. package/dist/private/spinbutton/useSpinButton.js.map +1 -1
  177. package/dist/private/spinbutton/useSpinButton.mjs.map +1 -1
  178. package/dist/private/steplist/useStepList.cjs.map +1 -1
  179. package/dist/private/steplist/useStepList.js.map +1 -1
  180. package/dist/private/steplist/useStepList.mjs.map +1 -1
  181. package/dist/private/table/useTable.cjs.map +1 -1
  182. package/dist/private/table/useTable.js.map +1 -1
  183. package/dist/private/table/useTable.mjs.map +1 -1
  184. package/dist/private/table/useTableColumnHeader.cjs.map +1 -1
  185. package/dist/private/table/useTableColumnHeader.js.map +1 -1
  186. package/dist/private/table/useTableColumnHeader.mjs.map +1 -1
  187. package/dist/private/table/useTableColumnResize.cjs.map +1 -1
  188. package/dist/private/table/useTableColumnResize.js.map +1 -1
  189. package/dist/private/table/useTableColumnResize.mjs.map +1 -1
  190. package/dist/private/table/useTableRow.cjs.map +1 -1
  191. package/dist/private/table/useTableRow.js.map +1 -1
  192. package/dist/private/table/useTableRow.mjs.map +1 -1
  193. package/dist/private/table/useTableSelectionCheckbox.cjs.map +1 -1
  194. package/dist/private/table/useTableSelectionCheckbox.js.map +1 -1
  195. package/dist/private/table/useTableSelectionCheckbox.mjs.map +1 -1
  196. package/dist/private/tabs/TabsKeyboardDelegate.cjs +2 -2
  197. package/dist/private/tabs/TabsKeyboardDelegate.cjs.map +1 -1
  198. package/dist/private/tabs/TabsKeyboardDelegate.js +2 -2
  199. package/dist/private/tabs/TabsKeyboardDelegate.js.map +1 -1
  200. package/dist/private/tabs/TabsKeyboardDelegate.mjs +2 -2
  201. package/dist/private/tabs/TabsKeyboardDelegate.mjs.map +1 -1
  202. package/dist/private/tag/useTag.cjs.map +1 -1
  203. package/dist/private/tag/useTag.js.map +1 -1
  204. package/dist/private/tag/useTag.mjs.map +1 -1
  205. package/dist/private/toast/useToast.cjs.map +1 -1
  206. package/dist/private/toast/useToast.js.map +1 -1
  207. package/dist/private/toast/useToast.mjs.map +1 -1
  208. package/dist/private/toast/useToastRegion.cjs.map +1 -1
  209. package/dist/private/toast/useToastRegion.js.map +1 -1
  210. package/dist/private/toast/useToastRegion.mjs.map +1 -1
  211. package/dist/private/toolbar/useToolbar.cjs +0 -1
  212. package/dist/private/toolbar/useToolbar.cjs.map +1 -1
  213. package/dist/private/toolbar/useToolbar.js +0 -1
  214. package/dist/private/toolbar/useToolbar.js.map +1 -1
  215. package/dist/private/toolbar/useToolbar.mjs +0 -1
  216. package/dist/private/toolbar/useToolbar.mjs.map +1 -1
  217. package/dist/private/tree/useTree.cjs.map +1 -1
  218. package/dist/private/tree/useTree.js.map +1 -1
  219. package/dist/private/tree/useTree.mjs.map +1 -1
  220. package/dist/private/tree/useTreeItem.cjs.map +1 -1
  221. package/dist/private/tree/useTreeItem.js.map +1 -1
  222. package/dist/private/tree/useTreeItem.mjs.map +1 -1
  223. package/dist/private/utils/isElementVisible.cjs +1 -1
  224. package/dist/private/utils/isElementVisible.cjs.map +1 -1
  225. package/dist/private/utils/isElementVisible.js +1 -1
  226. package/dist/private/utils/isElementVisible.js.map +1 -1
  227. package/dist/private/utils/isElementVisible.mjs +1 -1
  228. package/dist/private/utils/isElementVisible.mjs.map +1 -1
  229. package/dist/private/utils/isFocusable.cjs +3 -1
  230. package/dist/private/utils/isFocusable.cjs.map +1 -1
  231. package/dist/private/utils/isFocusable.js +3 -1
  232. package/dist/private/utils/isFocusable.js.map +1 -1
  233. package/dist/private/utils/isFocusable.mjs +3 -1
  234. package/dist/private/utils/isFocusable.mjs.map +1 -1
  235. package/dist/types/src/dnd/utils.d.ts +2 -2
  236. package/dist/types/src/gridlist/useGridList.d.ts +7 -0
  237. package/dist/types/src/menu/useMenu.d.ts +1 -1
  238. package/dist/types/src/menu/utils.d.ts +1 -1
  239. package/dist/types/src/overlays/calculatePosition.d.ts +1 -0
  240. package/dist/types/src/overlays/useOverlayPosition.d.ts +8 -0
  241. package/dist/types/src/selection/ListKeyboardDelegate.d.ts +1 -0
  242. package/dist/types/src/selection/useSelectableCollection.d.ts +7 -0
  243. package/dist/types/src/tree/useTree.d.ts +1 -1
  244. package/package.json +4 -4
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/react-aria/src/overlays/calculatePosition.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Axis, Placement, PlacementAxis, SizeAxis} from './useOverlayPosition';\nimport {clamp} from 'react-stately/private/utils/number';\nimport {isWebKit} from '../utils/platform';\nimport {nodeContains} from '../utils/shadowdom/DOMFunctions';\n\ninterface Position {\n top?: number;\n left?: number;\n bottom?: number;\n right?: number;\n}\n\ninterface Dimensions {\n width: number;\n height: number;\n totalWidth: number;\n totalHeight: number;\n top: number;\n left: number;\n scroll: Position;\n}\n\ninterface ParsedPlacement {\n placement: PlacementAxis;\n crossPlacement: PlacementAxis;\n axis: Axis;\n crossAxis: Axis;\n size: SizeAxis;\n crossSize: SizeAxis;\n}\n\ninterface Offset {\n top: number;\n left: number;\n width: number;\n height: number;\n}\n\ninterface PositionOpts {\n arrowSize: number;\n placement: Placement;\n targetNode: Element;\n overlayNode: Element;\n scrollNode: Element;\n padding: number;\n shouldFlip: boolean;\n boundaryElement: Element;\n offset: number;\n crossOffset: number;\n maxHeight?: number;\n arrowBoundaryOffset?: number;\n}\n\ntype HeightGrowthDirection = 'top' | 'bottom';\n\nexport interface PositionResult {\n position: Position;\n arrowOffsetLeft?: number;\n arrowOffsetTop?: number;\n triggerAnchorPoint: {x: number; y: number};\n maxHeight: number;\n placement: PlacementAxis;\n}\n\nconst AXIS = {\n top: 'top',\n bottom: 'top',\n left: 'left',\n right: 'left'\n};\n\nconst FLIPPED_DIRECTION = {\n top: 'bottom',\n bottom: 'top',\n left: 'right',\n right: 'left'\n};\n\nconst CROSS_AXIS = {\n top: 'left',\n left: 'top'\n};\n\nconst AXIS_SIZE = {\n top: 'height',\n left: 'width'\n};\n\nconst TOTAL_SIZE = {\n width: 'totalWidth',\n height: 'totalHeight'\n};\n\nconst PARSED_PLACEMENT_CACHE = {};\n\nlet getVisualViewport = () => (typeof document !== 'undefined' ? window.visualViewport : null);\n\nfunction getContainerDimensions(\n containerNode: Element,\n visualViewport: VisualViewport | null\n): Dimensions {\n let width = 0,\n height = 0,\n totalWidth = 0,\n totalHeight = 0,\n top = 0,\n left = 0;\n let scroll: Position = {};\n let isPinchZoomedIn = (visualViewport?.scale ?? 1) > 1;\n\n // In the case where the container is `html` or `body` and the container doesn't have something like `position: relative`,\n // then position absolute will be positioned relative to the viewport, also known as the `initial containing block`.\n // That's why we use the visual viewport instead.\n\n if (containerNode.tagName === 'BODY' || containerNode.tagName === 'HTML') {\n let documentElement = document.documentElement;\n totalWidth = documentElement.clientWidth;\n totalHeight = documentElement.clientHeight;\n width = visualViewport?.width ?? totalWidth;\n height = visualViewport?.height ?? totalHeight;\n scroll.top = documentElement.scrollTop || containerNode.scrollTop;\n scroll.left = documentElement.scrollLeft || containerNode.scrollLeft;\n\n // The goal of the below is to get a top/left value that represents the top/left of the visual viewport with\n // respect to the layout viewport origin. This combined with the scrollTop/scrollLeft will allow us to calculate\n // coordinates/values with respect to the visual viewport or with respect to the layout viewport.\n if (visualViewport) {\n top = visualViewport.offsetTop;\n left = visualViewport.offsetLeft;\n }\n } else {\n ({width, height, top, left} = getOffset(containerNode, false));\n scroll.top = containerNode.scrollTop;\n scroll.left = containerNode.scrollLeft;\n totalWidth = width;\n totalHeight = height;\n }\n\n if (\n isWebKit() &&\n (containerNode.tagName === 'BODY' || containerNode.tagName === 'HTML') &&\n isPinchZoomedIn\n ) {\n // Safari will report a non-zero scrollTop/Left for the non-scrolling body/HTML element when pinch zoomed in unlike other browsers.\n // Set to zero for parity calculations so we get consistent positioning of overlays across all browsers.\n // Also switch to visualViewport.pageTop/pageLeft so that we still accomodate for scroll positioning for body/HTML elements that are actually scrollable\n // before pinch zoom happens\n scroll.top = 0;\n scroll.left = 0;\n top = visualViewport?.pageTop ?? 0;\n left = visualViewport?.pageLeft ?? 0;\n }\n\n return {width, height, totalWidth, totalHeight, scroll, top, left};\n}\n\nfunction getScroll(node: Element): Offset {\n return {\n top: node.scrollTop,\n left: node.scrollLeft,\n width: node.scrollWidth,\n height: node.scrollHeight\n };\n}\n\n// Determines the amount of space required when moving the overlay to ensure it remains in the boundary\nfunction getDelta(\n axis: Axis,\n offset: number,\n size: number,\n // The dimensions of the boundary element that the popover is\n // positioned within (most of the time this is the <body>).\n boundaryDimensions: Dimensions,\n // The dimensions of the containing block element that the popover is\n // positioned relative to (e.g. parent with position: relative).\n // Usually this is the same as the boundary element, but if the popover\n // is portaled somewhere other than the body and has an ancestor with\n // position: relative/absolute, it will be different.\n containerDimensions: Dimensions,\n padding: number,\n containerOffsetWithBoundary: Offset\n) {\n let containerScroll = containerDimensions.scroll[axis] ?? 0;\n // The height/width of the boundary. Matches the axis along which we are adjusting the overlay position\n let boundarySize = boundaryDimensions[AXIS_SIZE[axis]];\n // Calculate the edges of the boundary (accomodating for the boundary padding) and the edges of the overlay.\n // Note that these values are with respect to the visual viewport (aka 0,0 is the top left of the viewport)\n\n let boundaryStartEdge =\n containerOffsetWithBoundary[axis] + boundaryDimensions.scroll[AXIS[axis]] + padding;\n let boundaryEndEdge =\n containerOffsetWithBoundary[axis] +\n boundaryDimensions.scroll[AXIS[axis]] +\n boundarySize -\n padding;\n // transformed value of the left edge of the overlay\n let startEdgeOffset =\n offset -\n containerScroll +\n boundaryDimensions.scroll[AXIS[axis]] +\n containerOffsetWithBoundary[axis] -\n boundaryDimensions[AXIS[axis]];\n // transformed value of the right edge of the overlay\n let endEdgeOffset =\n offset -\n containerScroll +\n size +\n boundaryDimensions.scroll[AXIS[axis]] +\n containerOffsetWithBoundary[axis] -\n boundaryDimensions[AXIS[axis]];\n\n // If any of the overlay edges falls outside of the boundary, shift the overlay the required amount to align one of the overlay's\n // edges with the closest boundary edge.\n if (startEdgeOffset < boundaryStartEdge) {\n return boundaryStartEdge - startEdgeOffset;\n } else if (endEdgeOffset > boundaryEndEdge) {\n return Math.max(boundaryEndEdge - endEdgeOffset, boundaryStartEdge - startEdgeOffset);\n } else {\n return 0;\n }\n}\n\nfunction getMargins(node: Element): Position {\n let style = window.getComputedStyle(node);\n return {\n top: parseInt(style.marginTop, 10) || 0,\n bottom: parseInt(style.marginBottom, 10) || 0,\n left: parseInt(style.marginLeft, 10) || 0,\n right: parseInt(style.marginRight, 10) || 0\n };\n}\n\nfunction parsePlacement(input: Placement): ParsedPlacement {\n if (PARSED_PLACEMENT_CACHE[input]) {\n return PARSED_PLACEMENT_CACHE[input];\n }\n\n let [placement, crossPlacement] = input.split(' ');\n let axis: Axis = AXIS[placement] || 'right';\n let crossAxis: Axis = CROSS_AXIS[axis];\n\n if (!AXIS[crossPlacement]) {\n crossPlacement = 'center';\n }\n\n let size = AXIS_SIZE[axis];\n let crossSize = AXIS_SIZE[crossAxis];\n PARSED_PLACEMENT_CACHE[input] = {placement, crossPlacement, axis, crossAxis, size, crossSize};\n return PARSED_PLACEMENT_CACHE[input];\n}\n\nfunction computePosition(\n childOffset: Offset,\n boundaryDimensions: Dimensions,\n overlaySize: Offset,\n placementInfo: ParsedPlacement,\n offset: number,\n crossOffset: number,\n containerOffsetWithBoundary: Offset,\n isContainerPositioned: boolean,\n arrowSize: number,\n arrowBoundaryOffset: number,\n containerDimensions: Dimensions\n) {\n let {placement, crossPlacement, axis, crossAxis, size, crossSize} = placementInfo;\n let position: Position = {};\n\n // button position\n position[crossAxis] = childOffset[crossAxis] ?? 0;\n if (crossPlacement === 'center') {\n // + (button size / 2) - (overlay size / 2)\n // at this point the overlay center should match the button center\n position[crossAxis]! += ((childOffset[crossSize] ?? 0) - (overlaySize[crossSize] ?? 0)) / 2;\n } else if (crossPlacement !== crossAxis) {\n // + (button size) - (overlay size)\n // at this point the overlay bottom should match the button bottom\n position[crossAxis]! += (childOffset[crossSize] ?? 0) - (overlaySize[crossSize] ?? 0);\n } /* else {\n the overlay top should match the button top\n } */\n\n position[crossAxis]! += crossOffset;\n\n // overlay top or left overlapping arrow with button bottom or right\n const minPosition =\n childOffset[crossAxis] - overlaySize[crossSize] + arrowSize + arrowBoundaryOffset;\n // overlay bottom or right overlapping arrow with button top or left\n const maxPosition =\n childOffset[crossAxis] + childOffset[crossSize] - arrowSize - arrowBoundaryOffset;\n position[crossAxis] = clamp(position[crossAxis]!, minPosition, maxPosition);\n\n // Floor these so the position isn't placed on a partial pixel, only whole pixels. Shouldn't matter if it was floored or ceiled, so chose one.\n if (placement === axis) {\n // If the container is positioned (non-static), then we use the container's actual\n // height, as `bottom` will be relative to this height. But if the container is static,\n // then it can only be the `document.body`, and `bottom` will be relative to _its_\n // container.\n let containerHeight = isContainerPositioned\n ? containerDimensions[size]\n : containerDimensions[TOTAL_SIZE[size]];\n position[FLIPPED_DIRECTION[axis]] = Math.floor(containerHeight - childOffset[axis] + offset);\n } else {\n position[axis] = Math.floor(childOffset[axis] + childOffset[size] + offset);\n }\n return position;\n}\n\nfunction getMaxHeight(\n position: Position,\n boundaryDimensions: Dimensions,\n containerOffsetWithBoundary: Offset,\n isContainerPositioned: boolean,\n margins: Position,\n padding: number,\n overlayHeight: number,\n heightGrowthDirection: HeightGrowthDirection,\n containerDimensions: Dimensions,\n isContainerDescendentOfBoundary: boolean,\n visualViewport: VisualViewport | null\n) {\n // For cases where position is set via \"bottom\" instead of \"top\", we need to calculate the true overlay top\n // with respect to the container.\n let overlayTop =\n (position.top != null\n ? position.top\n : containerDimensions[TOTAL_SIZE.height] - (position.bottom ?? 0) - overlayHeight) -\n (containerDimensions.scroll.top ?? 0);\n // calculate the dimentions of the \"boundingRect\" which is most restrictive top/bottom of the boundaryRect and the visual view port\n let boundaryToContainerTransformOffset = isContainerDescendentOfBoundary\n ? containerOffsetWithBoundary.top\n : 0;\n let boundingRect = {\n // This should be boundary top in container coord system vs viewport top in container coord system\n // For the viewport top, there are several cases\n // 1. pinchzoom case where we want the viewports offset top as top here\n // 2. case where container is offset from the boundary and is contained by the boundary. In this case the top we want here is NOT 0, we want to take boundary's top even though is is a negative number OR the visual viewport, whichever is more restrictive\n top: Math.max(\n boundaryDimensions.top + boundaryToContainerTransformOffset,\n (visualViewport?.offsetTop ?? boundaryDimensions.top) + boundaryToContainerTransformOffset\n ),\n bottom: Math.min(\n boundaryDimensions.top + boundaryDimensions.height + boundaryToContainerTransformOffset,\n (visualViewport?.offsetTop ?? 0) + (visualViewport?.height ?? 0)\n )\n };\n let maxHeight =\n heightGrowthDirection !== 'top'\n ? // We want the distance between the top of the overlay to the bottom of the boundary\n Math.max(\n 0,\n boundingRect.bottom - // this is the bottom of the boundary\n overlayTop - // this is the top of the overlay\n ((margins.top ?? 0) + (margins.bottom ?? 0) + padding) // save additional space for margin and padding\n )\n : // We want the distance between the bottom of the overlay to the top of the boundary\n Math.max(\n 0,\n overlayTop +\n overlayHeight - // this is the bottom of the overlay\n boundingRect.top - // this is the top of the boundary\n ((margins.top ?? 0) + (margins.bottom ?? 0) + padding) // save additional space for margin and padding\n );\n return maxHeight;\n}\n\nfunction getAvailableSpace(\n boundaryDimensions: Dimensions, // boundary\n containerOffsetWithBoundary: Offset,\n childOffset: Offset, // trigger, position based of container's non-viewport 0,0\n margins: Position, // overlay\n padding: number, // overlay <-> boundary\n placementInfo: ParsedPlacement,\n containerDimensions: Dimensions,\n isContainerDescendentOfBoundary: boolean\n) {\n let {placement, axis, size} = placementInfo;\n if (placement === axis) {\n return Math.max(\n 0,\n childOffset[axis] - // trigger start\n (containerDimensions.scroll[axis] ?? 0) - // transform trigger position to be with respect to viewport 0,0\n (boundaryDimensions[axis] +\n (isContainerDescendentOfBoundary ? containerOffsetWithBoundary[axis] : 0)) - // boundary start\n (margins[axis] ?? 0) - // margins usually for arrows or other decorations\n margins[FLIPPED_DIRECTION[axis]] -\n padding\n ); // padding between overlay and boundary\n }\n\n return Math.max(\n 0,\n boundaryDimensions[size] +\n boundaryDimensions[axis] +\n (isContainerDescendentOfBoundary ? containerOffsetWithBoundary[axis] : 0) -\n childOffset[axis] -\n childOffset[size] +\n (containerDimensions.scroll[axis] ?? 0) -\n (margins[axis] ?? 0) -\n margins[FLIPPED_DIRECTION[axis]] -\n padding\n );\n}\n\nexport function calculatePositionInternal(\n placementInput: Placement,\n childOffset: Offset,\n overlaySize: Offset,\n scrollSize: Offset,\n margins: Position,\n padding: number,\n flip: boolean,\n boundaryDimensions: Dimensions,\n containerDimensions: Dimensions,\n containerOffsetWithBoundary: Offset,\n offset: number,\n crossOffset: number,\n isContainerPositioned: boolean,\n userSetMaxHeight: number | undefined,\n arrowSize: number,\n arrowBoundaryOffset: number,\n isContainerDescendentOfBoundary: boolean,\n visualViewport: VisualViewport | null\n): PositionResult {\n let placementInfo = parsePlacement(placementInput);\n let {size, crossAxis, crossSize, placement, crossPlacement} = placementInfo;\n let position = computePosition(\n childOffset,\n boundaryDimensions,\n overlaySize,\n placementInfo,\n offset,\n crossOffset,\n containerOffsetWithBoundary,\n isContainerPositioned,\n arrowSize,\n arrowBoundaryOffset,\n containerDimensions\n );\n let normalizedOffset = offset;\n let space = getAvailableSpace(\n boundaryDimensions,\n containerOffsetWithBoundary,\n childOffset,\n margins,\n padding + offset,\n placementInfo,\n containerDimensions,\n isContainerDescendentOfBoundary\n );\n\n // Check if the scroll size of the overlay is greater than the available space to determine if we need to flip\n if (flip && overlaySize[size] > space) {\n let flippedPlacementInfo = parsePlacement(\n `${FLIPPED_DIRECTION[placement]} ${crossPlacement}` as Placement\n );\n let flippedPosition = computePosition(\n childOffset,\n boundaryDimensions,\n overlaySize,\n flippedPlacementInfo,\n offset,\n crossOffset,\n containerOffsetWithBoundary,\n isContainerPositioned,\n arrowSize,\n arrowBoundaryOffset,\n containerDimensions\n );\n\n let flippedSpace = getAvailableSpace(\n boundaryDimensions,\n containerOffsetWithBoundary,\n childOffset,\n margins,\n padding + offset,\n flippedPlacementInfo,\n containerDimensions,\n isContainerDescendentOfBoundary\n );\n\n // If the available space for the flipped position is greater than the original available space, flip.\n if (flippedSpace > space) {\n placementInfo = flippedPlacementInfo;\n position = flippedPosition;\n normalizedOffset = offset;\n }\n }\n\n // Determine the direction the height of the overlay can grow so that we can choose how to calculate the max height\n let heightGrowthDirection: HeightGrowthDirection = 'bottom';\n if (placementInfo.axis === 'top') {\n if (placementInfo.placement === 'top') {\n heightGrowthDirection = 'top';\n } else if (placementInfo.placement === 'bottom') {\n heightGrowthDirection = 'bottom';\n }\n } else if (placementInfo.crossAxis === 'top') {\n if (placementInfo.crossPlacement === 'top') {\n heightGrowthDirection = 'bottom';\n } else if (placementInfo.crossPlacement === 'bottom') {\n heightGrowthDirection = 'top';\n }\n }\n\n let delta = getDelta(\n crossAxis,\n position[crossAxis]!,\n overlaySize[crossSize],\n boundaryDimensions,\n containerDimensions,\n padding,\n containerOffsetWithBoundary\n );\n position[crossAxis]! += delta;\n\n let maxHeight = getMaxHeight(\n position,\n boundaryDimensions,\n containerOffsetWithBoundary,\n isContainerPositioned,\n margins,\n padding,\n overlaySize.height,\n heightGrowthDirection,\n containerDimensions,\n isContainerDescendentOfBoundary,\n visualViewport\n );\n\n if (userSetMaxHeight && userSetMaxHeight < maxHeight) {\n maxHeight = userSetMaxHeight;\n }\n\n overlaySize.height = Math.min(overlaySize.height, maxHeight);\n\n position = computePosition(\n childOffset,\n boundaryDimensions,\n overlaySize,\n placementInfo,\n normalizedOffset,\n crossOffset,\n containerOffsetWithBoundary,\n isContainerPositioned,\n arrowSize,\n arrowBoundaryOffset,\n containerDimensions\n );\n delta = getDelta(\n crossAxis,\n position[crossAxis]!,\n overlaySize[crossSize],\n boundaryDimensions,\n containerDimensions,\n padding,\n containerOffsetWithBoundary\n );\n position[crossAxis]! += delta;\n\n let arrowPosition: Position = {};\n\n // All values are transformed so that 0 is at the top/left of the overlay depending on the orientation\n // Prefer the arrow being in the center of the trigger/overlay anchor element\n // childOffset[crossAxis] + .5 * childOffset[crossSize] = absolute position with respect to the trigger's coordinate system that would place the arrow in the center of the trigger\n // position[crossAxis] - margins[AXIS[crossAxis]] = value use to transform the position to a value with respect to the overlay's coordinate system. A child element's (aka arrow) position absolute's \"0\"\n // is positioned after the margin of its parent (aka overlay) so we need to subtract it to get the proper coordinate transform\n let origin = childOffset[crossAxis] - position[crossAxis]! - margins[AXIS[crossAxis]];\n let preferredArrowPosition = origin + 0.5 * childOffset[crossSize];\n\n // Min/Max position limits for the arrow with respect to the overlay\n const arrowMinPosition = arrowSize / 2 + arrowBoundaryOffset;\n // overlaySize[crossSize] - margins = true size of the overlay\n const overlayMargin =\n AXIS[crossAxis] === 'left'\n ? (margins.left ?? 0) + (margins.right ?? 0)\n : (margins.top ?? 0) + (margins.bottom ?? 0);\n const arrowMaxPosition =\n overlaySize[crossSize] - overlayMargin - arrowSize / 2 - arrowBoundaryOffset;\n\n // Min/Max position limits for the arrow with respect to the trigger/overlay anchor element\n // Same margin accomodation done here as well as for the preferredArrowPosition\n const arrowOverlappingChildMinEdge =\n childOffset[crossAxis] + arrowSize / 2 - (position[crossAxis] + margins[AXIS[crossAxis]]);\n const arrowOverlappingChildMaxEdge =\n childOffset[crossAxis] +\n childOffset[crossSize] -\n arrowSize / 2 -\n (position[crossAxis] + margins[AXIS[crossAxis]]);\n\n // Clamp the arrow positioning so that it always is within the bounds of the anchor and the overlay\n const arrowPositionOverlappingChild = clamp(\n preferredArrowPosition,\n arrowOverlappingChildMinEdge,\n arrowOverlappingChildMaxEdge\n );\n arrowPosition[crossAxis] = clamp(\n arrowPositionOverlappingChild,\n arrowMinPosition,\n arrowMaxPosition\n );\n\n // If there is an arrow, use that as the origin so that animations are smooth.\n // Otherwise use the target edge.\n ({placement, crossPlacement} = placementInfo);\n if (arrowSize) {\n origin = arrowPosition[crossAxis];\n } else if (crossPlacement === 'right') {\n origin += childOffset[crossSize];\n } else if (crossPlacement === 'center') {\n origin += childOffset[crossSize] / 2;\n }\n\n let crossOrigin = placement === 'left' || placement === 'top' ? overlaySize[size] : 0;\n let triggerAnchorPoint = {\n x: placement === 'top' || placement === 'bottom' ? origin : crossOrigin,\n y: placement === 'left' || placement === 'right' ? origin : crossOrigin\n };\n\n return {\n position,\n maxHeight: maxHeight,\n arrowOffsetLeft: arrowPosition.left,\n arrowOffsetTop: arrowPosition.top,\n placement,\n triggerAnchorPoint\n };\n}\n\n/**\n * Determines where to place the overlay with regards to the target and the position of an optional\n * indicator.\n */\nexport function calculatePosition(opts: PositionOpts): PositionResult {\n let {\n placement,\n targetNode,\n overlayNode,\n scrollNode,\n padding,\n shouldFlip,\n boundaryElement,\n offset,\n crossOffset,\n maxHeight,\n arrowSize = 0,\n arrowBoundaryOffset = 0\n } = opts;\n\n let visualViewport = getVisualViewport();\n let container =\n overlayNode instanceof HTMLElement ? getContainingBlock(overlayNode) : document.documentElement;\n let isViewportContainer = container === document.documentElement;\n const containerPositionStyle = window.getComputedStyle(container).position;\n let isContainerPositioned = !!containerPositionStyle && containerPositionStyle !== 'static';\n let childOffset: Offset = isViewportContainer\n ? getOffset(targetNode, false)\n : getPosition(targetNode, container, false);\n\n if (!isViewportContainer) {\n let {marginTop, marginLeft} = window.getComputedStyle(targetNode);\n childOffset.top += parseInt(marginTop, 10) || 0;\n childOffset.left += parseInt(marginLeft, 10) || 0;\n }\n\n let overlaySize: Offset = getOffset(overlayNode, true);\n let margins = getMargins(overlayNode);\n overlaySize.width += (margins.left ?? 0) + (margins.right ?? 0);\n overlaySize.height += (margins.top ?? 0) + (margins.bottom ?? 0);\n\n let scrollSize = getScroll(scrollNode);\n\n // Note that due to logic inside getContainerDimensions, for cases where the boundary element is the body, we will return\n // a height/width that matches the visual viewport size rather than the body's height/width (aka for zoom it will be zoom adjusted size)\n // and a top/left that is adjusted as well (will return the top/left of the zoomed in viewport, or 0,0 for a non-zoomed body)\n // Otherwise this returns the height/width of a arbitrary boundary element, and its top/left with respect to the viewport (NOTE THIS MEANS IT DOESNT INCLUDE SCROLL)\n let boundaryDimensions = getContainerDimensions(boundaryElement, visualViewport);\n let containerDimensions = getContainerDimensions(container, visualViewport);\n\n // There are several difference cases of how to calculate the containerOffsetWithBoundary:\n // - boundaryElement is body or HTML and the container is an arbitrary element in the boundary (aka submenu with parent menu as container in v3)\n // - boundaryElement and container are both body or HTML element (aka standard popover case)\n // - boundaryElement is customized by the user. Container can also be arbitrary (either body/HTML or some other element)\n // containerOffsetWithBoundary should always return a value that is the boundary's coordinate offset with respect to the container coord system (container is 0, 0)\n let containerOffsetWithBoundary: Offset;\n if (\n (boundaryElement.tagName === 'BODY' || boundaryElement.tagName === 'HTML') &&\n !isViewportContainer\n ) {\n // Use getRect instead of getOffset because boundaryDimensions for BODY/HTML is in viewport coordinate space,\n // not document coordinate space\n let containerRect = getRect(container, false);\n // the offset should be negative because if container is at viewport position x,y, then viewport top (aka 0)\n // is at position -x,y in container-relative coordinates\n containerOffsetWithBoundary = {\n top: -(containerRect.top - boundaryDimensions.top),\n left: -(containerRect.left - boundaryDimensions.left),\n width: 0,\n height: 0\n };\n } else if (\n (boundaryElement.tagName === 'BODY' || boundaryElement.tagName === 'HTML') &&\n isViewportContainer\n ) {\n // both are the same viewport container, no offset needed\n containerOffsetWithBoundary = {top: 0, left: 0, width: 0, height: 0};\n } else {\n // This returns the boundary's coordinate with respect to the container. This case captures cases such as when you provide a custom boundary\n // like in ScrollingBoundaryContainerExample in Popover.stories.\n containerOffsetWithBoundary = getPosition(boundaryElement, container, false);\n }\n\n let isContainerDescendentOfBoundary = nodeContains(boundaryElement, container);\n return calculatePositionInternal(\n placement,\n childOffset,\n overlaySize,\n scrollSize,\n margins,\n padding,\n shouldFlip,\n boundaryDimensions,\n containerDimensions,\n containerOffsetWithBoundary,\n offset,\n crossOffset,\n isContainerPositioned,\n maxHeight,\n arrowSize,\n arrowBoundaryOffset,\n isContainerDescendentOfBoundary,\n visualViewport\n );\n}\n\nexport function getRect(node: Element, ignoreScale: boolean) {\n let {top, left, width, height} = node.getBoundingClientRect();\n\n // Use offsetWidth and offsetHeight if this is an HTML element, so that\n // the size is not affected by scale transforms.\n if (ignoreScale && node instanceof node.ownerDocument.defaultView!.HTMLElement) {\n width = node.offsetWidth;\n height = node.offsetHeight;\n }\n\n return {top, left, width, height};\n}\n\nfunction getOffset(node: Element, ignoreScale: boolean): Offset {\n let {top, left, width, height} = getRect(node, ignoreScale);\n let {scrollTop, scrollLeft, clientTop, clientLeft} = document.documentElement;\n return {\n top: top + scrollTop - clientTop,\n left: left + scrollLeft - clientLeft,\n width,\n height\n };\n}\n\nfunction getPosition(node: Element, parent: Element, ignoreScale: boolean): Offset {\n let style = window.getComputedStyle(node);\n let offset: Offset;\n if (style.position === 'fixed') {\n offset = getRect(node, ignoreScale);\n } else {\n offset = getOffset(node, ignoreScale);\n let parentOffset = getOffset(parent, ignoreScale);\n let parentStyle = window.getComputedStyle(parent);\n parentOffset.top += (parseInt(parentStyle.borderTopWidth, 10) || 0) - parent.scrollTop;\n parentOffset.left += (parseInt(parentStyle.borderLeftWidth, 10) || 0) - parent.scrollLeft;\n offset.top -= parentOffset.top;\n offset.left -= parentOffset.left;\n }\n\n offset.top -= parseInt(style.marginTop, 10) || 0;\n offset.left -= parseInt(style.marginLeft, 10) || 0;\n return offset;\n}\n\n// Returns the containing block of an element, which is the element that\n// this element will be positioned relative to.\n// https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block\nfunction getContainingBlock(node: HTMLElement): Element {\n // The offsetParent of an element in most cases equals the containing block.\n // https://w3c.github.io/csswg-drafts/cssom-view/#dom-htmlelement-offsetparent\n let offsetParent = node.offsetParent;\n\n // The offsetParent algorithm terminates at the document body,\n // even if the body is not a containing block. Double check that\n // and use the documentElement if so.\n if (\n offsetParent &&\n offsetParent === document.body &&\n window.getComputedStyle(offsetParent).position === 'static' &&\n !isContainingBlock(offsetParent)\n ) {\n offsetParent = document.documentElement;\n }\n\n // TODO(later): handle table elements?\n\n // The offsetParent can be null if the element has position: fixed, or a few other cases.\n // We have to walk up the tree manually in this case because fixed positioned elements\n // are still positioned relative to their containing block, which is not always the viewport.\n if (offsetParent == null) {\n offsetParent = node.parentElement;\n while (offsetParent && !isContainingBlock(offsetParent)) {\n offsetParent = offsetParent.parentElement;\n }\n }\n\n // Fall back to the viewport.\n return offsetParent || document.documentElement;\n}\n\n// https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block\nfunction isContainingBlock(node: Element): boolean {\n let style = window.getComputedStyle(node);\n return (\n style.transform !== 'none' ||\n /transform|perspective/.test(style.willChange) ||\n style.filter !== 'none' ||\n style.contain === 'paint' ||\n ('backdropFilter' in style && style.backdropFilter !== 'none') ||\n ('WebkitBackdropFilter' in style && style.WebkitBackdropFilter !== 'none')\n );\n}\n"],"names":[],"version":3,"file":"calculatePosition.mjs.map"}
1
+ {"mappings":"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","sources":["packages/react-aria/src/overlays/calculatePosition.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Axis, Placement, PlacementAxis, SizeAxis} from './useOverlayPosition';\nimport {clamp} from 'react-stately/private/utils/number';\nimport {isWebKit} from '../utils/platform';\nimport {nodeContains} from '../utils/shadowdom/DOMFunctions';\n\ninterface Position {\n top?: number;\n left?: number;\n bottom?: number;\n right?: number;\n}\n\ninterface Dimensions {\n width: number;\n height: number;\n totalWidth: number;\n totalHeight: number;\n top: number;\n left: number;\n scroll: Position;\n}\n\ninterface ParsedPlacement {\n placement: PlacementAxis;\n crossPlacement: PlacementAxis;\n axis: Axis;\n crossAxis: Axis;\n size: SizeAxis;\n crossSize: SizeAxis;\n}\n\ninterface Offset {\n top: number;\n left: number;\n width: number;\n height: number;\n}\n\ninterface PositionOpts {\n arrowSize: number;\n placement: Placement;\n targetNode: Element;\n overlayNode: Element;\n scrollNode: Element;\n padding: number;\n shouldFlip: boolean;\n boundaryElement: Element;\n offset: number;\n crossOffset: number;\n maxHeight?: number;\n arrowBoundaryOffset?: number;\n targetRect?: Offset | null | undefined;\n}\n\ntype HeightGrowthDirection = 'top' | 'bottom';\n\nexport interface PositionResult {\n position: Position;\n arrowOffsetLeft?: number;\n arrowOffsetTop?: number;\n triggerAnchorPoint: {x: number; y: number};\n maxHeight: number;\n placement: PlacementAxis;\n}\n\nconst AXIS = {\n top: 'top',\n bottom: 'top',\n left: 'left',\n right: 'left'\n};\n\nconst FLIPPED_DIRECTION = {\n top: 'bottom',\n bottom: 'top',\n left: 'right',\n right: 'left'\n};\n\nconst CROSS_AXIS = {\n top: 'left',\n left: 'top'\n};\n\nconst AXIS_SIZE = {\n top: 'height',\n left: 'width'\n};\n\nconst TOTAL_SIZE = {\n width: 'totalWidth',\n height: 'totalHeight'\n};\n\nconst PARSED_PLACEMENT_CACHE = {};\n\nlet getVisualViewport = () => (typeof document !== 'undefined' ? window.visualViewport : null);\n\nfunction getContainerDimensions(\n containerNode: Element,\n visualViewport: VisualViewport | null\n): Dimensions {\n let width = 0,\n height = 0,\n totalWidth = 0,\n totalHeight = 0,\n top = 0,\n left = 0;\n let scroll: Position = {};\n let isPinchZoomedIn = (visualViewport?.scale ?? 1) > 1;\n\n // In the case where the container is `html` or `body` and the container doesn't have something like `position: relative`,\n // then position absolute will be positioned relative to the viewport, also known as the `initial containing block`.\n // That's why we use the visual viewport instead.\n\n if (containerNode.tagName === 'BODY' || containerNode.tagName === 'HTML') {\n let documentElement = document.documentElement;\n totalWidth = documentElement.clientWidth;\n totalHeight = documentElement.clientHeight;\n width = visualViewport?.width ?? totalWidth;\n height = visualViewport?.height ?? totalHeight;\n scroll.top = documentElement.scrollTop || containerNode.scrollTop;\n scroll.left = documentElement.scrollLeft || containerNode.scrollLeft;\n\n // The goal of the below is to get a top/left value that represents the top/left of the visual viewport with\n // respect to the layout viewport origin. This combined with the scrollTop/scrollLeft will allow us to calculate\n // coordinates/values with respect to the visual viewport or with respect to the layout viewport.\n if (visualViewport) {\n top = visualViewport.offsetTop;\n left = visualViewport.offsetLeft;\n }\n } else {\n ({width, height, top, left} = getOffset(containerNode, false));\n scroll.top = containerNode.scrollTop;\n scroll.left = containerNode.scrollLeft;\n totalWidth = width;\n totalHeight = height;\n }\n\n if (\n isWebKit() &&\n (containerNode.tagName === 'BODY' || containerNode.tagName === 'HTML') &&\n isPinchZoomedIn\n ) {\n // Safari will report a non-zero scrollTop/Left for the non-scrolling body/HTML element when pinch zoomed in unlike other browsers.\n // Set to zero for parity calculations so we get consistent positioning of overlays across all browsers.\n // Also switch to visualViewport.pageTop/pageLeft so that we still accomodate for scroll positioning for body/HTML elements that are actually scrollable\n // before pinch zoom happens\n scroll.top = 0;\n scroll.left = 0;\n top = visualViewport?.pageTop ?? 0;\n left = visualViewport?.pageLeft ?? 0;\n }\n\n return {width, height, totalWidth, totalHeight, scroll, top, left};\n}\n\nfunction getScroll(node: Element): Offset {\n return {\n top: node.scrollTop,\n left: node.scrollLeft,\n width: node.scrollWidth,\n height: node.scrollHeight\n };\n}\n\n// Determines the amount of space required when moving the overlay to ensure it remains in the boundary\nfunction getDelta(\n axis: Axis,\n offset: number,\n size: number,\n // The dimensions of the boundary element that the popover is\n // positioned within (most of the time this is the <body>).\n boundaryDimensions: Dimensions,\n // The dimensions of the containing block element that the popover is\n // positioned relative to (e.g. parent with position: relative).\n // Usually this is the same as the boundary element, but if the popover\n // is portaled somewhere other than the body and has an ancestor with\n // position: relative/absolute, it will be different.\n containerDimensions: Dimensions,\n padding: number,\n containerOffsetWithBoundary: Offset\n) {\n let containerScroll = containerDimensions.scroll[axis] ?? 0;\n // The height/width of the boundary. Matches the axis along which we are adjusting the overlay position\n let boundarySize = boundaryDimensions[AXIS_SIZE[axis]];\n // Calculate the edges of the boundary (accomodating for the boundary padding) and the edges of the overlay.\n // Note that these values are with respect to the visual viewport (aka 0,0 is the top left of the viewport)\n\n let boundaryStartEdge =\n containerOffsetWithBoundary[axis] + boundaryDimensions.scroll[AXIS[axis]] + padding;\n let boundaryEndEdge =\n containerOffsetWithBoundary[axis] +\n boundaryDimensions.scroll[AXIS[axis]] +\n boundarySize -\n padding;\n // transformed value of the left edge of the overlay\n let startEdgeOffset =\n offset -\n containerScroll +\n boundaryDimensions.scroll[AXIS[axis]] +\n containerOffsetWithBoundary[axis] -\n boundaryDimensions[AXIS[axis]];\n // transformed value of the right edge of the overlay\n let endEdgeOffset =\n offset -\n containerScroll +\n size +\n boundaryDimensions.scroll[AXIS[axis]] +\n containerOffsetWithBoundary[axis] -\n boundaryDimensions[AXIS[axis]];\n\n // If any of the overlay edges falls outside of the boundary, shift the overlay the required amount to align one of the overlay's\n // edges with the closest boundary edge.\n if (startEdgeOffset < boundaryStartEdge) {\n return boundaryStartEdge - startEdgeOffset;\n } else if (endEdgeOffset > boundaryEndEdge) {\n return Math.max(boundaryEndEdge - endEdgeOffset, boundaryStartEdge - startEdgeOffset);\n } else {\n return 0;\n }\n}\n\nfunction getMargins(node: Element): Position {\n let style = window.getComputedStyle(node);\n return {\n top: parseInt(style.marginTop, 10) || 0,\n bottom: parseInt(style.marginBottom, 10) || 0,\n left: parseInt(style.marginLeft, 10) || 0,\n right: parseInt(style.marginRight, 10) || 0\n };\n}\n\nfunction parsePlacement(input: Placement): ParsedPlacement {\n if (PARSED_PLACEMENT_CACHE[input]) {\n return PARSED_PLACEMENT_CACHE[input];\n }\n\n let [placement, crossPlacement] = input.split(' ');\n let axis: Axis = AXIS[placement] || 'right';\n let crossAxis: Axis = CROSS_AXIS[axis];\n\n if (!AXIS[crossPlacement]) {\n crossPlacement = 'center';\n }\n\n let size = AXIS_SIZE[axis];\n let crossSize = AXIS_SIZE[crossAxis];\n PARSED_PLACEMENT_CACHE[input] = {placement, crossPlacement, axis, crossAxis, size, crossSize};\n return PARSED_PLACEMENT_CACHE[input];\n}\n\nfunction computePosition(\n childOffset: Offset,\n boundaryDimensions: Dimensions,\n overlaySize: Offset,\n placementInfo: ParsedPlacement,\n offset: number,\n crossOffset: number,\n containerOffsetWithBoundary: Offset,\n isContainerPositioned: boolean,\n arrowSize: number,\n arrowBoundaryOffset: number,\n containerDimensions: Dimensions\n) {\n let {placement, crossPlacement, axis, crossAxis, size, crossSize} = placementInfo;\n let position: Position = {};\n\n // button position\n position[crossAxis] = childOffset[crossAxis] ?? 0;\n if (crossPlacement === 'center') {\n // + (button size / 2) - (overlay size / 2)\n // at this point the overlay center should match the button center\n position[crossAxis]! += ((childOffset[crossSize] ?? 0) - (overlaySize[crossSize] ?? 0)) / 2;\n } else if (crossPlacement !== crossAxis) {\n // + (button size) - (overlay size)\n // at this point the overlay bottom should match the button bottom\n position[crossAxis]! += (childOffset[crossSize] ?? 0) - (overlaySize[crossSize] ?? 0);\n } /* else {\n the overlay top should match the button top\n } */\n\n position[crossAxis]! += crossOffset;\n\n // overlay top or left overlapping arrow with button bottom or right\n const minPosition =\n childOffset[crossAxis] - overlaySize[crossSize] + arrowSize + arrowBoundaryOffset;\n // overlay bottom or right overlapping arrow with button top or left\n const maxPosition =\n childOffset[crossAxis] + childOffset[crossSize] - arrowSize - arrowBoundaryOffset;\n position[crossAxis] = clamp(position[crossAxis]!, minPosition, maxPosition);\n\n // Floor these so the position isn't placed on a partial pixel, only whole pixels. Shouldn't matter if it was floored or ceiled, so chose one.\n if (placement === axis) {\n // If the container is positioned (non-static), then we use the container's actual\n // height, as `bottom` will be relative to this height. But if the container is static,\n // then it can only be the `document.body`, and `bottom` will be relative to _its_\n // container.\n let containerHeight = isContainerPositioned\n ? containerDimensions[size]\n : containerDimensions[TOTAL_SIZE[size]];\n position[FLIPPED_DIRECTION[axis]] = Math.floor(containerHeight - childOffset[axis] + offset);\n } else {\n position[axis] = Math.floor(childOffset[axis] + childOffset[size] + offset);\n }\n return position;\n}\n\nfunction getMaxHeight(\n position: Position,\n boundaryDimensions: Dimensions,\n containerOffsetWithBoundary: Offset,\n isContainerPositioned: boolean,\n margins: Position,\n padding: number,\n overlayHeight: number,\n heightGrowthDirection: HeightGrowthDirection,\n containerDimensions: Dimensions,\n isContainerDescendentOfBoundary: boolean,\n visualViewport: VisualViewport | null\n) {\n // For cases where position is set via \"bottom\" instead of \"top\", we need to calculate the true overlay top\n // with respect to the container.\n let overlayTop =\n (position.top != null\n ? position.top\n : containerDimensions[TOTAL_SIZE.height] - (position.bottom ?? 0) - overlayHeight) -\n (containerDimensions.scroll.top ?? 0);\n // calculate the dimentions of the \"boundingRect\" which is most restrictive top/bottom of the boundaryRect and the visual view port\n let boundaryToContainerTransformOffset = isContainerDescendentOfBoundary\n ? containerOffsetWithBoundary.top\n : 0;\n let boundingRect = {\n // This should be boundary top in container coord system vs viewport top in container coord system\n // For the viewport top, there are several cases\n // 1. pinchzoom case where we want the viewports offset top as top here\n // 2. case where container is offset from the boundary and is contained by the boundary. In this case the top we want here is NOT 0, we want to take boundary's top even though is is a negative number OR the visual viewport, whichever is more restrictive\n top: Math.max(\n boundaryDimensions.top + boundaryToContainerTransformOffset,\n (visualViewport?.offsetTop ?? boundaryDimensions.top) + boundaryToContainerTransformOffset\n ),\n bottom: Math.min(\n boundaryDimensions.top + boundaryDimensions.height + boundaryToContainerTransformOffset,\n (visualViewport?.offsetTop ?? 0) + (visualViewport?.height ?? 0)\n )\n };\n let maxHeight =\n heightGrowthDirection !== 'top'\n ? // We want the distance between the top of the overlay to the bottom of the boundary\n Math.max(\n 0,\n boundingRect.bottom - // this is the bottom of the boundary\n overlayTop - // this is the top of the overlay\n ((margins.top ?? 0) + (margins.bottom ?? 0) + padding) // save additional space for margin and padding\n )\n : // We want the distance between the bottom of the overlay to the top of the boundary\n Math.max(\n 0,\n overlayTop +\n overlayHeight - // this is the bottom of the overlay\n boundingRect.top - // this is the top of the boundary\n ((margins.top ?? 0) + (margins.bottom ?? 0) + padding) // save additional space for margin and padding\n );\n return maxHeight;\n}\n\nfunction getAvailableSpace(\n boundaryDimensions: Dimensions, // boundary\n containerOffsetWithBoundary: Offset,\n childOffset: Offset, // trigger, position based of container's non-viewport 0,0\n margins: Position, // overlay\n padding: number, // overlay <-> boundary\n placementInfo: ParsedPlacement,\n containerDimensions: Dimensions,\n isContainerDescendentOfBoundary: boolean\n) {\n let {placement, axis, size} = placementInfo;\n if (placement === axis) {\n return Math.max(\n 0,\n childOffset[axis] - // trigger start\n (containerDimensions.scroll[axis] ?? 0) - // transform trigger position to be with respect to viewport 0,0\n (boundaryDimensions[axis] +\n (isContainerDescendentOfBoundary ? containerOffsetWithBoundary[axis] : 0)) - // boundary start\n (margins[axis] ?? 0) - // margins usually for arrows or other decorations\n margins[FLIPPED_DIRECTION[axis]] -\n padding\n ); // padding between overlay and boundary\n }\n\n return Math.max(\n 0,\n boundaryDimensions[size] +\n boundaryDimensions[axis] +\n (isContainerDescendentOfBoundary ? containerOffsetWithBoundary[axis] : 0) -\n childOffset[axis] -\n childOffset[size] +\n (containerDimensions.scroll[axis] ?? 0) -\n (margins[axis] ?? 0) -\n margins[FLIPPED_DIRECTION[axis]] -\n padding\n );\n}\n\nexport function calculatePositionInternal(\n placementInput: Placement,\n childOffset: Offset,\n overlaySize: Offset,\n scrollSize: Offset,\n margins: Position,\n padding: number,\n flip: boolean,\n boundaryDimensions: Dimensions,\n containerDimensions: Dimensions,\n containerOffsetWithBoundary: Offset,\n offset: number,\n crossOffset: number,\n isContainerPositioned: boolean,\n userSetMaxHeight: number | undefined,\n arrowSize: number,\n arrowBoundaryOffset: number,\n isContainerDescendentOfBoundary: boolean,\n visualViewport: VisualViewport | null\n): PositionResult {\n let placementInfo = parsePlacement(placementInput);\n let {size, crossAxis, crossSize, placement, crossPlacement} = placementInfo;\n let position = computePosition(\n childOffset,\n boundaryDimensions,\n overlaySize,\n placementInfo,\n offset,\n crossOffset,\n containerOffsetWithBoundary,\n isContainerPositioned,\n arrowSize,\n arrowBoundaryOffset,\n containerDimensions\n );\n let normalizedOffset = offset;\n let space = getAvailableSpace(\n boundaryDimensions,\n containerOffsetWithBoundary,\n childOffset,\n margins,\n padding + offset,\n placementInfo,\n containerDimensions,\n isContainerDescendentOfBoundary\n );\n\n // Check if the scroll size of the overlay is greater than the available space to determine if we need to flip\n if (flip && overlaySize[size] > space) {\n let flippedPlacementInfo = parsePlacement(\n `${FLIPPED_DIRECTION[placement]} ${crossPlacement}` as Placement\n );\n let flippedPosition = computePosition(\n childOffset,\n boundaryDimensions,\n overlaySize,\n flippedPlacementInfo,\n offset,\n crossOffset,\n containerOffsetWithBoundary,\n isContainerPositioned,\n arrowSize,\n arrowBoundaryOffset,\n containerDimensions\n );\n\n let flippedSpace = getAvailableSpace(\n boundaryDimensions,\n containerOffsetWithBoundary,\n childOffset,\n margins,\n padding + offset,\n flippedPlacementInfo,\n containerDimensions,\n isContainerDescendentOfBoundary\n );\n\n // If the available space for the flipped position is greater than the original available space, flip.\n if (flippedSpace > space) {\n placementInfo = flippedPlacementInfo;\n position = flippedPosition;\n normalizedOffset = offset;\n }\n }\n\n // Determine the direction the height of the overlay can grow so that we can choose how to calculate the max height\n let heightGrowthDirection: HeightGrowthDirection = 'bottom';\n if (placementInfo.axis === 'top') {\n if (placementInfo.placement === 'top') {\n heightGrowthDirection = 'top';\n } else if (placementInfo.placement === 'bottom') {\n heightGrowthDirection = 'bottom';\n }\n } else if (placementInfo.crossAxis === 'top') {\n if (placementInfo.crossPlacement === 'top') {\n heightGrowthDirection = 'bottom';\n } else if (placementInfo.crossPlacement === 'bottom') {\n heightGrowthDirection = 'top';\n }\n }\n\n let delta = getDelta(\n crossAxis,\n position[crossAxis]!,\n overlaySize[crossSize],\n boundaryDimensions,\n containerDimensions,\n padding,\n containerOffsetWithBoundary\n );\n position[crossAxis]! += delta;\n\n let maxHeight = getMaxHeight(\n position,\n boundaryDimensions,\n containerOffsetWithBoundary,\n isContainerPositioned,\n margins,\n padding,\n overlaySize.height,\n heightGrowthDirection,\n containerDimensions,\n isContainerDescendentOfBoundary,\n visualViewport\n );\n\n if (userSetMaxHeight && userSetMaxHeight < maxHeight) {\n maxHeight = userSetMaxHeight;\n }\n\n overlaySize.height = Math.min(overlaySize.height, maxHeight);\n\n position = computePosition(\n childOffset,\n boundaryDimensions,\n overlaySize,\n placementInfo,\n normalizedOffset,\n crossOffset,\n containerOffsetWithBoundary,\n isContainerPositioned,\n arrowSize,\n arrowBoundaryOffset,\n containerDimensions\n );\n delta = getDelta(\n crossAxis,\n position[crossAxis]!,\n overlaySize[crossSize],\n boundaryDimensions,\n containerDimensions,\n padding,\n containerOffsetWithBoundary\n );\n position[crossAxis]! += delta;\n\n let arrowPosition: Position = {};\n\n // All values are transformed so that 0 is at the top/left of the overlay depending on the orientation\n // Prefer the arrow being in the center of the trigger/overlay anchor element\n // childOffset[crossAxis] + .5 * childOffset[crossSize] = absolute position with respect to the trigger's coordinate system that would place the arrow in the center of the trigger\n // position[crossAxis] - margins[AXIS[crossAxis]] = value use to transform the position to a value with respect to the overlay's coordinate system. A child element's (aka arrow) position absolute's \"0\"\n // is positioned after the margin of its parent (aka overlay) so we need to subtract it to get the proper coordinate transform\n let origin = childOffset[crossAxis] - position[crossAxis]! - margins[AXIS[crossAxis]];\n let preferredArrowPosition = origin + 0.5 * childOffset[crossSize];\n\n // Min/Max position limits for the arrow with respect to the overlay\n const arrowMinPosition = arrowSize / 2 + arrowBoundaryOffset;\n // overlaySize[crossSize] - margins = true size of the overlay\n const overlayMargin =\n AXIS[crossAxis] === 'left'\n ? (margins.left ?? 0) + (margins.right ?? 0)\n : (margins.top ?? 0) + (margins.bottom ?? 0);\n const arrowMaxPosition =\n overlaySize[crossSize] - overlayMargin - arrowSize / 2 - arrowBoundaryOffset;\n\n // Min/Max position limits for the arrow with respect to the trigger/overlay anchor element\n // Same margin accomodation done here as well as for the preferredArrowPosition\n const arrowOverlappingChildMinEdge =\n childOffset[crossAxis] + arrowSize / 2 - (position[crossAxis] + margins[AXIS[crossAxis]]);\n const arrowOverlappingChildMaxEdge =\n childOffset[crossAxis] +\n childOffset[crossSize] -\n arrowSize / 2 -\n (position[crossAxis] + margins[AXIS[crossAxis]]);\n\n // Clamp the arrow positioning so that it always is within the bounds of the anchor and the overlay\n const arrowPositionOverlappingChild = clamp(\n preferredArrowPosition,\n arrowOverlappingChildMinEdge,\n arrowOverlappingChildMaxEdge\n );\n arrowPosition[crossAxis] = clamp(\n arrowPositionOverlappingChild,\n arrowMinPosition,\n arrowMaxPosition\n );\n\n // If there is an arrow, use that as the origin so that animations are smooth.\n // Otherwise use the target edge.\n ({placement, crossPlacement} = placementInfo);\n if (arrowSize) {\n origin = arrowPosition[crossAxis];\n } else if (crossPlacement === 'right') {\n origin += childOffset[crossSize];\n } else if (crossPlacement === 'center') {\n origin += childOffset[crossSize] / 2;\n }\n\n let crossOrigin = placement === 'left' || placement === 'top' ? overlaySize[size] : 0;\n let triggerAnchorPoint = {\n x: placement === 'top' || placement === 'bottom' ? origin : crossOrigin,\n y: placement === 'left' || placement === 'right' ? origin : crossOrigin\n };\n\n return {\n position,\n maxHeight: maxHeight,\n arrowOffsetLeft: arrowPosition.left,\n arrowOffsetTop: arrowPosition.top,\n placement,\n triggerAnchorPoint\n };\n}\n\n/**\n * Determines where to place the overlay with regards to the target and the position of an optional\n * indicator.\n */\nexport function calculatePosition(opts: PositionOpts): PositionResult {\n let {\n placement,\n targetNode,\n overlayNode,\n scrollNode,\n padding,\n shouldFlip,\n boundaryElement,\n offset,\n crossOffset,\n maxHeight,\n arrowSize = 0,\n arrowBoundaryOffset = 0,\n targetRect\n } = opts;\n\n let visualViewport = getVisualViewport();\n let container =\n overlayNode instanceof HTMLElement ? getContainingBlock(overlayNode) : document.documentElement;\n let isViewportContainer = container === document.documentElement;\n const containerPositionStyle = window.getComputedStyle(container).position;\n let isContainerPositioned = !!containerPositionStyle && containerPositionStyle !== 'static';\n let childOffset: Offset = isViewportContainer\n ? getOffset(targetNode, false, targetRect)\n : getPosition(targetNode, container, false, targetRect);\n\n if (!isViewportContainer) {\n let {marginTop, marginLeft} = window.getComputedStyle(targetNode);\n childOffset.top += parseInt(marginTop, 10) || 0;\n childOffset.left += parseInt(marginLeft, 10) || 0;\n }\n\n let overlaySize: Offset = getOffset(overlayNode, true);\n let margins = getMargins(overlayNode);\n overlaySize.width += (margins.left ?? 0) + (margins.right ?? 0);\n overlaySize.height += (margins.top ?? 0) + (margins.bottom ?? 0);\n\n let scrollSize = getScroll(scrollNode);\n\n // Note that due to logic inside getContainerDimensions, for cases where the boundary element is the body, we will return\n // a height/width that matches the visual viewport size rather than the body's height/width (aka for zoom it will be zoom adjusted size)\n // and a top/left that is adjusted as well (will return the top/left of the zoomed in viewport, or 0,0 for a non-zoomed body)\n // Otherwise this returns the height/width of a arbitrary boundary element, and its top/left with respect to the viewport (NOTE THIS MEANS IT DOESNT INCLUDE SCROLL)\n let boundaryDimensions = getContainerDimensions(boundaryElement, visualViewport);\n let containerDimensions = getContainerDimensions(container, visualViewport);\n\n // There are several difference cases of how to calculate the containerOffsetWithBoundary:\n // - boundaryElement is body or HTML and the container is an arbitrary element in the boundary (aka submenu with parent menu as container in v3)\n // - boundaryElement and container are both body or HTML element (aka standard popover case)\n // - boundaryElement is customized by the user. Container can also be arbitrary (either body/HTML or some other element)\n // containerOffsetWithBoundary should always return a value that is the boundary's coordinate offset with respect to the container coord system (container is 0, 0)\n let containerOffsetWithBoundary: Offset;\n if (\n (boundaryElement.tagName === 'BODY' || boundaryElement.tagName === 'HTML') &&\n !isViewportContainer\n ) {\n // Use getRect instead of getOffset because boundaryDimensions for BODY/HTML is in viewport coordinate space,\n // not document coordinate space\n let containerRect = getRect(container, false);\n // the offset should be negative because if container is at viewport position x,y, then viewport top (aka 0)\n // is at position -x,y in container-relative coordinates\n containerOffsetWithBoundary = {\n top: -(containerRect.top - boundaryDimensions.top),\n left: -(containerRect.left - boundaryDimensions.left),\n width: 0,\n height: 0\n };\n } else if (\n (boundaryElement.tagName === 'BODY' || boundaryElement.tagName === 'HTML') &&\n isViewportContainer\n ) {\n // both are the same viewport container, no offset needed\n containerOffsetWithBoundary = {top: 0, left: 0, width: 0, height: 0};\n } else {\n // This returns the boundary's coordinate with respect to the container. This case captures cases such as when you provide a custom boundary\n // like in ScrollingBoundaryContainerExample in Popover.stories.\n containerOffsetWithBoundary = getPosition(boundaryElement, container, false);\n }\n\n let isContainerDescendentOfBoundary = nodeContains(boundaryElement, container);\n return calculatePositionInternal(\n placement,\n childOffset,\n overlaySize,\n scrollSize,\n margins,\n padding,\n shouldFlip,\n boundaryDimensions,\n containerDimensions,\n containerOffsetWithBoundary,\n offset,\n crossOffset,\n isContainerPositioned,\n maxHeight,\n arrowSize,\n arrowBoundaryOffset,\n isContainerDescendentOfBoundary,\n visualViewport\n );\n}\n\nexport function getRect(node: Element, ignoreScale: boolean) {\n let {top, left, width, height} = node.getBoundingClientRect();\n\n // Use offsetWidth and offsetHeight if this is an HTML element, so that\n // the size is not affected by scale transforms.\n if (ignoreScale && node instanceof node.ownerDocument.defaultView!.HTMLElement) {\n width = node.offsetWidth;\n height = node.offsetHeight;\n }\n\n return {top, left, width, height};\n}\n\nfunction getOffset(\n node: Element,\n ignoreScale: boolean,\n overrideRect?: Offset | null | undefined\n): Offset {\n let {top, left, width, height} = overrideRect || getRect(node, ignoreScale);\n let {scrollTop, scrollLeft, clientTop, clientLeft} = document.documentElement;\n return {\n top: top + scrollTop - clientTop,\n left: left + scrollLeft - clientLeft,\n width,\n height\n };\n}\n\nfunction getPosition(\n node: Element,\n parent: Element,\n ignoreScale: boolean,\n overrideRect?: Offset | null | undefined\n): Offset {\n let style = window.getComputedStyle(node);\n let offset: Offset;\n if (style.position === 'fixed') {\n offset = overrideRect || getRect(node, ignoreScale);\n } else {\n offset = getOffset(node, ignoreScale, overrideRect);\n let parentOffset = getOffset(parent, ignoreScale);\n let parentStyle = window.getComputedStyle(parent);\n parentOffset.top += (parseInt(parentStyle.borderTopWidth, 10) || 0) - parent.scrollTop;\n parentOffset.left += (parseInt(parentStyle.borderLeftWidth, 10) || 0) - parent.scrollLeft;\n offset.top -= parentOffset.top;\n offset.left -= parentOffset.left;\n }\n\n offset.top -= parseInt(style.marginTop, 10) || 0;\n offset.left -= parseInt(style.marginLeft, 10) || 0;\n return offset;\n}\n\n// Returns the containing block of an element, which is the element that\n// this element will be positioned relative to.\n// https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block\nfunction getContainingBlock(node: HTMLElement): Element {\n // The offsetParent of an element in most cases equals the containing block.\n // https://w3c.github.io/csswg-drafts/cssom-view/#dom-htmlelement-offsetparent\n let offsetParent = node.offsetParent;\n\n // The offsetParent algorithm terminates at the document body,\n // even if the body is not a containing block. Double check that\n // and use the documentElement if so.\n if (\n offsetParent &&\n offsetParent === document.body &&\n window.getComputedStyle(offsetParent).position === 'static' &&\n !isContainingBlock(offsetParent)\n ) {\n offsetParent = document.documentElement;\n }\n\n // TODO(later): handle table elements?\n\n // The offsetParent can be null if the element has position: fixed, or a few other cases.\n // We have to walk up the tree manually in this case because fixed positioned elements\n // are still positioned relative to their containing block, which is not always the viewport.\n if (offsetParent == null) {\n offsetParent = node.parentElement;\n while (offsetParent && !isContainingBlock(offsetParent)) {\n offsetParent = offsetParent.parentElement;\n }\n }\n\n // Fall back to the viewport.\n return offsetParent || document.documentElement;\n}\n\n// https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block\nfunction isContainingBlock(node: Element): boolean {\n let style = window.getComputedStyle(node);\n return (\n style.transform !== 'none' ||\n /transform|perspective/.test(style.willChange) ||\n style.filter !== 'none' ||\n style.contain === 'paint' ||\n ('backdropFilter' in style && style.backdropFilter !== 'none') ||\n ('WebkitBackdropFilter' in style && style.WebkitBackdropFilter !== 'none')\n );\n}\n"],"names":[],"version":3,"file":"calculatePosition.mjs.map"}
@@ -32,7 +32,7 @@ $parcel$export(module.exports, "useOverlayPosition", function () { return $9b275
32
32
  let $9b27591aafdd7244$var$visualViewport = typeof document !== 'undefined' ? window.visualViewport : null;
33
33
  function $9b27591aafdd7244$export$d39e1813b3bdd0e1(props) {
34
34
  let { direction: direction } = (0, $2522e612fa919664$exports.useLocale)();
35
- let { arrowSize: arrowSize, targetRef: targetRef, overlayRef: overlayRef, arrowRef: arrowRef, scrollRef: scrollRef = overlayRef, placement: placement = 'bottom', containerPadding: containerPadding = 12, shouldFlip: shouldFlip = true, boundaryElement: boundaryElement = typeof document !== 'undefined' ? document.body : null, offset: offset = 0, crossOffset: crossOffset = 0, shouldUpdatePosition: shouldUpdatePosition = true, isOpen: isOpen = true, onClose: onClose, maxHeight: maxHeight, arrowBoundaryOffset: arrowBoundaryOffset = 0 } = props;
35
+ let { arrowSize: arrowSize, targetRef: targetRef, overlayRef: overlayRef, arrowRef: arrowRef, scrollRef: scrollRef = overlayRef, placement: placement = 'bottom', containerPadding: containerPadding = 12, shouldFlip: shouldFlip = true, boundaryElement: boundaryElement = typeof document !== 'undefined' ? document.body : null, offset: offset = 0, crossOffset: crossOffset = 0, shouldUpdatePosition: shouldUpdatePosition = true, isOpen: isOpen = true, onClose: onClose, maxHeight: maxHeight, arrowBoundaryOffset: arrowBoundaryOffset = 0, getTargetRect: getTargetRect } = props;
36
36
  let [position, setPosition] = (0, $kA7qX$react.useState)(null);
37
37
  let deps = [
38
38
  shouldUpdatePosition,
@@ -103,7 +103,8 @@ function $9b27591aafdd7244$export$d39e1813b3bdd0e1(props) {
103
103
  crossOffset: crossOffset,
104
104
  maxHeight: maxHeight,
105
105
  arrowSize: arrowSize ?? (arrowRef?.current ? (0, $43b053bcc899501d$exports.getRect)(arrowRef.current, true).width : 0),
106
- arrowBoundaryOffset: arrowBoundaryOffset
106
+ arrowBoundaryOffset: arrowBoundaryOffset,
107
+ targetRect: getTargetRect?.(targetRef.current)
107
108
  });
108
109
  if (!position.position) return;
109
110
  // Modify overlay styles directly so positioning happens immediately without the need of a second render
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/react-aria/src/overlays/useOverlayPosition.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {calculatePosition, getRect, PositionResult} from './calculatePosition';\nimport {DOMAttributes, RefObject} from '@react-types/shared';\nimport {getActiveElement, isFocusWithin} from '../utils/shadowdom/DOMFunctions';\nimport {useCallback, useEffect, useRef, useState} from 'react';\nimport {useCloseOnScroll} from './useCloseOnScroll';\nimport {useLayoutEffect} from '../utils/useLayoutEffect';\nimport {useLocale} from '../i18n/I18nProvider';\nimport {useResizeObserver} from '../utils/useResizeObserver';\n\nexport type Placement =\n | 'bottom'\n | 'bottom left'\n | 'bottom right'\n | 'bottom start'\n | 'bottom end'\n | 'top'\n | 'top left'\n | 'top right'\n | 'top start'\n | 'top end'\n | 'left'\n | 'left top'\n | 'left bottom'\n | 'start'\n | 'start top'\n | 'start bottom'\n | 'right'\n | 'right top'\n | 'right bottom'\n | 'end'\n | 'end top'\n | 'end bottom';\n\nexport type Axis = 'top' | 'bottom' | 'left' | 'right';\nexport type SizeAxis = 'width' | 'height';\nexport type PlacementAxis = Axis | 'center';\n\nexport interface PositionProps {\n /**\n * The placement of the element with respect to its anchor element.\n *\n * @default 'bottom'\n */\n placement?: Placement;\n /**\n * The placement padding that should be applied between the element and its\n * surrounding container.\n *\n * @default 12\n */\n containerPadding?: number;\n /**\n * The additional offset applied along the main axis between the element and its\n * anchor element.\n *\n * @default 0\n */\n offset?: number;\n /**\n * The additional offset applied along the cross axis between the element and its\n * anchor element.\n *\n * @default 0\n */\n crossOffset?: number;\n /**\n * Whether the element should flip its orientation (e.g. top to bottom or left to right) when\n * there is insufficient room for it to render completely.\n *\n * @default true\n */\n shouldFlip?: boolean;\n // /**\n // * The element that should be used as the bounding container when calculating container offset\n // * or whether it should flip.\n // */\n // boundaryElement?: Element,\n /** Whether the element is rendered. */\n isOpen?: boolean;\n}\n\nexport interface AriaPositionProps extends PositionProps {\n /**\n * Cross size of the overlay arrow in pixels.\n *\n * @default 0\n */\n arrowSize?: number;\n /**\n * Element that that serves as the positioning boundary.\n *\n * @default document.body\n */\n boundaryElement?: Element;\n /**\n * The ref for the element which the overlay positions itself with respect to.\n */\n targetRef: RefObject<Element | null>;\n /**\n * The ref for the overlay element.\n */\n overlayRef: RefObject<Element | null>;\n /**\n * The ref for the arrow element.\n */\n arrowRef?: RefObject<Element | null>;\n /**\n * A ref for the scrollable region within the overlay.\n *\n * @default overlayRef\n */\n scrollRef?: RefObject<Element | null>;\n /**\n * Whether the overlay should update its position automatically.\n *\n * @default true\n */\n shouldUpdatePosition?: boolean;\n /** Handler that is called when the overlay should close. */\n onClose?: (() => void) | null;\n /**\n * The maxHeight specified for the overlay element.\n * By default, it will take all space up to the current viewport height.\n */\n maxHeight?: number;\n /**\n * The minimum distance the arrow's edge should be from the edge of the overlay element.\n *\n * @default 0\n */\n arrowBoundaryOffset?: number;\n}\n\nexport interface PositionAria {\n /** Props for the overlay container element. */\n overlayProps: DOMAttributes;\n /** Props for the overlay tip arrow if any. */\n arrowProps: DOMAttributes;\n /** Placement of the overlay with respect to the overlay trigger. */\n placement: PlacementAxis | null;\n /** The origin of the target in the overlay's coordinate system. Useful for animations. */\n triggerAnchorPoint: {x: number; y: number} | null;\n /** Updates the position of the overlay. */\n updatePosition(): void;\n}\n\ninterface ScrollAnchor {\n type: 'top' | 'bottom';\n offset: number;\n}\n\nlet visualViewport = typeof document !== 'undefined' ? window.visualViewport : null;\n\n/**\n * Handles positioning overlays like popovers and menus relative to a trigger\n * element, and updating the position when the window resizes.\n */\nexport function useOverlayPosition(props: AriaPositionProps): PositionAria {\n let {direction} = useLocale();\n let {\n arrowSize,\n targetRef,\n overlayRef,\n arrowRef,\n scrollRef = overlayRef,\n placement = 'bottom' as Placement,\n containerPadding = 12,\n shouldFlip = true,\n boundaryElement = typeof document !== 'undefined' ? document.body : null,\n offset = 0,\n crossOffset = 0,\n shouldUpdatePosition = true,\n isOpen = true,\n onClose,\n maxHeight,\n arrowBoundaryOffset = 0\n } = props;\n let [position, setPosition] = useState<PositionResult | null>(null);\n\n let deps = [\n shouldUpdatePosition,\n placement,\n overlayRef.current,\n targetRef.current,\n arrowRef?.current,\n scrollRef.current,\n containerPadding,\n shouldFlip,\n boundaryElement,\n offset,\n crossOffset,\n isOpen,\n direction,\n maxHeight,\n arrowBoundaryOffset,\n arrowSize\n ];\n\n // Note, the position freezing breaks if body sizes itself dynamicly with the visual viewport but that might\n // just be a non-realistic use case\n // Upon opening a overlay, record the current visual viewport scale so we can freeze the overlay styles\n let lastScale = useRef(visualViewport?.scale);\n useEffect(() => {\n if (isOpen) {\n lastScale.current = visualViewport?.scale;\n }\n }, [isOpen]);\n\n let updatePosition = useCallback(() => {\n if (\n shouldUpdatePosition === false ||\n !isOpen ||\n !overlayRef.current ||\n !targetRef.current ||\n !boundaryElement\n ) {\n return;\n }\n\n if (visualViewport?.scale !== lastScale.current) {\n return;\n }\n\n // Determine a scroll anchor based on the focused element.\n // This stores the offset of the anchor element from the scroll container\n // so it can be restored after repositioning. This way if the overlay height\n // changes, the focused element appears to stay in the same position.\n let anchor: ScrollAnchor | null = null;\n if (scrollRef.current && isFocusWithin(scrollRef.current)) {\n let anchorRect = getActiveElement()?.getBoundingClientRect();\n let scrollRect = scrollRef.current.getBoundingClientRect();\n // Anchor from the top if the offset is in the top half of the scrollable element,\n // otherwise anchor from the bottom.\n anchor = {\n type: 'top',\n offset: (anchorRect?.top ?? 0) - scrollRect.top\n };\n if (anchor.offset > scrollRect.height / 2) {\n anchor.type = 'bottom';\n anchor.offset = (anchorRect?.bottom ?? 0) - scrollRect.bottom;\n }\n }\n\n // Always reset the overlay's previous max height if not defined by the user so that we can compensate for\n // RAC collections populating after a second render and properly set a correct max height + positioning when it populates.\n let overlay = overlayRef.current as HTMLElement;\n if (!maxHeight && overlayRef.current) {\n overlay.style.top = '0px';\n overlay.style.bottom = '';\n overlay.style.maxHeight = (window.visualViewport?.height ?? window.innerHeight) + 'px';\n }\n\n let position = calculatePosition({\n placement: translateRTL(placement, direction),\n overlayNode: overlayRef.current,\n targetNode: targetRef.current,\n scrollNode: scrollRef.current || overlayRef.current,\n padding: containerPadding,\n shouldFlip,\n boundaryElement,\n offset,\n crossOffset,\n maxHeight,\n arrowSize: arrowSize ?? (arrowRef?.current ? getRect(arrowRef.current, true).width : 0),\n arrowBoundaryOffset\n });\n\n if (!position.position) {\n return;\n }\n\n // Modify overlay styles directly so positioning happens immediately without the need of a second render\n // This is so we don't have to delay autoFocus scrolling or delay applying preventScroll for popovers\n overlay.style.top = '';\n overlay.style.bottom = '';\n overlay.style.left = '';\n overlay.style.right = '';\n\n Object.keys(position.position).forEach(\n key => (overlay.style[key] = position.position![key] + 'px')\n );\n overlay.style.maxHeight = position.maxHeight != null ? position.maxHeight + 'px' : '';\n\n // Restore scroll position relative to anchor element.\n let activeElement = getActiveElement();\n if (anchor && activeElement && scrollRef.current) {\n let anchorRect = activeElement.getBoundingClientRect();\n let scrollRect = scrollRef.current.getBoundingClientRect();\n let newOffset = anchorRect[anchor.type] - scrollRect[anchor.type];\n scrollRef.current.scrollTop += newOffset - anchor.offset;\n }\n\n // Trigger a set state for a second render anyway for arrow positioning\n setPosition(position);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, deps);\n\n // Update position when anything changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useLayoutEffect(updatePosition, deps);\n\n // Update position on window resize\n useResize(updatePosition);\n\n // Update position when the overlay changes size (might need to flip).\n useResizeObserver({\n ref: overlayRef,\n onResize: updatePosition\n });\n\n // Update position when the target changes size (might need to flip).\n useResizeObserver({\n ref: targetRef,\n onResize: updatePosition\n });\n\n // Reposition the overlay and do not close on scroll while the visual viewport is resizing.\n // This will ensure that overlays adjust their positioning when the iOS virtual keyboard appears.\n let isResizing = useRef(false);\n useLayoutEffect(() => {\n let timeout: ReturnType<typeof setTimeout>;\n let onResize = () => {\n isResizing.current = true;\n clearTimeout(timeout);\n\n timeout = setTimeout(() => {\n isResizing.current = false;\n }, 500);\n\n updatePosition();\n };\n\n // Only reposition the overlay if a scroll event happens immediately as a result of resize (aka the virtual keyboard has appears)\n // We don't want to reposition the overlay if the user has pinch zoomed in and is scrolling the viewport around.\n let onScroll = () => {\n if (isResizing.current) {\n onResize();\n }\n };\n\n visualViewport?.addEventListener('resize', onResize);\n visualViewport?.addEventListener('scroll', onScroll);\n return () => {\n visualViewport?.removeEventListener('resize', onResize);\n visualViewport?.removeEventListener('scroll', onScroll);\n };\n }, [updatePosition]);\n\n let close = useCallback(() => {\n if (!isResizing.current) {\n onClose?.();\n }\n }, [onClose, isResizing]);\n\n // When scrolling a parent scrollable region of the trigger (other than the body),\n // we hide the popover. Otherwise, its position would be incorrect.\n useCloseOnScroll({\n triggerRef: targetRef,\n isOpen,\n onClose: onClose && close\n });\n\n return {\n overlayProps: {\n style: {\n position: position ? 'absolute' : 'fixed',\n top: !position ? 0 : undefined,\n left: !position ? 0 : undefined,\n zIndex: 100000, // should match the z-index in ModalTrigger\n ...position?.position,\n maxHeight: position?.maxHeight ?? '100vh'\n }\n },\n placement: position?.placement ?? null,\n triggerAnchorPoint: position?.triggerAnchorPoint ?? null,\n arrowProps: {\n 'aria-hidden': 'true',\n role: 'presentation',\n style: {\n left: position?.arrowOffsetLeft,\n top: position?.arrowOffsetTop\n }\n },\n updatePosition\n };\n}\n\nfunction useResize(onResize) {\n useLayoutEffect(() => {\n window.addEventListener('resize', onResize, false);\n return () => {\n window.removeEventListener('resize', onResize, false);\n };\n }, [onResize]);\n}\n\nfunction translateRTL(position, direction) {\n if (direction === 'rtl') {\n return position.replace('start', 'right').replace('end', 'left');\n }\n return position.replace('start', 'left').replace('end', 'right');\n}\n"],"names":[],"version":3,"file":"useOverlayPosition.cjs.map"}
1
+ {"mappings":"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","sources":["packages/react-aria/src/overlays/useOverlayPosition.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {calculatePosition, getRect, PositionResult} from './calculatePosition';\nimport {DOMAttributes, RefObject} from '@react-types/shared';\nimport {getActiveElement, isFocusWithin} from '../utils/shadowdom/DOMFunctions';\nimport {useCallback, useEffect, useRef, useState} from 'react';\nimport {useCloseOnScroll} from './useCloseOnScroll';\nimport {useLayoutEffect} from '../utils/useLayoutEffect';\nimport {useLocale} from '../i18n/I18nProvider';\nimport {useResizeObserver} from '../utils/useResizeObserver';\n\nexport type Placement =\n | 'bottom'\n | 'bottom left'\n | 'bottom right'\n | 'bottom start'\n | 'bottom end'\n | 'top'\n | 'top left'\n | 'top right'\n | 'top start'\n | 'top end'\n | 'left'\n | 'left top'\n | 'left bottom'\n | 'start'\n | 'start top'\n | 'start bottom'\n | 'right'\n | 'right top'\n | 'right bottom'\n | 'end'\n | 'end top'\n | 'end bottom';\n\nexport type Axis = 'top' | 'bottom' | 'left' | 'right';\nexport type SizeAxis = 'width' | 'height';\nexport type PlacementAxis = Axis | 'center';\n\nexport interface PositionProps {\n /**\n * The placement of the element with respect to its anchor element.\n *\n * @default 'bottom'\n */\n placement?: Placement;\n /**\n * The placement padding that should be applied between the element and its\n * surrounding container.\n *\n * @default 12\n */\n containerPadding?: number;\n /**\n * The additional offset applied along the main axis between the element and its\n * anchor element.\n *\n * @default 0\n */\n offset?: number;\n /**\n * The additional offset applied along the cross axis between the element and its\n * anchor element.\n *\n * @default 0\n */\n crossOffset?: number;\n /**\n * Whether the element should flip its orientation (e.g. top to bottom or left to right) when\n * there is insufficient room for it to render completely.\n *\n * @default true\n */\n shouldFlip?: boolean;\n // /**\n // * The element that should be used as the bounding container when calculating container offset\n // * or whether it should flip.\n // */\n // boundaryElement?: Element,\n /** Whether the element is rendered. */\n isOpen?: boolean;\n}\n\nexport interface AriaPositionProps extends PositionProps {\n /**\n * Cross size of the overlay arrow in pixels.\n *\n * @default 0\n */\n arrowSize?: number;\n /**\n * Element that that serves as the positioning boundary.\n *\n * @default document.body\n */\n boundaryElement?: Element;\n /**\n * The ref for the element which the overlay positions itself with respect to.\n */\n targetRef: RefObject<Element | null>;\n /**\n * The ref for the overlay element.\n */\n overlayRef: RefObject<Element | null>;\n /**\n * The ref for the arrow element.\n */\n arrowRef?: RefObject<Element | null>;\n /**\n * A ref for the scrollable region within the overlay.\n *\n * @default overlayRef\n */\n scrollRef?: RefObject<Element | null>;\n /**\n * Whether the overlay should update its position automatically.\n *\n * @default true\n */\n shouldUpdatePosition?: boolean;\n /** Handler that is called when the overlay should close. */\n onClose?: (() => void) | null;\n /**\n * The maxHeight specified for the overlay element.\n * By default, it will take all space up to the current viewport height.\n */\n maxHeight?: number;\n /**\n * The minimum distance the arrow's edge should be from the edge of the overlay element.\n *\n * @default 0\n */\n arrowBoundaryOffset?: number;\n /**\n * Overrides the target element's bounding rectangle. Useful for positioning relative to\n * a specific point such as the mouse cursor (e.g. context menus) or text selection.\n *\n * @default target.getBoundingClientRect()\n * @param target - The target element.\n */\n getTargetRect?: (target: Element) => DOMRect | null | undefined;\n}\n\nexport interface PositionAria {\n /** Props for the overlay container element. */\n overlayProps: DOMAttributes;\n /** Props for the overlay tip arrow if any. */\n arrowProps: DOMAttributes;\n /** Placement of the overlay with respect to the overlay trigger. */\n placement: PlacementAxis | null;\n /** The origin of the target in the overlay's coordinate system. Useful for animations. */\n triggerAnchorPoint: {x: number; y: number} | null;\n /** Updates the position of the overlay. */\n updatePosition(): void;\n}\n\ninterface ScrollAnchor {\n type: 'top' | 'bottom';\n offset: number;\n}\n\nlet visualViewport = typeof document !== 'undefined' ? window.visualViewport : null;\n\n/**\n * Handles positioning overlays like popovers and menus relative to a trigger\n * element, and updating the position when the window resizes.\n */\nexport function useOverlayPosition(props: AriaPositionProps): PositionAria {\n let {direction} = useLocale();\n let {\n arrowSize,\n targetRef,\n overlayRef,\n arrowRef,\n scrollRef = overlayRef,\n placement = 'bottom' as Placement,\n containerPadding = 12,\n shouldFlip = true,\n boundaryElement = typeof document !== 'undefined' ? document.body : null,\n offset = 0,\n crossOffset = 0,\n shouldUpdatePosition = true,\n isOpen = true,\n onClose,\n maxHeight,\n arrowBoundaryOffset = 0,\n getTargetRect\n } = props;\n let [position, setPosition] = useState<PositionResult | null>(null);\n\n let deps = [\n shouldUpdatePosition,\n placement,\n overlayRef.current,\n targetRef.current,\n arrowRef?.current,\n scrollRef.current,\n containerPadding,\n shouldFlip,\n boundaryElement,\n offset,\n crossOffset,\n isOpen,\n direction,\n maxHeight,\n arrowBoundaryOffset,\n arrowSize\n ];\n\n // Note, the position freezing breaks if body sizes itself dynamicly with the visual viewport but that might\n // just be a non-realistic use case\n // Upon opening a overlay, record the current visual viewport scale so we can freeze the overlay styles\n let lastScale = useRef(visualViewport?.scale);\n useEffect(() => {\n if (isOpen) {\n lastScale.current = visualViewport?.scale;\n }\n }, [isOpen]);\n\n let updatePosition = useCallback(() => {\n if (\n shouldUpdatePosition === false ||\n !isOpen ||\n !overlayRef.current ||\n !targetRef.current ||\n !boundaryElement\n ) {\n return;\n }\n\n if (visualViewport?.scale !== lastScale.current) {\n return;\n }\n\n // Determine a scroll anchor based on the focused element.\n // This stores the offset of the anchor element from the scroll container\n // so it can be restored after repositioning. This way if the overlay height\n // changes, the focused element appears to stay in the same position.\n let anchor: ScrollAnchor | null = null;\n if (scrollRef.current && isFocusWithin(scrollRef.current)) {\n let anchorRect = getActiveElement()?.getBoundingClientRect();\n let scrollRect = scrollRef.current.getBoundingClientRect();\n // Anchor from the top if the offset is in the top half of the scrollable element,\n // otherwise anchor from the bottom.\n anchor = {\n type: 'top',\n offset: (anchorRect?.top ?? 0) - scrollRect.top\n };\n if (anchor.offset > scrollRect.height / 2) {\n anchor.type = 'bottom';\n anchor.offset = (anchorRect?.bottom ?? 0) - scrollRect.bottom;\n }\n }\n\n // Always reset the overlay's previous max height if not defined by the user so that we can compensate for\n // RAC collections populating after a second render and properly set a correct max height + positioning when it populates.\n let overlay = overlayRef.current as HTMLElement;\n if (!maxHeight && overlayRef.current) {\n overlay.style.top = '0px';\n overlay.style.bottom = '';\n overlay.style.maxHeight = (window.visualViewport?.height ?? window.innerHeight) + 'px';\n }\n\n let position = calculatePosition({\n placement: translateRTL(placement, direction),\n overlayNode: overlayRef.current,\n targetNode: targetRef.current,\n scrollNode: scrollRef.current || overlayRef.current,\n padding: containerPadding,\n shouldFlip,\n boundaryElement,\n offset,\n crossOffset,\n maxHeight,\n arrowSize: arrowSize ?? (arrowRef?.current ? getRect(arrowRef.current, true).width : 0),\n arrowBoundaryOffset,\n targetRect: getTargetRect?.(targetRef.current)\n });\n\n if (!position.position) {\n return;\n }\n\n // Modify overlay styles directly so positioning happens immediately without the need of a second render\n // This is so we don't have to delay autoFocus scrolling or delay applying preventScroll for popovers\n overlay.style.top = '';\n overlay.style.bottom = '';\n overlay.style.left = '';\n overlay.style.right = '';\n\n Object.keys(position.position).forEach(\n key => (overlay.style[key] = position.position![key] + 'px')\n );\n overlay.style.maxHeight = position.maxHeight != null ? position.maxHeight + 'px' : '';\n\n // Restore scroll position relative to anchor element.\n let activeElement = getActiveElement();\n if (anchor && activeElement && scrollRef.current) {\n let anchorRect = activeElement.getBoundingClientRect();\n let scrollRect = scrollRef.current.getBoundingClientRect();\n let newOffset = anchorRect[anchor.type] - scrollRect[anchor.type];\n scrollRef.current.scrollTop += newOffset - anchor.offset;\n }\n\n // Trigger a set state for a second render anyway for arrow positioning\n setPosition(position);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, deps);\n\n // Update position when anything changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useLayoutEffect(updatePosition, deps);\n\n // Update position on window resize\n useResize(updatePosition);\n\n // Update position when the overlay changes size (might need to flip).\n useResizeObserver({\n ref: overlayRef,\n onResize: updatePosition\n });\n\n // Update position when the target changes size (might need to flip).\n useResizeObserver({\n ref: targetRef,\n onResize: updatePosition\n });\n\n // Reposition the overlay and do not close on scroll while the visual viewport is resizing.\n // This will ensure that overlays adjust their positioning when the iOS virtual keyboard appears.\n let isResizing = useRef(false);\n useLayoutEffect(() => {\n let timeout: ReturnType<typeof setTimeout>;\n let onResize = () => {\n isResizing.current = true;\n clearTimeout(timeout);\n\n timeout = setTimeout(() => {\n isResizing.current = false;\n }, 500);\n\n updatePosition();\n };\n\n // Only reposition the overlay if a scroll event happens immediately as a result of resize (aka the virtual keyboard has appears)\n // We don't want to reposition the overlay if the user has pinch zoomed in and is scrolling the viewport around.\n let onScroll = () => {\n if (isResizing.current) {\n onResize();\n }\n };\n\n visualViewport?.addEventListener('resize', onResize);\n visualViewport?.addEventListener('scroll', onScroll);\n return () => {\n visualViewport?.removeEventListener('resize', onResize);\n visualViewport?.removeEventListener('scroll', onScroll);\n };\n }, [updatePosition]);\n\n let close = useCallback(() => {\n if (!isResizing.current) {\n onClose?.();\n }\n }, [onClose, isResizing]);\n\n // When scrolling a parent scrollable region of the trigger (other than the body),\n // we hide the popover. Otherwise, its position would be incorrect.\n useCloseOnScroll({\n triggerRef: targetRef,\n isOpen,\n onClose: onClose && close\n });\n\n return {\n overlayProps: {\n style: {\n position: position ? 'absolute' : 'fixed',\n top: !position ? 0 : undefined,\n left: !position ? 0 : undefined,\n zIndex: 100000, // should match the z-index in ModalTrigger\n ...position?.position,\n maxHeight: position?.maxHeight ?? '100vh'\n }\n },\n placement: position?.placement ?? null,\n triggerAnchorPoint: position?.triggerAnchorPoint ?? null,\n arrowProps: {\n 'aria-hidden': 'true',\n role: 'presentation',\n style: {\n left: position?.arrowOffsetLeft,\n top: position?.arrowOffsetTop\n }\n },\n updatePosition\n };\n}\n\nfunction useResize(onResize) {\n useLayoutEffect(() => {\n window.addEventListener('resize', onResize, false);\n return () => {\n window.removeEventListener('resize', onResize, false);\n };\n }, [onResize]);\n}\n\nfunction translateRTL(position, direction) {\n if (direction === 'rtl') {\n return position.replace('start', 'right').replace('end', 'left');\n }\n return position.replace('start', 'left').replace('end', 'right');\n}\n"],"names":[],"version":3,"file":"useOverlayPosition.cjs.map"}
@@ -26,7 +26,7 @@ import {useState as $dzWlW$useState, useRef as $dzWlW$useRef, useEffect as $dzWl
26
26
  let $e55325afa7851309$var$visualViewport = typeof document !== 'undefined' ? window.visualViewport : null;
27
27
  function $e55325afa7851309$export$d39e1813b3bdd0e1(props) {
28
28
  let { direction: direction } = (0, $4defb058003b3e05$export$43bb16f9c6d9e3f7)();
29
- let { arrowSize: arrowSize, targetRef: targetRef, overlayRef: overlayRef, arrowRef: arrowRef, scrollRef: scrollRef = overlayRef, placement: placement = 'bottom', containerPadding: containerPadding = 12, shouldFlip: shouldFlip = true, boundaryElement: boundaryElement = typeof document !== 'undefined' ? document.body : null, offset: offset = 0, crossOffset: crossOffset = 0, shouldUpdatePosition: shouldUpdatePosition = true, isOpen: isOpen = true, onClose: onClose, maxHeight: maxHeight, arrowBoundaryOffset: arrowBoundaryOffset = 0 } = props;
29
+ let { arrowSize: arrowSize, targetRef: targetRef, overlayRef: overlayRef, arrowRef: arrowRef, scrollRef: scrollRef = overlayRef, placement: placement = 'bottom', containerPadding: containerPadding = 12, shouldFlip: shouldFlip = true, boundaryElement: boundaryElement = typeof document !== 'undefined' ? document.body : null, offset: offset = 0, crossOffset: crossOffset = 0, shouldUpdatePosition: shouldUpdatePosition = true, isOpen: isOpen = true, onClose: onClose, maxHeight: maxHeight, arrowBoundaryOffset: arrowBoundaryOffset = 0, getTargetRect: getTargetRect } = props;
30
30
  let [position, setPosition] = (0, $dzWlW$useState)(null);
31
31
  let deps = [
32
32
  shouldUpdatePosition,
@@ -102,7 +102,8 @@ function $e55325afa7851309$export$d39e1813b3bdd0e1(props) {
102
102
  crossOffset: crossOffset,
103
103
  maxHeight: maxHeight,
104
104
  arrowSize: arrowSize !== null && arrowSize !== void 0 ? arrowSize : (arrowRef === null || arrowRef === void 0 ? void 0 : arrowRef.current) ? (0, $ba2991ee81d3897a$export$4b834cebd9e5cebe)(arrowRef.current, true).width : 0,
105
- arrowBoundaryOffset: arrowBoundaryOffset
105
+ arrowBoundaryOffset: arrowBoundaryOffset,
106
+ targetRect: getTargetRect === null || getTargetRect === void 0 ? void 0 : getTargetRect(targetRef.current)
106
107
  });
107
108
  if (!position.position) return;
108
109
  // Modify overlay styles directly so positioning happens immediately without the need of a second render
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/react-aria/src/overlays/useOverlayPosition.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {calculatePosition, getRect, PositionResult} from './calculatePosition';\nimport {DOMAttributes, RefObject} from '@react-types/shared';\nimport {getActiveElement, isFocusWithin} from '../utils/shadowdom/DOMFunctions';\nimport {useCallback, useEffect, useRef, useState} from 'react';\nimport {useCloseOnScroll} from './useCloseOnScroll';\nimport {useLayoutEffect} from '../utils/useLayoutEffect';\nimport {useLocale} from '../i18n/I18nProvider';\nimport {useResizeObserver} from '../utils/useResizeObserver';\n\nexport type Placement =\n | 'bottom'\n | 'bottom left'\n | 'bottom right'\n | 'bottom start'\n | 'bottom end'\n | 'top'\n | 'top left'\n | 'top right'\n | 'top start'\n | 'top end'\n | 'left'\n | 'left top'\n | 'left bottom'\n | 'start'\n | 'start top'\n | 'start bottom'\n | 'right'\n | 'right top'\n | 'right bottom'\n | 'end'\n | 'end top'\n | 'end bottom';\n\nexport type Axis = 'top' | 'bottom' | 'left' | 'right';\nexport type SizeAxis = 'width' | 'height';\nexport type PlacementAxis = Axis | 'center';\n\nexport interface PositionProps {\n /**\n * The placement of the element with respect to its anchor element.\n *\n * @default 'bottom'\n */\n placement?: Placement;\n /**\n * The placement padding that should be applied between the element and its\n * surrounding container.\n *\n * @default 12\n */\n containerPadding?: number;\n /**\n * The additional offset applied along the main axis between the element and its\n * anchor element.\n *\n * @default 0\n */\n offset?: number;\n /**\n * The additional offset applied along the cross axis between the element and its\n * anchor element.\n *\n * @default 0\n */\n crossOffset?: number;\n /**\n * Whether the element should flip its orientation (e.g. top to bottom or left to right) when\n * there is insufficient room for it to render completely.\n *\n * @default true\n */\n shouldFlip?: boolean;\n // /**\n // * The element that should be used as the bounding container when calculating container offset\n // * or whether it should flip.\n // */\n // boundaryElement?: Element,\n /** Whether the element is rendered. */\n isOpen?: boolean;\n}\n\nexport interface AriaPositionProps extends PositionProps {\n /**\n * Cross size of the overlay arrow in pixels.\n *\n * @default 0\n */\n arrowSize?: number;\n /**\n * Element that that serves as the positioning boundary.\n *\n * @default document.body\n */\n boundaryElement?: Element;\n /**\n * The ref for the element which the overlay positions itself with respect to.\n */\n targetRef: RefObject<Element | null>;\n /**\n * The ref for the overlay element.\n */\n overlayRef: RefObject<Element | null>;\n /**\n * The ref for the arrow element.\n */\n arrowRef?: RefObject<Element | null>;\n /**\n * A ref for the scrollable region within the overlay.\n *\n * @default overlayRef\n */\n scrollRef?: RefObject<Element | null>;\n /**\n * Whether the overlay should update its position automatically.\n *\n * @default true\n */\n shouldUpdatePosition?: boolean;\n /** Handler that is called when the overlay should close. */\n onClose?: (() => void) | null;\n /**\n * The maxHeight specified for the overlay element.\n * By default, it will take all space up to the current viewport height.\n */\n maxHeight?: number;\n /**\n * The minimum distance the arrow's edge should be from the edge of the overlay element.\n *\n * @default 0\n */\n arrowBoundaryOffset?: number;\n}\n\nexport interface PositionAria {\n /** Props for the overlay container element. */\n overlayProps: DOMAttributes;\n /** Props for the overlay tip arrow if any. */\n arrowProps: DOMAttributes;\n /** Placement of the overlay with respect to the overlay trigger. */\n placement: PlacementAxis | null;\n /** The origin of the target in the overlay's coordinate system. Useful for animations. */\n triggerAnchorPoint: {x: number; y: number} | null;\n /** Updates the position of the overlay. */\n updatePosition(): void;\n}\n\ninterface ScrollAnchor {\n type: 'top' | 'bottom';\n offset: number;\n}\n\nlet visualViewport = typeof document !== 'undefined' ? window.visualViewport : null;\n\n/**\n * Handles positioning overlays like popovers and menus relative to a trigger\n * element, and updating the position when the window resizes.\n */\nexport function useOverlayPosition(props: AriaPositionProps): PositionAria {\n let {direction} = useLocale();\n let {\n arrowSize,\n targetRef,\n overlayRef,\n arrowRef,\n scrollRef = overlayRef,\n placement = 'bottom' as Placement,\n containerPadding = 12,\n shouldFlip = true,\n boundaryElement = typeof document !== 'undefined' ? document.body : null,\n offset = 0,\n crossOffset = 0,\n shouldUpdatePosition = true,\n isOpen = true,\n onClose,\n maxHeight,\n arrowBoundaryOffset = 0\n } = props;\n let [position, setPosition] = useState<PositionResult | null>(null);\n\n let deps = [\n shouldUpdatePosition,\n placement,\n overlayRef.current,\n targetRef.current,\n arrowRef?.current,\n scrollRef.current,\n containerPadding,\n shouldFlip,\n boundaryElement,\n offset,\n crossOffset,\n isOpen,\n direction,\n maxHeight,\n arrowBoundaryOffset,\n arrowSize\n ];\n\n // Note, the position freezing breaks if body sizes itself dynamicly with the visual viewport but that might\n // just be a non-realistic use case\n // Upon opening a overlay, record the current visual viewport scale so we can freeze the overlay styles\n let lastScale = useRef(visualViewport?.scale);\n useEffect(() => {\n if (isOpen) {\n lastScale.current = visualViewport?.scale;\n }\n }, [isOpen]);\n\n let updatePosition = useCallback(() => {\n if (\n shouldUpdatePosition === false ||\n !isOpen ||\n !overlayRef.current ||\n !targetRef.current ||\n !boundaryElement\n ) {\n return;\n }\n\n if (visualViewport?.scale !== lastScale.current) {\n return;\n }\n\n // Determine a scroll anchor based on the focused element.\n // This stores the offset of the anchor element from the scroll container\n // so it can be restored after repositioning. This way if the overlay height\n // changes, the focused element appears to stay in the same position.\n let anchor: ScrollAnchor | null = null;\n if (scrollRef.current && isFocusWithin(scrollRef.current)) {\n let anchorRect = getActiveElement()?.getBoundingClientRect();\n let scrollRect = scrollRef.current.getBoundingClientRect();\n // Anchor from the top if the offset is in the top half of the scrollable element,\n // otherwise anchor from the bottom.\n anchor = {\n type: 'top',\n offset: (anchorRect?.top ?? 0) - scrollRect.top\n };\n if (anchor.offset > scrollRect.height / 2) {\n anchor.type = 'bottom';\n anchor.offset = (anchorRect?.bottom ?? 0) - scrollRect.bottom;\n }\n }\n\n // Always reset the overlay's previous max height if not defined by the user so that we can compensate for\n // RAC collections populating after a second render and properly set a correct max height + positioning when it populates.\n let overlay = overlayRef.current as HTMLElement;\n if (!maxHeight && overlayRef.current) {\n overlay.style.top = '0px';\n overlay.style.bottom = '';\n overlay.style.maxHeight = (window.visualViewport?.height ?? window.innerHeight) + 'px';\n }\n\n let position = calculatePosition({\n placement: translateRTL(placement, direction),\n overlayNode: overlayRef.current,\n targetNode: targetRef.current,\n scrollNode: scrollRef.current || overlayRef.current,\n padding: containerPadding,\n shouldFlip,\n boundaryElement,\n offset,\n crossOffset,\n maxHeight,\n arrowSize: arrowSize ?? (arrowRef?.current ? getRect(arrowRef.current, true).width : 0),\n arrowBoundaryOffset\n });\n\n if (!position.position) {\n return;\n }\n\n // Modify overlay styles directly so positioning happens immediately without the need of a second render\n // This is so we don't have to delay autoFocus scrolling or delay applying preventScroll for popovers\n overlay.style.top = '';\n overlay.style.bottom = '';\n overlay.style.left = '';\n overlay.style.right = '';\n\n Object.keys(position.position).forEach(\n key => (overlay.style[key] = position.position![key] + 'px')\n );\n overlay.style.maxHeight = position.maxHeight != null ? position.maxHeight + 'px' : '';\n\n // Restore scroll position relative to anchor element.\n let activeElement = getActiveElement();\n if (anchor && activeElement && scrollRef.current) {\n let anchorRect = activeElement.getBoundingClientRect();\n let scrollRect = scrollRef.current.getBoundingClientRect();\n let newOffset = anchorRect[anchor.type] - scrollRect[anchor.type];\n scrollRef.current.scrollTop += newOffset - anchor.offset;\n }\n\n // Trigger a set state for a second render anyway for arrow positioning\n setPosition(position);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, deps);\n\n // Update position when anything changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useLayoutEffect(updatePosition, deps);\n\n // Update position on window resize\n useResize(updatePosition);\n\n // Update position when the overlay changes size (might need to flip).\n useResizeObserver({\n ref: overlayRef,\n onResize: updatePosition\n });\n\n // Update position when the target changes size (might need to flip).\n useResizeObserver({\n ref: targetRef,\n onResize: updatePosition\n });\n\n // Reposition the overlay and do not close on scroll while the visual viewport is resizing.\n // This will ensure that overlays adjust their positioning when the iOS virtual keyboard appears.\n let isResizing = useRef(false);\n useLayoutEffect(() => {\n let timeout: ReturnType<typeof setTimeout>;\n let onResize = () => {\n isResizing.current = true;\n clearTimeout(timeout);\n\n timeout = setTimeout(() => {\n isResizing.current = false;\n }, 500);\n\n updatePosition();\n };\n\n // Only reposition the overlay if a scroll event happens immediately as a result of resize (aka the virtual keyboard has appears)\n // We don't want to reposition the overlay if the user has pinch zoomed in and is scrolling the viewport around.\n let onScroll = () => {\n if (isResizing.current) {\n onResize();\n }\n };\n\n visualViewport?.addEventListener('resize', onResize);\n visualViewport?.addEventListener('scroll', onScroll);\n return () => {\n visualViewport?.removeEventListener('resize', onResize);\n visualViewport?.removeEventListener('scroll', onScroll);\n };\n }, [updatePosition]);\n\n let close = useCallback(() => {\n if (!isResizing.current) {\n onClose?.();\n }\n }, [onClose, isResizing]);\n\n // When scrolling a parent scrollable region of the trigger (other than the body),\n // we hide the popover. Otherwise, its position would be incorrect.\n useCloseOnScroll({\n triggerRef: targetRef,\n isOpen,\n onClose: onClose && close\n });\n\n return {\n overlayProps: {\n style: {\n position: position ? 'absolute' : 'fixed',\n top: !position ? 0 : undefined,\n left: !position ? 0 : undefined,\n zIndex: 100000, // should match the z-index in ModalTrigger\n ...position?.position,\n maxHeight: position?.maxHeight ?? '100vh'\n }\n },\n placement: position?.placement ?? null,\n triggerAnchorPoint: position?.triggerAnchorPoint ?? null,\n arrowProps: {\n 'aria-hidden': 'true',\n role: 'presentation',\n style: {\n left: position?.arrowOffsetLeft,\n top: position?.arrowOffsetTop\n }\n },\n updatePosition\n };\n}\n\nfunction useResize(onResize) {\n useLayoutEffect(() => {\n window.addEventListener('resize', onResize, false);\n return () => {\n window.removeEventListener('resize', onResize, false);\n };\n }, [onResize]);\n}\n\nfunction translateRTL(position, direction) {\n if (direction === 'rtl') {\n return position.replace('start', 'right').replace('end', 'left');\n }\n return position.replace('start', 'left').replace('end', 'right');\n}\n"],"names":[],"version":3,"file":"useOverlayPosition.js.map"}
1
+ {"mappings":"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","sources":["packages/react-aria/src/overlays/useOverlayPosition.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {calculatePosition, getRect, PositionResult} from './calculatePosition';\nimport {DOMAttributes, RefObject} from '@react-types/shared';\nimport {getActiveElement, isFocusWithin} from '../utils/shadowdom/DOMFunctions';\nimport {useCallback, useEffect, useRef, useState} from 'react';\nimport {useCloseOnScroll} from './useCloseOnScroll';\nimport {useLayoutEffect} from '../utils/useLayoutEffect';\nimport {useLocale} from '../i18n/I18nProvider';\nimport {useResizeObserver} from '../utils/useResizeObserver';\n\nexport type Placement =\n | 'bottom'\n | 'bottom left'\n | 'bottom right'\n | 'bottom start'\n | 'bottom end'\n | 'top'\n | 'top left'\n | 'top right'\n | 'top start'\n | 'top end'\n | 'left'\n | 'left top'\n | 'left bottom'\n | 'start'\n | 'start top'\n | 'start bottom'\n | 'right'\n | 'right top'\n | 'right bottom'\n | 'end'\n | 'end top'\n | 'end bottom';\n\nexport type Axis = 'top' | 'bottom' | 'left' | 'right';\nexport type SizeAxis = 'width' | 'height';\nexport type PlacementAxis = Axis | 'center';\n\nexport interface PositionProps {\n /**\n * The placement of the element with respect to its anchor element.\n *\n * @default 'bottom'\n */\n placement?: Placement;\n /**\n * The placement padding that should be applied between the element and its\n * surrounding container.\n *\n * @default 12\n */\n containerPadding?: number;\n /**\n * The additional offset applied along the main axis between the element and its\n * anchor element.\n *\n * @default 0\n */\n offset?: number;\n /**\n * The additional offset applied along the cross axis between the element and its\n * anchor element.\n *\n * @default 0\n */\n crossOffset?: number;\n /**\n * Whether the element should flip its orientation (e.g. top to bottom or left to right) when\n * there is insufficient room for it to render completely.\n *\n * @default true\n */\n shouldFlip?: boolean;\n // /**\n // * The element that should be used as the bounding container when calculating container offset\n // * or whether it should flip.\n // */\n // boundaryElement?: Element,\n /** Whether the element is rendered. */\n isOpen?: boolean;\n}\n\nexport interface AriaPositionProps extends PositionProps {\n /**\n * Cross size of the overlay arrow in pixels.\n *\n * @default 0\n */\n arrowSize?: number;\n /**\n * Element that that serves as the positioning boundary.\n *\n * @default document.body\n */\n boundaryElement?: Element;\n /**\n * The ref for the element which the overlay positions itself with respect to.\n */\n targetRef: RefObject<Element | null>;\n /**\n * The ref for the overlay element.\n */\n overlayRef: RefObject<Element | null>;\n /**\n * The ref for the arrow element.\n */\n arrowRef?: RefObject<Element | null>;\n /**\n * A ref for the scrollable region within the overlay.\n *\n * @default overlayRef\n */\n scrollRef?: RefObject<Element | null>;\n /**\n * Whether the overlay should update its position automatically.\n *\n * @default true\n */\n shouldUpdatePosition?: boolean;\n /** Handler that is called when the overlay should close. */\n onClose?: (() => void) | null;\n /**\n * The maxHeight specified for the overlay element.\n * By default, it will take all space up to the current viewport height.\n */\n maxHeight?: number;\n /**\n * The minimum distance the arrow's edge should be from the edge of the overlay element.\n *\n * @default 0\n */\n arrowBoundaryOffset?: number;\n /**\n * Overrides the target element's bounding rectangle. Useful for positioning relative to\n * a specific point such as the mouse cursor (e.g. context menus) or text selection.\n *\n * @default target.getBoundingClientRect()\n * @param target - The target element.\n */\n getTargetRect?: (target: Element) => DOMRect | null | undefined;\n}\n\nexport interface PositionAria {\n /** Props for the overlay container element. */\n overlayProps: DOMAttributes;\n /** Props for the overlay tip arrow if any. */\n arrowProps: DOMAttributes;\n /** Placement of the overlay with respect to the overlay trigger. */\n placement: PlacementAxis | null;\n /** The origin of the target in the overlay's coordinate system. Useful for animations. */\n triggerAnchorPoint: {x: number; y: number} | null;\n /** Updates the position of the overlay. */\n updatePosition(): void;\n}\n\ninterface ScrollAnchor {\n type: 'top' | 'bottom';\n offset: number;\n}\n\nlet visualViewport = typeof document !== 'undefined' ? window.visualViewport : null;\n\n/**\n * Handles positioning overlays like popovers and menus relative to a trigger\n * element, and updating the position when the window resizes.\n */\nexport function useOverlayPosition(props: AriaPositionProps): PositionAria {\n let {direction} = useLocale();\n let {\n arrowSize,\n targetRef,\n overlayRef,\n arrowRef,\n scrollRef = overlayRef,\n placement = 'bottom' as Placement,\n containerPadding = 12,\n shouldFlip = true,\n boundaryElement = typeof document !== 'undefined' ? document.body : null,\n offset = 0,\n crossOffset = 0,\n shouldUpdatePosition = true,\n isOpen = true,\n onClose,\n maxHeight,\n arrowBoundaryOffset = 0,\n getTargetRect\n } = props;\n let [position, setPosition] = useState<PositionResult | null>(null);\n\n let deps = [\n shouldUpdatePosition,\n placement,\n overlayRef.current,\n targetRef.current,\n arrowRef?.current,\n scrollRef.current,\n containerPadding,\n shouldFlip,\n boundaryElement,\n offset,\n crossOffset,\n isOpen,\n direction,\n maxHeight,\n arrowBoundaryOffset,\n arrowSize\n ];\n\n // Note, the position freezing breaks if body sizes itself dynamicly with the visual viewport but that might\n // just be a non-realistic use case\n // Upon opening a overlay, record the current visual viewport scale so we can freeze the overlay styles\n let lastScale = useRef(visualViewport?.scale);\n useEffect(() => {\n if (isOpen) {\n lastScale.current = visualViewport?.scale;\n }\n }, [isOpen]);\n\n let updatePosition = useCallback(() => {\n if (\n shouldUpdatePosition === false ||\n !isOpen ||\n !overlayRef.current ||\n !targetRef.current ||\n !boundaryElement\n ) {\n return;\n }\n\n if (visualViewport?.scale !== lastScale.current) {\n return;\n }\n\n // Determine a scroll anchor based on the focused element.\n // This stores the offset of the anchor element from the scroll container\n // so it can be restored after repositioning. This way if the overlay height\n // changes, the focused element appears to stay in the same position.\n let anchor: ScrollAnchor | null = null;\n if (scrollRef.current && isFocusWithin(scrollRef.current)) {\n let anchorRect = getActiveElement()?.getBoundingClientRect();\n let scrollRect = scrollRef.current.getBoundingClientRect();\n // Anchor from the top if the offset is in the top half of the scrollable element,\n // otherwise anchor from the bottom.\n anchor = {\n type: 'top',\n offset: (anchorRect?.top ?? 0) - scrollRect.top\n };\n if (anchor.offset > scrollRect.height / 2) {\n anchor.type = 'bottom';\n anchor.offset = (anchorRect?.bottom ?? 0) - scrollRect.bottom;\n }\n }\n\n // Always reset the overlay's previous max height if not defined by the user so that we can compensate for\n // RAC collections populating after a second render and properly set a correct max height + positioning when it populates.\n let overlay = overlayRef.current as HTMLElement;\n if (!maxHeight && overlayRef.current) {\n overlay.style.top = '0px';\n overlay.style.bottom = '';\n overlay.style.maxHeight = (window.visualViewport?.height ?? window.innerHeight) + 'px';\n }\n\n let position = calculatePosition({\n placement: translateRTL(placement, direction),\n overlayNode: overlayRef.current,\n targetNode: targetRef.current,\n scrollNode: scrollRef.current || overlayRef.current,\n padding: containerPadding,\n shouldFlip,\n boundaryElement,\n offset,\n crossOffset,\n maxHeight,\n arrowSize: arrowSize ?? (arrowRef?.current ? getRect(arrowRef.current, true).width : 0),\n arrowBoundaryOffset,\n targetRect: getTargetRect?.(targetRef.current)\n });\n\n if (!position.position) {\n return;\n }\n\n // Modify overlay styles directly so positioning happens immediately without the need of a second render\n // This is so we don't have to delay autoFocus scrolling or delay applying preventScroll for popovers\n overlay.style.top = '';\n overlay.style.bottom = '';\n overlay.style.left = '';\n overlay.style.right = '';\n\n Object.keys(position.position).forEach(\n key => (overlay.style[key] = position.position![key] + 'px')\n );\n overlay.style.maxHeight = position.maxHeight != null ? position.maxHeight + 'px' : '';\n\n // Restore scroll position relative to anchor element.\n let activeElement = getActiveElement();\n if (anchor && activeElement && scrollRef.current) {\n let anchorRect = activeElement.getBoundingClientRect();\n let scrollRect = scrollRef.current.getBoundingClientRect();\n let newOffset = anchorRect[anchor.type] - scrollRect[anchor.type];\n scrollRef.current.scrollTop += newOffset - anchor.offset;\n }\n\n // Trigger a set state for a second render anyway for arrow positioning\n setPosition(position);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, deps);\n\n // Update position when anything changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useLayoutEffect(updatePosition, deps);\n\n // Update position on window resize\n useResize(updatePosition);\n\n // Update position when the overlay changes size (might need to flip).\n useResizeObserver({\n ref: overlayRef,\n onResize: updatePosition\n });\n\n // Update position when the target changes size (might need to flip).\n useResizeObserver({\n ref: targetRef,\n onResize: updatePosition\n });\n\n // Reposition the overlay and do not close on scroll while the visual viewport is resizing.\n // This will ensure that overlays adjust their positioning when the iOS virtual keyboard appears.\n let isResizing = useRef(false);\n useLayoutEffect(() => {\n let timeout: ReturnType<typeof setTimeout>;\n let onResize = () => {\n isResizing.current = true;\n clearTimeout(timeout);\n\n timeout = setTimeout(() => {\n isResizing.current = false;\n }, 500);\n\n updatePosition();\n };\n\n // Only reposition the overlay if a scroll event happens immediately as a result of resize (aka the virtual keyboard has appears)\n // We don't want to reposition the overlay if the user has pinch zoomed in and is scrolling the viewport around.\n let onScroll = () => {\n if (isResizing.current) {\n onResize();\n }\n };\n\n visualViewport?.addEventListener('resize', onResize);\n visualViewport?.addEventListener('scroll', onScroll);\n return () => {\n visualViewport?.removeEventListener('resize', onResize);\n visualViewport?.removeEventListener('scroll', onScroll);\n };\n }, [updatePosition]);\n\n let close = useCallback(() => {\n if (!isResizing.current) {\n onClose?.();\n }\n }, [onClose, isResizing]);\n\n // When scrolling a parent scrollable region of the trigger (other than the body),\n // we hide the popover. Otherwise, its position would be incorrect.\n useCloseOnScroll({\n triggerRef: targetRef,\n isOpen,\n onClose: onClose && close\n });\n\n return {\n overlayProps: {\n style: {\n position: position ? 'absolute' : 'fixed',\n top: !position ? 0 : undefined,\n left: !position ? 0 : undefined,\n zIndex: 100000, // should match the z-index in ModalTrigger\n ...position?.position,\n maxHeight: position?.maxHeight ?? '100vh'\n }\n },\n placement: position?.placement ?? null,\n triggerAnchorPoint: position?.triggerAnchorPoint ?? null,\n arrowProps: {\n 'aria-hidden': 'true',\n role: 'presentation',\n style: {\n left: position?.arrowOffsetLeft,\n top: position?.arrowOffsetTop\n }\n },\n updatePosition\n };\n}\n\nfunction useResize(onResize) {\n useLayoutEffect(() => {\n window.addEventListener('resize', onResize, false);\n return () => {\n window.removeEventListener('resize', onResize, false);\n };\n }, [onResize]);\n}\n\nfunction translateRTL(position, direction) {\n if (direction === 'rtl') {\n return position.replace('start', 'right').replace('end', 'left');\n }\n return position.replace('start', 'left').replace('end', 'right');\n}\n"],"names":[],"version":3,"file":"useOverlayPosition.js.map"}
@@ -26,7 +26,7 @@ import {useState as $jKzS8$useState, useRef as $jKzS8$useRef, useEffect as $jKzS
26
26
  let $b3526bc71400be8d$var$visualViewport = typeof document !== 'undefined' ? window.visualViewport : null;
27
27
  function $b3526bc71400be8d$export$d39e1813b3bdd0e1(props) {
28
28
  let { direction: direction } = (0, $2eb8e6d23f3d0cb0$export$43bb16f9c6d9e3f7)();
29
- let { arrowSize: arrowSize, targetRef: targetRef, overlayRef: overlayRef, arrowRef: arrowRef, scrollRef: scrollRef = overlayRef, placement: placement = 'bottom', containerPadding: containerPadding = 12, shouldFlip: shouldFlip = true, boundaryElement: boundaryElement = typeof document !== 'undefined' ? document.body : null, offset: offset = 0, crossOffset: crossOffset = 0, shouldUpdatePosition: shouldUpdatePosition = true, isOpen: isOpen = true, onClose: onClose, maxHeight: maxHeight, arrowBoundaryOffset: arrowBoundaryOffset = 0 } = props;
29
+ let { arrowSize: arrowSize, targetRef: targetRef, overlayRef: overlayRef, arrowRef: arrowRef, scrollRef: scrollRef = overlayRef, placement: placement = 'bottom', containerPadding: containerPadding = 12, shouldFlip: shouldFlip = true, boundaryElement: boundaryElement = typeof document !== 'undefined' ? document.body : null, offset: offset = 0, crossOffset: crossOffset = 0, shouldUpdatePosition: shouldUpdatePosition = true, isOpen: isOpen = true, onClose: onClose, maxHeight: maxHeight, arrowBoundaryOffset: arrowBoundaryOffset = 0, getTargetRect: getTargetRect } = props;
30
30
  let [position, setPosition] = (0, $jKzS8$useState)(null);
31
31
  let deps = [
32
32
  shouldUpdatePosition,
@@ -97,7 +97,8 @@ function $b3526bc71400be8d$export$d39e1813b3bdd0e1(props) {
97
97
  crossOffset: crossOffset,
98
98
  maxHeight: maxHeight,
99
99
  arrowSize: arrowSize ?? (arrowRef?.current ? (0, $954926fb6168ae2a$export$4b834cebd9e5cebe)(arrowRef.current, true).width : 0),
100
- arrowBoundaryOffset: arrowBoundaryOffset
100
+ arrowBoundaryOffset: arrowBoundaryOffset,
101
+ targetRect: getTargetRect?.(targetRef.current)
101
102
  });
102
103
  if (!position.position) return;
103
104
  // Modify overlay styles directly so positioning happens immediately without the need of a second render
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/react-aria/src/overlays/useOverlayPosition.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {calculatePosition, getRect, PositionResult} from './calculatePosition';\nimport {DOMAttributes, RefObject} from '@react-types/shared';\nimport {getActiveElement, isFocusWithin} from '../utils/shadowdom/DOMFunctions';\nimport {useCallback, useEffect, useRef, useState} from 'react';\nimport {useCloseOnScroll} from './useCloseOnScroll';\nimport {useLayoutEffect} from '../utils/useLayoutEffect';\nimport {useLocale} from '../i18n/I18nProvider';\nimport {useResizeObserver} from '../utils/useResizeObserver';\n\nexport type Placement =\n | 'bottom'\n | 'bottom left'\n | 'bottom right'\n | 'bottom start'\n | 'bottom end'\n | 'top'\n | 'top left'\n | 'top right'\n | 'top start'\n | 'top end'\n | 'left'\n | 'left top'\n | 'left bottom'\n | 'start'\n | 'start top'\n | 'start bottom'\n | 'right'\n | 'right top'\n | 'right bottom'\n | 'end'\n | 'end top'\n | 'end bottom';\n\nexport type Axis = 'top' | 'bottom' | 'left' | 'right';\nexport type SizeAxis = 'width' | 'height';\nexport type PlacementAxis = Axis | 'center';\n\nexport interface PositionProps {\n /**\n * The placement of the element with respect to its anchor element.\n *\n * @default 'bottom'\n */\n placement?: Placement;\n /**\n * The placement padding that should be applied between the element and its\n * surrounding container.\n *\n * @default 12\n */\n containerPadding?: number;\n /**\n * The additional offset applied along the main axis between the element and its\n * anchor element.\n *\n * @default 0\n */\n offset?: number;\n /**\n * The additional offset applied along the cross axis between the element and its\n * anchor element.\n *\n * @default 0\n */\n crossOffset?: number;\n /**\n * Whether the element should flip its orientation (e.g. top to bottom or left to right) when\n * there is insufficient room for it to render completely.\n *\n * @default true\n */\n shouldFlip?: boolean;\n // /**\n // * The element that should be used as the bounding container when calculating container offset\n // * or whether it should flip.\n // */\n // boundaryElement?: Element,\n /** Whether the element is rendered. */\n isOpen?: boolean;\n}\n\nexport interface AriaPositionProps extends PositionProps {\n /**\n * Cross size of the overlay arrow in pixels.\n *\n * @default 0\n */\n arrowSize?: number;\n /**\n * Element that that serves as the positioning boundary.\n *\n * @default document.body\n */\n boundaryElement?: Element;\n /**\n * The ref for the element which the overlay positions itself with respect to.\n */\n targetRef: RefObject<Element | null>;\n /**\n * The ref for the overlay element.\n */\n overlayRef: RefObject<Element | null>;\n /**\n * The ref for the arrow element.\n */\n arrowRef?: RefObject<Element | null>;\n /**\n * A ref for the scrollable region within the overlay.\n *\n * @default overlayRef\n */\n scrollRef?: RefObject<Element | null>;\n /**\n * Whether the overlay should update its position automatically.\n *\n * @default true\n */\n shouldUpdatePosition?: boolean;\n /** Handler that is called when the overlay should close. */\n onClose?: (() => void) | null;\n /**\n * The maxHeight specified for the overlay element.\n * By default, it will take all space up to the current viewport height.\n */\n maxHeight?: number;\n /**\n * The minimum distance the arrow's edge should be from the edge of the overlay element.\n *\n * @default 0\n */\n arrowBoundaryOffset?: number;\n}\n\nexport interface PositionAria {\n /** Props for the overlay container element. */\n overlayProps: DOMAttributes;\n /** Props for the overlay tip arrow if any. */\n arrowProps: DOMAttributes;\n /** Placement of the overlay with respect to the overlay trigger. */\n placement: PlacementAxis | null;\n /** The origin of the target in the overlay's coordinate system. Useful for animations. */\n triggerAnchorPoint: {x: number; y: number} | null;\n /** Updates the position of the overlay. */\n updatePosition(): void;\n}\n\ninterface ScrollAnchor {\n type: 'top' | 'bottom';\n offset: number;\n}\n\nlet visualViewport = typeof document !== 'undefined' ? window.visualViewport : null;\n\n/**\n * Handles positioning overlays like popovers and menus relative to a trigger\n * element, and updating the position when the window resizes.\n */\nexport function useOverlayPosition(props: AriaPositionProps): PositionAria {\n let {direction} = useLocale();\n let {\n arrowSize,\n targetRef,\n overlayRef,\n arrowRef,\n scrollRef = overlayRef,\n placement = 'bottom' as Placement,\n containerPadding = 12,\n shouldFlip = true,\n boundaryElement = typeof document !== 'undefined' ? document.body : null,\n offset = 0,\n crossOffset = 0,\n shouldUpdatePosition = true,\n isOpen = true,\n onClose,\n maxHeight,\n arrowBoundaryOffset = 0\n } = props;\n let [position, setPosition] = useState<PositionResult | null>(null);\n\n let deps = [\n shouldUpdatePosition,\n placement,\n overlayRef.current,\n targetRef.current,\n arrowRef?.current,\n scrollRef.current,\n containerPadding,\n shouldFlip,\n boundaryElement,\n offset,\n crossOffset,\n isOpen,\n direction,\n maxHeight,\n arrowBoundaryOffset,\n arrowSize\n ];\n\n // Note, the position freezing breaks if body sizes itself dynamicly with the visual viewport but that might\n // just be a non-realistic use case\n // Upon opening a overlay, record the current visual viewport scale so we can freeze the overlay styles\n let lastScale = useRef(visualViewport?.scale);\n useEffect(() => {\n if (isOpen) {\n lastScale.current = visualViewport?.scale;\n }\n }, [isOpen]);\n\n let updatePosition = useCallback(() => {\n if (\n shouldUpdatePosition === false ||\n !isOpen ||\n !overlayRef.current ||\n !targetRef.current ||\n !boundaryElement\n ) {\n return;\n }\n\n if (visualViewport?.scale !== lastScale.current) {\n return;\n }\n\n // Determine a scroll anchor based on the focused element.\n // This stores the offset of the anchor element from the scroll container\n // so it can be restored after repositioning. This way if the overlay height\n // changes, the focused element appears to stay in the same position.\n let anchor: ScrollAnchor | null = null;\n if (scrollRef.current && isFocusWithin(scrollRef.current)) {\n let anchorRect = getActiveElement()?.getBoundingClientRect();\n let scrollRect = scrollRef.current.getBoundingClientRect();\n // Anchor from the top if the offset is in the top half of the scrollable element,\n // otherwise anchor from the bottom.\n anchor = {\n type: 'top',\n offset: (anchorRect?.top ?? 0) - scrollRect.top\n };\n if (anchor.offset > scrollRect.height / 2) {\n anchor.type = 'bottom';\n anchor.offset = (anchorRect?.bottom ?? 0) - scrollRect.bottom;\n }\n }\n\n // Always reset the overlay's previous max height if not defined by the user so that we can compensate for\n // RAC collections populating after a second render and properly set a correct max height + positioning when it populates.\n let overlay = overlayRef.current as HTMLElement;\n if (!maxHeight && overlayRef.current) {\n overlay.style.top = '0px';\n overlay.style.bottom = '';\n overlay.style.maxHeight = (window.visualViewport?.height ?? window.innerHeight) + 'px';\n }\n\n let position = calculatePosition({\n placement: translateRTL(placement, direction),\n overlayNode: overlayRef.current,\n targetNode: targetRef.current,\n scrollNode: scrollRef.current || overlayRef.current,\n padding: containerPadding,\n shouldFlip,\n boundaryElement,\n offset,\n crossOffset,\n maxHeight,\n arrowSize: arrowSize ?? (arrowRef?.current ? getRect(arrowRef.current, true).width : 0),\n arrowBoundaryOffset\n });\n\n if (!position.position) {\n return;\n }\n\n // Modify overlay styles directly so positioning happens immediately without the need of a second render\n // This is so we don't have to delay autoFocus scrolling or delay applying preventScroll for popovers\n overlay.style.top = '';\n overlay.style.bottom = '';\n overlay.style.left = '';\n overlay.style.right = '';\n\n Object.keys(position.position).forEach(\n key => (overlay.style[key] = position.position![key] + 'px')\n );\n overlay.style.maxHeight = position.maxHeight != null ? position.maxHeight + 'px' : '';\n\n // Restore scroll position relative to anchor element.\n let activeElement = getActiveElement();\n if (anchor && activeElement && scrollRef.current) {\n let anchorRect = activeElement.getBoundingClientRect();\n let scrollRect = scrollRef.current.getBoundingClientRect();\n let newOffset = anchorRect[anchor.type] - scrollRect[anchor.type];\n scrollRef.current.scrollTop += newOffset - anchor.offset;\n }\n\n // Trigger a set state for a second render anyway for arrow positioning\n setPosition(position);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, deps);\n\n // Update position when anything changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useLayoutEffect(updatePosition, deps);\n\n // Update position on window resize\n useResize(updatePosition);\n\n // Update position when the overlay changes size (might need to flip).\n useResizeObserver({\n ref: overlayRef,\n onResize: updatePosition\n });\n\n // Update position when the target changes size (might need to flip).\n useResizeObserver({\n ref: targetRef,\n onResize: updatePosition\n });\n\n // Reposition the overlay and do not close on scroll while the visual viewport is resizing.\n // This will ensure that overlays adjust their positioning when the iOS virtual keyboard appears.\n let isResizing = useRef(false);\n useLayoutEffect(() => {\n let timeout: ReturnType<typeof setTimeout>;\n let onResize = () => {\n isResizing.current = true;\n clearTimeout(timeout);\n\n timeout = setTimeout(() => {\n isResizing.current = false;\n }, 500);\n\n updatePosition();\n };\n\n // Only reposition the overlay if a scroll event happens immediately as a result of resize (aka the virtual keyboard has appears)\n // We don't want to reposition the overlay if the user has pinch zoomed in and is scrolling the viewport around.\n let onScroll = () => {\n if (isResizing.current) {\n onResize();\n }\n };\n\n visualViewport?.addEventListener('resize', onResize);\n visualViewport?.addEventListener('scroll', onScroll);\n return () => {\n visualViewport?.removeEventListener('resize', onResize);\n visualViewport?.removeEventListener('scroll', onScroll);\n };\n }, [updatePosition]);\n\n let close = useCallback(() => {\n if (!isResizing.current) {\n onClose?.();\n }\n }, [onClose, isResizing]);\n\n // When scrolling a parent scrollable region of the trigger (other than the body),\n // we hide the popover. Otherwise, its position would be incorrect.\n useCloseOnScroll({\n triggerRef: targetRef,\n isOpen,\n onClose: onClose && close\n });\n\n return {\n overlayProps: {\n style: {\n position: position ? 'absolute' : 'fixed',\n top: !position ? 0 : undefined,\n left: !position ? 0 : undefined,\n zIndex: 100000, // should match the z-index in ModalTrigger\n ...position?.position,\n maxHeight: position?.maxHeight ?? '100vh'\n }\n },\n placement: position?.placement ?? null,\n triggerAnchorPoint: position?.triggerAnchorPoint ?? null,\n arrowProps: {\n 'aria-hidden': 'true',\n role: 'presentation',\n style: {\n left: position?.arrowOffsetLeft,\n top: position?.arrowOffsetTop\n }\n },\n updatePosition\n };\n}\n\nfunction useResize(onResize) {\n useLayoutEffect(() => {\n window.addEventListener('resize', onResize, false);\n return () => {\n window.removeEventListener('resize', onResize, false);\n };\n }, [onResize]);\n}\n\nfunction translateRTL(position, direction) {\n if (direction === 'rtl') {\n return position.replace('start', 'right').replace('end', 'left');\n }\n return position.replace('start', 'left').replace('end', 'right');\n}\n"],"names":[],"version":3,"file":"useOverlayPosition.mjs.map"}
1
+ {"mappings":"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","sources":["packages/react-aria/src/overlays/useOverlayPosition.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {calculatePosition, getRect, PositionResult} from './calculatePosition';\nimport {DOMAttributes, RefObject} from '@react-types/shared';\nimport {getActiveElement, isFocusWithin} from '../utils/shadowdom/DOMFunctions';\nimport {useCallback, useEffect, useRef, useState} from 'react';\nimport {useCloseOnScroll} from './useCloseOnScroll';\nimport {useLayoutEffect} from '../utils/useLayoutEffect';\nimport {useLocale} from '../i18n/I18nProvider';\nimport {useResizeObserver} from '../utils/useResizeObserver';\n\nexport type Placement =\n | 'bottom'\n | 'bottom left'\n | 'bottom right'\n | 'bottom start'\n | 'bottom end'\n | 'top'\n | 'top left'\n | 'top right'\n | 'top start'\n | 'top end'\n | 'left'\n | 'left top'\n | 'left bottom'\n | 'start'\n | 'start top'\n | 'start bottom'\n | 'right'\n | 'right top'\n | 'right bottom'\n | 'end'\n | 'end top'\n | 'end bottom';\n\nexport type Axis = 'top' | 'bottom' | 'left' | 'right';\nexport type SizeAxis = 'width' | 'height';\nexport type PlacementAxis = Axis | 'center';\n\nexport interface PositionProps {\n /**\n * The placement of the element with respect to its anchor element.\n *\n * @default 'bottom'\n */\n placement?: Placement;\n /**\n * The placement padding that should be applied between the element and its\n * surrounding container.\n *\n * @default 12\n */\n containerPadding?: number;\n /**\n * The additional offset applied along the main axis between the element and its\n * anchor element.\n *\n * @default 0\n */\n offset?: number;\n /**\n * The additional offset applied along the cross axis between the element and its\n * anchor element.\n *\n * @default 0\n */\n crossOffset?: number;\n /**\n * Whether the element should flip its orientation (e.g. top to bottom or left to right) when\n * there is insufficient room for it to render completely.\n *\n * @default true\n */\n shouldFlip?: boolean;\n // /**\n // * The element that should be used as the bounding container when calculating container offset\n // * or whether it should flip.\n // */\n // boundaryElement?: Element,\n /** Whether the element is rendered. */\n isOpen?: boolean;\n}\n\nexport interface AriaPositionProps extends PositionProps {\n /**\n * Cross size of the overlay arrow in pixels.\n *\n * @default 0\n */\n arrowSize?: number;\n /**\n * Element that that serves as the positioning boundary.\n *\n * @default document.body\n */\n boundaryElement?: Element;\n /**\n * The ref for the element which the overlay positions itself with respect to.\n */\n targetRef: RefObject<Element | null>;\n /**\n * The ref for the overlay element.\n */\n overlayRef: RefObject<Element | null>;\n /**\n * The ref for the arrow element.\n */\n arrowRef?: RefObject<Element | null>;\n /**\n * A ref for the scrollable region within the overlay.\n *\n * @default overlayRef\n */\n scrollRef?: RefObject<Element | null>;\n /**\n * Whether the overlay should update its position automatically.\n *\n * @default true\n */\n shouldUpdatePosition?: boolean;\n /** Handler that is called when the overlay should close. */\n onClose?: (() => void) | null;\n /**\n * The maxHeight specified for the overlay element.\n * By default, it will take all space up to the current viewport height.\n */\n maxHeight?: number;\n /**\n * The minimum distance the arrow's edge should be from the edge of the overlay element.\n *\n * @default 0\n */\n arrowBoundaryOffset?: number;\n /**\n * Overrides the target element's bounding rectangle. Useful for positioning relative to\n * a specific point such as the mouse cursor (e.g. context menus) or text selection.\n *\n * @default target.getBoundingClientRect()\n * @param target - The target element.\n */\n getTargetRect?: (target: Element) => DOMRect | null | undefined;\n}\n\nexport interface PositionAria {\n /** Props for the overlay container element. */\n overlayProps: DOMAttributes;\n /** Props for the overlay tip arrow if any. */\n arrowProps: DOMAttributes;\n /** Placement of the overlay with respect to the overlay trigger. */\n placement: PlacementAxis | null;\n /** The origin of the target in the overlay's coordinate system. Useful for animations. */\n triggerAnchorPoint: {x: number; y: number} | null;\n /** Updates the position of the overlay. */\n updatePosition(): void;\n}\n\ninterface ScrollAnchor {\n type: 'top' | 'bottom';\n offset: number;\n}\n\nlet visualViewport = typeof document !== 'undefined' ? window.visualViewport : null;\n\n/**\n * Handles positioning overlays like popovers and menus relative to a trigger\n * element, and updating the position when the window resizes.\n */\nexport function useOverlayPosition(props: AriaPositionProps): PositionAria {\n let {direction} = useLocale();\n let {\n arrowSize,\n targetRef,\n overlayRef,\n arrowRef,\n scrollRef = overlayRef,\n placement = 'bottom' as Placement,\n containerPadding = 12,\n shouldFlip = true,\n boundaryElement = typeof document !== 'undefined' ? document.body : null,\n offset = 0,\n crossOffset = 0,\n shouldUpdatePosition = true,\n isOpen = true,\n onClose,\n maxHeight,\n arrowBoundaryOffset = 0,\n getTargetRect\n } = props;\n let [position, setPosition] = useState<PositionResult | null>(null);\n\n let deps = [\n shouldUpdatePosition,\n placement,\n overlayRef.current,\n targetRef.current,\n arrowRef?.current,\n scrollRef.current,\n containerPadding,\n shouldFlip,\n boundaryElement,\n offset,\n crossOffset,\n isOpen,\n direction,\n maxHeight,\n arrowBoundaryOffset,\n arrowSize\n ];\n\n // Note, the position freezing breaks if body sizes itself dynamicly with the visual viewport but that might\n // just be a non-realistic use case\n // Upon opening a overlay, record the current visual viewport scale so we can freeze the overlay styles\n let lastScale = useRef(visualViewport?.scale);\n useEffect(() => {\n if (isOpen) {\n lastScale.current = visualViewport?.scale;\n }\n }, [isOpen]);\n\n let updatePosition = useCallback(() => {\n if (\n shouldUpdatePosition === false ||\n !isOpen ||\n !overlayRef.current ||\n !targetRef.current ||\n !boundaryElement\n ) {\n return;\n }\n\n if (visualViewport?.scale !== lastScale.current) {\n return;\n }\n\n // Determine a scroll anchor based on the focused element.\n // This stores the offset of the anchor element from the scroll container\n // so it can be restored after repositioning. This way if the overlay height\n // changes, the focused element appears to stay in the same position.\n let anchor: ScrollAnchor | null = null;\n if (scrollRef.current && isFocusWithin(scrollRef.current)) {\n let anchorRect = getActiveElement()?.getBoundingClientRect();\n let scrollRect = scrollRef.current.getBoundingClientRect();\n // Anchor from the top if the offset is in the top half of the scrollable element,\n // otherwise anchor from the bottom.\n anchor = {\n type: 'top',\n offset: (anchorRect?.top ?? 0) - scrollRect.top\n };\n if (anchor.offset > scrollRect.height / 2) {\n anchor.type = 'bottom';\n anchor.offset = (anchorRect?.bottom ?? 0) - scrollRect.bottom;\n }\n }\n\n // Always reset the overlay's previous max height if not defined by the user so that we can compensate for\n // RAC collections populating after a second render and properly set a correct max height + positioning when it populates.\n let overlay = overlayRef.current as HTMLElement;\n if (!maxHeight && overlayRef.current) {\n overlay.style.top = '0px';\n overlay.style.bottom = '';\n overlay.style.maxHeight = (window.visualViewport?.height ?? window.innerHeight) + 'px';\n }\n\n let position = calculatePosition({\n placement: translateRTL(placement, direction),\n overlayNode: overlayRef.current,\n targetNode: targetRef.current,\n scrollNode: scrollRef.current || overlayRef.current,\n padding: containerPadding,\n shouldFlip,\n boundaryElement,\n offset,\n crossOffset,\n maxHeight,\n arrowSize: arrowSize ?? (arrowRef?.current ? getRect(arrowRef.current, true).width : 0),\n arrowBoundaryOffset,\n targetRect: getTargetRect?.(targetRef.current)\n });\n\n if (!position.position) {\n return;\n }\n\n // Modify overlay styles directly so positioning happens immediately without the need of a second render\n // This is so we don't have to delay autoFocus scrolling or delay applying preventScroll for popovers\n overlay.style.top = '';\n overlay.style.bottom = '';\n overlay.style.left = '';\n overlay.style.right = '';\n\n Object.keys(position.position).forEach(\n key => (overlay.style[key] = position.position![key] + 'px')\n );\n overlay.style.maxHeight = position.maxHeight != null ? position.maxHeight + 'px' : '';\n\n // Restore scroll position relative to anchor element.\n let activeElement = getActiveElement();\n if (anchor && activeElement && scrollRef.current) {\n let anchorRect = activeElement.getBoundingClientRect();\n let scrollRect = scrollRef.current.getBoundingClientRect();\n let newOffset = anchorRect[anchor.type] - scrollRect[anchor.type];\n scrollRef.current.scrollTop += newOffset - anchor.offset;\n }\n\n // Trigger a set state for a second render anyway for arrow positioning\n setPosition(position);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, deps);\n\n // Update position when anything changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useLayoutEffect(updatePosition, deps);\n\n // Update position on window resize\n useResize(updatePosition);\n\n // Update position when the overlay changes size (might need to flip).\n useResizeObserver({\n ref: overlayRef,\n onResize: updatePosition\n });\n\n // Update position when the target changes size (might need to flip).\n useResizeObserver({\n ref: targetRef,\n onResize: updatePosition\n });\n\n // Reposition the overlay and do not close on scroll while the visual viewport is resizing.\n // This will ensure that overlays adjust their positioning when the iOS virtual keyboard appears.\n let isResizing = useRef(false);\n useLayoutEffect(() => {\n let timeout: ReturnType<typeof setTimeout>;\n let onResize = () => {\n isResizing.current = true;\n clearTimeout(timeout);\n\n timeout = setTimeout(() => {\n isResizing.current = false;\n }, 500);\n\n updatePosition();\n };\n\n // Only reposition the overlay if a scroll event happens immediately as a result of resize (aka the virtual keyboard has appears)\n // We don't want to reposition the overlay if the user has pinch zoomed in and is scrolling the viewport around.\n let onScroll = () => {\n if (isResizing.current) {\n onResize();\n }\n };\n\n visualViewport?.addEventListener('resize', onResize);\n visualViewport?.addEventListener('scroll', onScroll);\n return () => {\n visualViewport?.removeEventListener('resize', onResize);\n visualViewport?.removeEventListener('scroll', onScroll);\n };\n }, [updatePosition]);\n\n let close = useCallback(() => {\n if (!isResizing.current) {\n onClose?.();\n }\n }, [onClose, isResizing]);\n\n // When scrolling a parent scrollable region of the trigger (other than the body),\n // we hide the popover. Otherwise, its position would be incorrect.\n useCloseOnScroll({\n triggerRef: targetRef,\n isOpen,\n onClose: onClose && close\n });\n\n return {\n overlayProps: {\n style: {\n position: position ? 'absolute' : 'fixed',\n top: !position ? 0 : undefined,\n left: !position ? 0 : undefined,\n zIndex: 100000, // should match the z-index in ModalTrigger\n ...position?.position,\n maxHeight: position?.maxHeight ?? '100vh'\n }\n },\n placement: position?.placement ?? null,\n triggerAnchorPoint: position?.triggerAnchorPoint ?? null,\n arrowProps: {\n 'aria-hidden': 'true',\n role: 'presentation',\n style: {\n left: position?.arrowOffsetLeft,\n top: position?.arrowOffsetTop\n }\n },\n updatePosition\n };\n}\n\nfunction useResize(onResize) {\n useLayoutEffect(() => {\n window.addEventListener('resize', onResize, false);\n return () => {\n window.removeEventListener('resize', onResize, false);\n };\n }, [onResize]);\n}\n\nfunction translateRTL(position, direction) {\n if (direction === 'rtl') {\n return position.replace('start', 'right').replace('end', 'left');\n }\n return position.replace('start', 'left').replace('end', 'right');\n}\n"],"names":[],"version":3,"file":"useOverlayPosition.mjs.map"}