@react-aria/overlays 3.20.0 → 3.21.1
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.
- package/dist/import.mjs +84 -19
- package/dist/main.js +82 -17
- package/dist/main.js.map +1 -1
- package/dist/module.js +84 -19
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +12 -12
- package/src/calculatePosition.ts +85 -24
- package/src/useOverlayPosition.ts +31 -4
package/dist/import.mjs
CHANGED
|
@@ -32,8 +32,8 @@ import $29700c92185d38f8$exports from "./tr-TR.mjs";
|
|
|
32
32
|
import $662ccaf2be4c25b3$exports from "./uk-UA.mjs";
|
|
33
33
|
import $d80a27deda7cdb3c$exports from "./zh-CN.mjs";
|
|
34
34
|
import $2b2734393847c884$exports from "./zh-TW.mjs";
|
|
35
|
-
import $k7QOs$react, {useState as $k7QOs$useState,
|
|
36
|
-
import {useLayoutEffect as $k7QOs$useLayoutEffect, useResizeObserver as $k7QOs$useResizeObserver, clamp as $k7QOs$clamp, useId as $k7QOs$useId, isIOS as $k7QOs$isIOS, chain as $k7QOs$chain, getScrollParent as $k7QOs$getScrollParent, useLabels as $k7QOs$useLabels, mergeProps as $k7QOs$mergeProps} from "@react-aria/utils";
|
|
35
|
+
import $k7QOs$react, {useState as $k7QOs$useState, useRef as $k7QOs$useRef, useEffect as $k7QOs$useEffect, useCallback as $k7QOs$useCallback, useContext as $k7QOs$useContext, useMemo as $k7QOs$useMemo} from "react";
|
|
36
|
+
import {useLayoutEffect as $k7QOs$useLayoutEffect, useResizeObserver as $k7QOs$useResizeObserver, isWebKit as $k7QOs$isWebKit, clamp as $k7QOs$clamp, useId as $k7QOs$useId, isIOS as $k7QOs$isIOS, chain as $k7QOs$chain, getScrollParent as $k7QOs$getScrollParent, useLabels as $k7QOs$useLabels, mergeProps as $k7QOs$mergeProps} from "@react-aria/utils";
|
|
37
37
|
import {useLocale as $k7QOs$useLocale, useLocalizedStringFormatter as $k7QOs$useLocalizedStringFormatter} from "@react-aria/i18n";
|
|
38
38
|
import {isElementInChildOfActiveScope as $k7QOs$isElementInChildOfActiveScope, FocusScope as $k7QOs$FocusScope} from "@react-aria/focus";
|
|
39
39
|
import {useInteractOutside as $k7QOs$useInteractOutside, useFocusWithin as $k7QOs$useFocusWithin, ClearPressResponder as $k7QOs$ClearPressResponder} from "@react-aria/interactions";
|
|
@@ -106,6 +106,7 @@ let $edcf132a9284368a$var$visualViewport = typeof document !== "undefined" && wi
|
|
|
106
106
|
function $edcf132a9284368a$var$getContainerDimensions(containerNode) {
|
|
107
107
|
let width = 0, height = 0, totalWidth = 0, totalHeight = 0, top = 0, left = 0;
|
|
108
108
|
let scroll = {};
|
|
109
|
+
let isPinchZoomedIn = ($edcf132a9284368a$var$visualViewport === null || $edcf132a9284368a$var$visualViewport === void 0 ? void 0 : $edcf132a9284368a$var$visualViewport.scale) > 1;
|
|
109
110
|
if (containerNode.tagName === "BODY") {
|
|
110
111
|
let documentElement = document.documentElement;
|
|
111
112
|
totalWidth = documentElement.clientWidth;
|
|
@@ -116,6 +117,13 @@ function $edcf132a9284368a$var$getContainerDimensions(containerNode) {
|
|
|
116
117
|
height = (_visualViewport_height = $edcf132a9284368a$var$visualViewport === null || $edcf132a9284368a$var$visualViewport === void 0 ? void 0 : $edcf132a9284368a$var$visualViewport.height) !== null && _visualViewport_height !== void 0 ? _visualViewport_height : totalHeight;
|
|
117
118
|
scroll.top = documentElement.scrollTop || containerNode.scrollTop;
|
|
118
119
|
scroll.left = documentElement.scrollLeft || containerNode.scrollLeft;
|
|
120
|
+
// The goal of the below is to get a top/left value that represents the top/left of the visual viewport with
|
|
121
|
+
// respect to the layout viewport origin. This combined with the scrollTop/scrollLeft will allow us to calculate
|
|
122
|
+
// coordinates/values with respect to the visual viewport or with respect to the layout viewport.
|
|
123
|
+
if ($edcf132a9284368a$var$visualViewport) {
|
|
124
|
+
top = $edcf132a9284368a$var$visualViewport.offsetTop;
|
|
125
|
+
left = $edcf132a9284368a$var$visualViewport.offsetLeft;
|
|
126
|
+
}
|
|
119
127
|
} else {
|
|
120
128
|
({ width: width, height: height, top: top, left: left } = $edcf132a9284368a$var$getOffset(containerNode));
|
|
121
129
|
scroll.top = containerNode.scrollTop;
|
|
@@ -123,6 +131,16 @@ function $edcf132a9284368a$var$getContainerDimensions(containerNode) {
|
|
|
123
131
|
totalWidth = width;
|
|
124
132
|
totalHeight = height;
|
|
125
133
|
}
|
|
134
|
+
if ((0, $k7QOs$isWebKit)() && (containerNode.tagName === "BODY" || containerNode.tagName === "HTML") && isPinchZoomedIn) {
|
|
135
|
+
// Safari will report a non-zero scrollTop/Left for the non-scrolling body/HTML element when pinch zoomed in unlike other browsers.
|
|
136
|
+
// Set to zero for parity calculations so we get consistent positioning of overlays across all browsers.
|
|
137
|
+
// Also switch to visualViewport.pageTop/pageLeft so that we still accomodate for scroll positioning for body/HTML elements that are actually scrollable
|
|
138
|
+
// before pinch zoom happens
|
|
139
|
+
scroll.top = 0;
|
|
140
|
+
scroll.left = 0;
|
|
141
|
+
top = $edcf132a9284368a$var$visualViewport.pageTop;
|
|
142
|
+
left = $edcf132a9284368a$var$visualViewport.pageLeft;
|
|
143
|
+
}
|
|
126
144
|
return {
|
|
127
145
|
width: width,
|
|
128
146
|
height: height,
|
|
@@ -141,6 +159,7 @@ function $edcf132a9284368a$var$getScroll(node) {
|
|
|
141
159
|
height: node.scrollHeight
|
|
142
160
|
};
|
|
143
161
|
}
|
|
162
|
+
// Determines the amount of space required when moving the overlay to ensure it remains in the boundary
|
|
144
163
|
function $edcf132a9284368a$var$getDelta(axis, offset, size, // The dimensions of the boundary element that the popover is
|
|
145
164
|
// positioned within (most of the time this is the <body>).
|
|
146
165
|
boundaryDimensions, // The dimensions of the containing block element that the popover is
|
|
@@ -148,13 +167,20 @@ boundaryDimensions, // The dimensions of the containing block element that the p
|
|
|
148
167
|
// Usually this is the same as the boundary element, but if the popover
|
|
149
168
|
// is portaled somewhere other than the body and has an ancestor with
|
|
150
169
|
// position: relative/absolute, it will be different.
|
|
151
|
-
containerDimensions, padding) {
|
|
170
|
+
containerDimensions, padding, containerOffsetWithBoundary) {
|
|
152
171
|
let containerScroll = containerDimensions.scroll[axis];
|
|
153
|
-
|
|
154
|
-
let
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
172
|
+
// The height/width of the boundary. Matches the axis along which we are adjusting the overlay position
|
|
173
|
+
let boundarySize = boundaryDimensions[$edcf132a9284368a$var$AXIS_SIZE[axis]];
|
|
174
|
+
// Calculate the edges of the boundary (accomodating for the boundary padding) and the edges of the overlay.
|
|
175
|
+
// Note that these values are with respect to the visual viewport (aka 0,0 is the top left of the viewport)
|
|
176
|
+
let boundaryStartEdge = boundaryDimensions.scroll[$edcf132a9284368a$var$AXIS[axis]] + padding;
|
|
177
|
+
let boundaryEndEdge = boundarySize + boundaryDimensions.scroll[$edcf132a9284368a$var$AXIS[axis]] - padding;
|
|
178
|
+
let startEdgeOffset = offset - containerScroll + containerOffsetWithBoundary[axis] - boundaryDimensions[$edcf132a9284368a$var$AXIS[axis]];
|
|
179
|
+
let endEdgeOffset = offset - containerScroll + size + containerOffsetWithBoundary[axis] - boundaryDimensions[$edcf132a9284368a$var$AXIS[axis]];
|
|
180
|
+
// If any of the overlay edges falls outside of the boundary, shift the overlay the required amount to align one of the overlay's
|
|
181
|
+
// edges with the closest boundary edge.
|
|
182
|
+
if (startEdgeOffset < boundaryStartEdge) return boundaryStartEdge - startEdgeOffset;
|
|
183
|
+
else if (endEdgeOffset > boundaryEndEdge) return Math.max(boundaryEndEdge - endEdgeOffset, boundaryStartEdge - startEdgeOffset);
|
|
158
184
|
else return 0;
|
|
159
185
|
}
|
|
160
186
|
function $edcf132a9284368a$var$getMargins(node) {
|
|
@@ -198,7 +224,6 @@ function $edcf132a9284368a$var$computePosition(childOffset, boundaryDimensions,
|
|
|
198
224
|
/* else {
|
|
199
225
|
the overlay top should match the button top
|
|
200
226
|
} */
|
|
201
|
-
// add the crossOffset from props
|
|
202
227
|
position[crossAxis] += crossOffset;
|
|
203
228
|
// overlay top overlapping arrow with button bottom
|
|
204
229
|
const minPosition = childOffset[crossAxis] - overlaySize[crossSize] + arrowSize + arrowBoundaryOffset;
|
|
@@ -216,14 +241,20 @@ function $edcf132a9284368a$var$computePosition(childOffset, boundaryDimensions,
|
|
|
216
241
|
} else position[axis] = Math.floor(childOffset[axis] + childOffset[size] + offset);
|
|
217
242
|
return position;
|
|
218
243
|
}
|
|
219
|
-
function $edcf132a9284368a$var$getMaxHeight(position, boundaryDimensions, containerOffsetWithBoundary,
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
244
|
+
function $edcf132a9284368a$var$getMaxHeight(position, boundaryDimensions, containerOffsetWithBoundary, isContainerPositioned, margins, padding, overlayHeight, heightGrowthDirection) {
|
|
245
|
+
const containerHeight = isContainerPositioned ? containerOffsetWithBoundary.height : boundaryDimensions[$edcf132a9284368a$var$TOTAL_SIZE.height];
|
|
246
|
+
// For cases where position is set via "bottom" instead of "top", we need to calculate the true overlay top with respect to the boundary. Reverse calculate this with the same method
|
|
247
|
+
// used in computePosition.
|
|
248
|
+
let overlayTop = position.top != null ? containerOffsetWithBoundary.top + position.top : containerOffsetWithBoundary.top + (containerHeight - position.bottom - overlayHeight);
|
|
249
|
+
let maxHeight = heightGrowthDirection !== "top" ? // We want the distance between the top of the overlay to the bottom of the boundary
|
|
250
|
+
Math.max(0, boundaryDimensions.height + boundaryDimensions.top + boundaryDimensions.scroll.top // this is the bottom of the boundary
|
|
251
|
+
- overlayTop // this is the top of the overlay
|
|
252
|
+
- (margins.top + margins.bottom + padding // save additional space for margin and padding
|
|
253
|
+
)) : Math.max(0, overlayTop + overlayHeight // this is the bottom of the overlay
|
|
224
254
|
- (boundaryDimensions.top + boundaryDimensions.scroll.top // this is the top of the boundary
|
|
225
255
|
) - (margins.top + margins.bottom + padding // save additional space for margin and padding
|
|
226
256
|
));
|
|
257
|
+
return Math.min(boundaryDimensions.height - padding * 2, maxHeight);
|
|
227
258
|
}
|
|
228
259
|
function $edcf132a9284368a$var$getAvailableSpace(boundaryDimensions, containerOffsetWithBoundary, childOffset, margins, padding, placementInfo) {
|
|
229
260
|
let { placement: placement, axis: axis, size: size } = placementInfo;
|
|
@@ -248,13 +279,22 @@ function $edcf132a9284368a$export$6839422d1f33cee9(placementInput, childOffset,
|
|
|
248
279
|
normalizedOffset = offset;
|
|
249
280
|
}
|
|
250
281
|
}
|
|
251
|
-
|
|
282
|
+
// Determine the direction the height of the overlay can grow so that we can choose how to calculate the max height
|
|
283
|
+
let heightGrowthDirection = "bottom";
|
|
284
|
+
if (placementInfo.axis === "top") {
|
|
285
|
+
if (placementInfo.placement === "top") heightGrowthDirection = "top";
|
|
286
|
+
else if (placementInfo.placement === "bottom") heightGrowthDirection = "bottom";
|
|
287
|
+
} else if (placementInfo.crossAxis === "top") {
|
|
288
|
+
if (placementInfo.crossPlacement === "top") heightGrowthDirection = "bottom";
|
|
289
|
+
else if (placementInfo.crossPlacement === "bottom") heightGrowthDirection = "top";
|
|
290
|
+
}
|
|
291
|
+
let delta = $edcf132a9284368a$var$getDelta(crossAxis, position[crossAxis], overlaySize[crossSize], boundaryDimensions, containerDimensions, padding, containerOffsetWithBoundary);
|
|
252
292
|
position[crossAxis] += delta;
|
|
253
|
-
let maxHeight = $edcf132a9284368a$var$getMaxHeight(position, boundaryDimensions, containerOffsetWithBoundary,
|
|
293
|
+
let maxHeight = $edcf132a9284368a$var$getMaxHeight(position, boundaryDimensions, containerOffsetWithBoundary, isContainerPositioned, margins, padding, overlaySize.height, heightGrowthDirection);
|
|
254
294
|
if (userSetMaxHeight && userSetMaxHeight < maxHeight) maxHeight = userSetMaxHeight;
|
|
255
295
|
overlaySize.height = Math.min(overlaySize.height, maxHeight);
|
|
256
296
|
position = $edcf132a9284368a$var$computePosition(childOffset, boundaryDimensions, overlaySize, placementInfo, normalizedOffset, crossOffset, containerOffsetWithBoundary, isContainerPositioned, arrowSize, arrowBoundaryOffset);
|
|
257
|
-
delta = $edcf132a9284368a$var$getDelta(crossAxis, position[crossAxis], overlaySize[crossSize], boundaryDimensions, containerDimensions, padding);
|
|
297
|
+
delta = $edcf132a9284368a$var$getDelta(crossAxis, position[crossAxis], overlaySize[crossSize], boundaryDimensions, containerDimensions, padding, containerOffsetWithBoundary);
|
|
258
298
|
position[crossAxis] += delta;
|
|
259
299
|
let arrowPosition = {};
|
|
260
300
|
// All values are transformed so that 0 is at the top/left of the overlay depending on the orientation
|
|
@@ -296,7 +336,14 @@ function $edcf132a9284368a$export$b3ceb0cbf1056d98(opts) {
|
|
|
296
336
|
let scrollSize = $edcf132a9284368a$var$getScroll(scrollNode);
|
|
297
337
|
let boundaryDimensions = $edcf132a9284368a$var$getContainerDimensions(boundaryElement);
|
|
298
338
|
let containerDimensions = $edcf132a9284368a$var$getContainerDimensions(container);
|
|
339
|
+
// If the container is the HTML element wrapping the body element, the retrieved scrollTop/scrollLeft will be equal to the
|
|
340
|
+
// body element's scroll. Set the container's scroll values to 0 since the overlay's edge position value in getDelta don't then need to be further offset
|
|
341
|
+
// by the container scroll since they are essentially the same containing element and thus in the same coordinate system
|
|
299
342
|
let containerOffsetWithBoundary = boundaryElement.tagName === "BODY" ? $edcf132a9284368a$var$getOffset(container) : $edcf132a9284368a$var$getPosition(container, boundaryElement);
|
|
343
|
+
if (container.tagName === "HTML" && boundaryElement.tagName === "BODY") {
|
|
344
|
+
containerDimensions.scroll.top = 0;
|
|
345
|
+
containerDimensions.scroll.left = 0;
|
|
346
|
+
}
|
|
300
347
|
return $edcf132a9284368a$export$6839422d1f33cee9(placement, childOffset, overlaySize, scrollSize, margins, padding, shouldFlip, boundaryDimensions, containerDimensions, containerOffsetWithBoundary, offset, crossOffset, isContainerPositioned, maxHeight, arrowSize, arrowBoundaryOffset);
|
|
301
348
|
}
|
|
302
349
|
function $edcf132a9284368a$var$getOffset(node) {
|
|
@@ -432,8 +479,21 @@ function $2a41e45df1593e64$export$d39e1813b3bdd0e1(props) {
|
|
|
432
479
|
arrowBoundaryOffset,
|
|
433
480
|
arrowSize
|
|
434
481
|
];
|
|
482
|
+
// Note, the position freezing breaks if body sizes itself dynamicly with the visual viewport but that might
|
|
483
|
+
// just be a non-realistic use case
|
|
484
|
+
// Upon opening a overlay, record the current visual viewport scale so we can freeze the overlay styles
|
|
485
|
+
let lastScale = (0, $k7QOs$useRef)($2a41e45df1593e64$var$visualViewport === null || $2a41e45df1593e64$var$visualViewport === void 0 ? void 0 : $2a41e45df1593e64$var$visualViewport.scale);
|
|
486
|
+
(0, $k7QOs$useEffect)(()=>{
|
|
487
|
+
if (isOpen) lastScale.current = $2a41e45df1593e64$var$visualViewport === null || $2a41e45df1593e64$var$visualViewport === void 0 ? void 0 : $2a41e45df1593e64$var$visualViewport.scale;
|
|
488
|
+
}, [
|
|
489
|
+
isOpen
|
|
490
|
+
]);
|
|
435
491
|
let updatePosition = (0, $k7QOs$useCallback)(()=>{
|
|
436
492
|
if (shouldUpdatePosition === false || !isOpen || !overlayRef.current || !targetRef.current || !scrollRef.current || !boundaryElement) return;
|
|
493
|
+
if (($2a41e45df1593e64$var$visualViewport === null || $2a41e45df1593e64$var$visualViewport === void 0 ? void 0 : $2a41e45df1593e64$var$visualViewport.scale) !== lastScale.current) return;
|
|
494
|
+
// Always reset the overlay's previous max height if not defined by the user so that we can compensate for
|
|
495
|
+
// RAC collections populating after a second render and properly set a correct max height + positioning when it populates.
|
|
496
|
+
if (!maxHeight && overlayRef.current) overlayRef.current.style.maxHeight = "none";
|
|
437
497
|
let position = (0, $edcf132a9284368a$export$b3ceb0cbf1056d98)({
|
|
438
498
|
placement: $2a41e45df1593e64$var$translateRTL(placement, direction),
|
|
439
499
|
overlayNode: overlayRef.current,
|
|
@@ -479,11 +539,16 @@ function $2a41e45df1593e64$export$d39e1813b3bdd0e1(props) {
|
|
|
479
539
|
}, 500);
|
|
480
540
|
updatePosition();
|
|
481
541
|
};
|
|
542
|
+
// Only reposition the overlay if a scroll event happens immediately as a result of resize (aka the virtual keyboard has appears)
|
|
543
|
+
// We don't want to reposition the overlay if the user has pinch zoomed in and is scrolling the viewport around.
|
|
544
|
+
let onScroll = ()=>{
|
|
545
|
+
if (isResizing.current) onResize();
|
|
546
|
+
};
|
|
482
547
|
$2a41e45df1593e64$var$visualViewport === null || $2a41e45df1593e64$var$visualViewport === void 0 ? void 0 : $2a41e45df1593e64$var$visualViewport.addEventListener("resize", onResize);
|
|
483
|
-
$2a41e45df1593e64$var$visualViewport === null || $2a41e45df1593e64$var$visualViewport === void 0 ? void 0 : $2a41e45df1593e64$var$visualViewport.addEventListener("scroll",
|
|
548
|
+
$2a41e45df1593e64$var$visualViewport === null || $2a41e45df1593e64$var$visualViewport === void 0 ? void 0 : $2a41e45df1593e64$var$visualViewport.addEventListener("scroll", onScroll);
|
|
484
549
|
return ()=>{
|
|
485
550
|
$2a41e45df1593e64$var$visualViewport === null || $2a41e45df1593e64$var$visualViewport === void 0 ? void 0 : $2a41e45df1593e64$var$visualViewport.removeEventListener("resize", onResize);
|
|
486
|
-
$2a41e45df1593e64$var$visualViewport === null || $2a41e45df1593e64$var$visualViewport === void 0 ? void 0 : $2a41e45df1593e64$var$visualViewport.removeEventListener("scroll",
|
|
551
|
+
$2a41e45df1593e64$var$visualViewport === null || $2a41e45df1593e64$var$visualViewport === void 0 ? void 0 : $2a41e45df1593e64$var$visualViewport.removeEventListener("scroll", onScroll);
|
|
487
552
|
};
|
|
488
553
|
}, [
|
|
489
554
|
updatePosition
|
package/dist/main.js
CHANGED
|
@@ -126,6 +126,7 @@ let $5935ba4d7da2c103$var$visualViewport = typeof document !== "undefined" && wi
|
|
|
126
126
|
function $5935ba4d7da2c103$var$getContainerDimensions(containerNode) {
|
|
127
127
|
let width = 0, height = 0, totalWidth = 0, totalHeight = 0, top = 0, left = 0;
|
|
128
128
|
let scroll = {};
|
|
129
|
+
let isPinchZoomedIn = ($5935ba4d7da2c103$var$visualViewport === null || $5935ba4d7da2c103$var$visualViewport === void 0 ? void 0 : $5935ba4d7da2c103$var$visualViewport.scale) > 1;
|
|
129
130
|
if (containerNode.tagName === "BODY") {
|
|
130
131
|
let documentElement = document.documentElement;
|
|
131
132
|
totalWidth = documentElement.clientWidth;
|
|
@@ -136,6 +137,13 @@ function $5935ba4d7da2c103$var$getContainerDimensions(containerNode) {
|
|
|
136
137
|
height = (_visualViewport_height = $5935ba4d7da2c103$var$visualViewport === null || $5935ba4d7da2c103$var$visualViewport === void 0 ? void 0 : $5935ba4d7da2c103$var$visualViewport.height) !== null && _visualViewport_height !== void 0 ? _visualViewport_height : totalHeight;
|
|
137
138
|
scroll.top = documentElement.scrollTop || containerNode.scrollTop;
|
|
138
139
|
scroll.left = documentElement.scrollLeft || containerNode.scrollLeft;
|
|
140
|
+
// The goal of the below is to get a top/left value that represents the top/left of the visual viewport with
|
|
141
|
+
// respect to the layout viewport origin. This combined with the scrollTop/scrollLeft will allow us to calculate
|
|
142
|
+
// coordinates/values with respect to the visual viewport or with respect to the layout viewport.
|
|
143
|
+
if ($5935ba4d7da2c103$var$visualViewport) {
|
|
144
|
+
top = $5935ba4d7da2c103$var$visualViewport.offsetTop;
|
|
145
|
+
left = $5935ba4d7da2c103$var$visualViewport.offsetLeft;
|
|
146
|
+
}
|
|
139
147
|
} else {
|
|
140
148
|
({ width: width, height: height, top: top, left: left } = $5935ba4d7da2c103$var$getOffset(containerNode));
|
|
141
149
|
scroll.top = containerNode.scrollTop;
|
|
@@ -143,6 +151,16 @@ function $5935ba4d7da2c103$var$getContainerDimensions(containerNode) {
|
|
|
143
151
|
totalWidth = width;
|
|
144
152
|
totalHeight = height;
|
|
145
153
|
}
|
|
154
|
+
if ((0, $6Zb2x$reactariautils.isWebKit)() && (containerNode.tagName === "BODY" || containerNode.tagName === "HTML") && isPinchZoomedIn) {
|
|
155
|
+
// Safari will report a non-zero scrollTop/Left for the non-scrolling body/HTML element when pinch zoomed in unlike other browsers.
|
|
156
|
+
// Set to zero for parity calculations so we get consistent positioning of overlays across all browsers.
|
|
157
|
+
// Also switch to visualViewport.pageTop/pageLeft so that we still accomodate for scroll positioning for body/HTML elements that are actually scrollable
|
|
158
|
+
// before pinch zoom happens
|
|
159
|
+
scroll.top = 0;
|
|
160
|
+
scroll.left = 0;
|
|
161
|
+
top = $5935ba4d7da2c103$var$visualViewport.pageTop;
|
|
162
|
+
left = $5935ba4d7da2c103$var$visualViewport.pageLeft;
|
|
163
|
+
}
|
|
146
164
|
return {
|
|
147
165
|
width: width,
|
|
148
166
|
height: height,
|
|
@@ -161,6 +179,7 @@ function $5935ba4d7da2c103$var$getScroll(node) {
|
|
|
161
179
|
height: node.scrollHeight
|
|
162
180
|
};
|
|
163
181
|
}
|
|
182
|
+
// Determines the amount of space required when moving the overlay to ensure it remains in the boundary
|
|
164
183
|
function $5935ba4d7da2c103$var$getDelta(axis, offset, size, // The dimensions of the boundary element that the popover is
|
|
165
184
|
// positioned within (most of the time this is the <body>).
|
|
166
185
|
boundaryDimensions, // The dimensions of the containing block element that the popover is
|
|
@@ -168,13 +187,20 @@ boundaryDimensions, // The dimensions of the containing block element that the p
|
|
|
168
187
|
// Usually this is the same as the boundary element, but if the popover
|
|
169
188
|
// is portaled somewhere other than the body and has an ancestor with
|
|
170
189
|
// position: relative/absolute, it will be different.
|
|
171
|
-
containerDimensions, padding) {
|
|
190
|
+
containerDimensions, padding, containerOffsetWithBoundary) {
|
|
172
191
|
let containerScroll = containerDimensions.scroll[axis];
|
|
173
|
-
|
|
174
|
-
let
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
192
|
+
// The height/width of the boundary. Matches the axis along which we are adjusting the overlay position
|
|
193
|
+
let boundarySize = boundaryDimensions[$5935ba4d7da2c103$var$AXIS_SIZE[axis]];
|
|
194
|
+
// Calculate the edges of the boundary (accomodating for the boundary padding) and the edges of the overlay.
|
|
195
|
+
// Note that these values are with respect to the visual viewport (aka 0,0 is the top left of the viewport)
|
|
196
|
+
let boundaryStartEdge = boundaryDimensions.scroll[$5935ba4d7da2c103$var$AXIS[axis]] + padding;
|
|
197
|
+
let boundaryEndEdge = boundarySize + boundaryDimensions.scroll[$5935ba4d7da2c103$var$AXIS[axis]] - padding;
|
|
198
|
+
let startEdgeOffset = offset - containerScroll + containerOffsetWithBoundary[axis] - boundaryDimensions[$5935ba4d7da2c103$var$AXIS[axis]];
|
|
199
|
+
let endEdgeOffset = offset - containerScroll + size + containerOffsetWithBoundary[axis] - boundaryDimensions[$5935ba4d7da2c103$var$AXIS[axis]];
|
|
200
|
+
// If any of the overlay edges falls outside of the boundary, shift the overlay the required amount to align one of the overlay's
|
|
201
|
+
// edges with the closest boundary edge.
|
|
202
|
+
if (startEdgeOffset < boundaryStartEdge) return boundaryStartEdge - startEdgeOffset;
|
|
203
|
+
else if (endEdgeOffset > boundaryEndEdge) return Math.max(boundaryEndEdge - endEdgeOffset, boundaryStartEdge - startEdgeOffset);
|
|
178
204
|
else return 0;
|
|
179
205
|
}
|
|
180
206
|
function $5935ba4d7da2c103$var$getMargins(node) {
|
|
@@ -218,7 +244,6 @@ function $5935ba4d7da2c103$var$computePosition(childOffset, boundaryDimensions,
|
|
|
218
244
|
/* else {
|
|
219
245
|
the overlay top should match the button top
|
|
220
246
|
} */
|
|
221
|
-
// add the crossOffset from props
|
|
222
247
|
position[crossAxis] += crossOffset;
|
|
223
248
|
// overlay top overlapping arrow with button bottom
|
|
224
249
|
const minPosition = childOffset[crossAxis] - overlaySize[crossSize] + arrowSize + arrowBoundaryOffset;
|
|
@@ -236,14 +261,20 @@ function $5935ba4d7da2c103$var$computePosition(childOffset, boundaryDimensions,
|
|
|
236
261
|
} else position[axis] = Math.floor(childOffset[axis] + childOffset[size] + offset);
|
|
237
262
|
return position;
|
|
238
263
|
}
|
|
239
|
-
function $5935ba4d7da2c103$var$getMaxHeight(position, boundaryDimensions, containerOffsetWithBoundary,
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
264
|
+
function $5935ba4d7da2c103$var$getMaxHeight(position, boundaryDimensions, containerOffsetWithBoundary, isContainerPositioned, margins, padding, overlayHeight, heightGrowthDirection) {
|
|
265
|
+
const containerHeight = isContainerPositioned ? containerOffsetWithBoundary.height : boundaryDimensions[$5935ba4d7da2c103$var$TOTAL_SIZE.height];
|
|
266
|
+
// For cases where position is set via "bottom" instead of "top", we need to calculate the true overlay top with respect to the boundary. Reverse calculate this with the same method
|
|
267
|
+
// used in computePosition.
|
|
268
|
+
let overlayTop = position.top != null ? containerOffsetWithBoundary.top + position.top : containerOffsetWithBoundary.top + (containerHeight - position.bottom - overlayHeight);
|
|
269
|
+
let maxHeight = heightGrowthDirection !== "top" ? // We want the distance between the top of the overlay to the bottom of the boundary
|
|
270
|
+
Math.max(0, boundaryDimensions.height + boundaryDimensions.top + boundaryDimensions.scroll.top // this is the bottom of the boundary
|
|
271
|
+
- overlayTop // this is the top of the overlay
|
|
272
|
+
- (margins.top + margins.bottom + padding // save additional space for margin and padding
|
|
273
|
+
)) : Math.max(0, overlayTop + overlayHeight // this is the bottom of the overlay
|
|
244
274
|
- (boundaryDimensions.top + boundaryDimensions.scroll.top // this is the top of the boundary
|
|
245
275
|
) - (margins.top + margins.bottom + padding // save additional space for margin and padding
|
|
246
276
|
));
|
|
277
|
+
return Math.min(boundaryDimensions.height - padding * 2, maxHeight);
|
|
247
278
|
}
|
|
248
279
|
function $5935ba4d7da2c103$var$getAvailableSpace(boundaryDimensions, containerOffsetWithBoundary, childOffset, margins, padding, placementInfo) {
|
|
249
280
|
let { placement: placement, axis: axis, size: size } = placementInfo;
|
|
@@ -268,13 +299,22 @@ function $5935ba4d7da2c103$export$6839422d1f33cee9(placementInput, childOffset,
|
|
|
268
299
|
normalizedOffset = offset;
|
|
269
300
|
}
|
|
270
301
|
}
|
|
271
|
-
|
|
302
|
+
// Determine the direction the height of the overlay can grow so that we can choose how to calculate the max height
|
|
303
|
+
let heightGrowthDirection = "bottom";
|
|
304
|
+
if (placementInfo.axis === "top") {
|
|
305
|
+
if (placementInfo.placement === "top") heightGrowthDirection = "top";
|
|
306
|
+
else if (placementInfo.placement === "bottom") heightGrowthDirection = "bottom";
|
|
307
|
+
} else if (placementInfo.crossAxis === "top") {
|
|
308
|
+
if (placementInfo.crossPlacement === "top") heightGrowthDirection = "bottom";
|
|
309
|
+
else if (placementInfo.crossPlacement === "bottom") heightGrowthDirection = "top";
|
|
310
|
+
}
|
|
311
|
+
let delta = $5935ba4d7da2c103$var$getDelta(crossAxis, position[crossAxis], overlaySize[crossSize], boundaryDimensions, containerDimensions, padding, containerOffsetWithBoundary);
|
|
272
312
|
position[crossAxis] += delta;
|
|
273
|
-
let maxHeight = $5935ba4d7da2c103$var$getMaxHeight(position, boundaryDimensions, containerOffsetWithBoundary,
|
|
313
|
+
let maxHeight = $5935ba4d7da2c103$var$getMaxHeight(position, boundaryDimensions, containerOffsetWithBoundary, isContainerPositioned, margins, padding, overlaySize.height, heightGrowthDirection);
|
|
274
314
|
if (userSetMaxHeight && userSetMaxHeight < maxHeight) maxHeight = userSetMaxHeight;
|
|
275
315
|
overlaySize.height = Math.min(overlaySize.height, maxHeight);
|
|
276
316
|
position = $5935ba4d7da2c103$var$computePosition(childOffset, boundaryDimensions, overlaySize, placementInfo, normalizedOffset, crossOffset, containerOffsetWithBoundary, isContainerPositioned, arrowSize, arrowBoundaryOffset);
|
|
277
|
-
delta = $5935ba4d7da2c103$var$getDelta(crossAxis, position[crossAxis], overlaySize[crossSize], boundaryDimensions, containerDimensions, padding);
|
|
317
|
+
delta = $5935ba4d7da2c103$var$getDelta(crossAxis, position[crossAxis], overlaySize[crossSize], boundaryDimensions, containerDimensions, padding, containerOffsetWithBoundary);
|
|
278
318
|
position[crossAxis] += delta;
|
|
279
319
|
let arrowPosition = {};
|
|
280
320
|
// All values are transformed so that 0 is at the top/left of the overlay depending on the orientation
|
|
@@ -316,7 +356,14 @@ function $5935ba4d7da2c103$export$b3ceb0cbf1056d98(opts) {
|
|
|
316
356
|
let scrollSize = $5935ba4d7da2c103$var$getScroll(scrollNode);
|
|
317
357
|
let boundaryDimensions = $5935ba4d7da2c103$var$getContainerDimensions(boundaryElement);
|
|
318
358
|
let containerDimensions = $5935ba4d7da2c103$var$getContainerDimensions(container);
|
|
359
|
+
// If the container is the HTML element wrapping the body element, the retrieved scrollTop/scrollLeft will be equal to the
|
|
360
|
+
// body element's scroll. Set the container's scroll values to 0 since the overlay's edge position value in getDelta don't then need to be further offset
|
|
361
|
+
// by the container scroll since they are essentially the same containing element and thus in the same coordinate system
|
|
319
362
|
let containerOffsetWithBoundary = boundaryElement.tagName === "BODY" ? $5935ba4d7da2c103$var$getOffset(container) : $5935ba4d7da2c103$var$getPosition(container, boundaryElement);
|
|
363
|
+
if (container.tagName === "HTML" && boundaryElement.tagName === "BODY") {
|
|
364
|
+
containerDimensions.scroll.top = 0;
|
|
365
|
+
containerDimensions.scroll.left = 0;
|
|
366
|
+
}
|
|
320
367
|
return $5935ba4d7da2c103$export$6839422d1f33cee9(placement, childOffset, overlaySize, scrollSize, margins, padding, shouldFlip, boundaryDimensions, containerDimensions, containerOffsetWithBoundary, offset, crossOffset, isContainerPositioned, maxHeight, arrowSize, arrowBoundaryOffset);
|
|
321
368
|
}
|
|
322
369
|
function $5935ba4d7da2c103$var$getOffset(node) {
|
|
@@ -452,8 +499,21 @@ function $cd94b4896dd97759$export$d39e1813b3bdd0e1(props) {
|
|
|
452
499
|
arrowBoundaryOffset,
|
|
453
500
|
arrowSize
|
|
454
501
|
];
|
|
502
|
+
// Note, the position freezing breaks if body sizes itself dynamicly with the visual viewport but that might
|
|
503
|
+
// just be a non-realistic use case
|
|
504
|
+
// Upon opening a overlay, record the current visual viewport scale so we can freeze the overlay styles
|
|
505
|
+
let lastScale = (0, $6Zb2x$react.useRef)($cd94b4896dd97759$var$visualViewport === null || $cd94b4896dd97759$var$visualViewport === void 0 ? void 0 : $cd94b4896dd97759$var$visualViewport.scale);
|
|
506
|
+
(0, $6Zb2x$react.useEffect)(()=>{
|
|
507
|
+
if (isOpen) lastScale.current = $cd94b4896dd97759$var$visualViewport === null || $cd94b4896dd97759$var$visualViewport === void 0 ? void 0 : $cd94b4896dd97759$var$visualViewport.scale;
|
|
508
|
+
}, [
|
|
509
|
+
isOpen
|
|
510
|
+
]);
|
|
455
511
|
let updatePosition = (0, $6Zb2x$react.useCallback)(()=>{
|
|
456
512
|
if (shouldUpdatePosition === false || !isOpen || !overlayRef.current || !targetRef.current || !scrollRef.current || !boundaryElement) return;
|
|
513
|
+
if (($cd94b4896dd97759$var$visualViewport === null || $cd94b4896dd97759$var$visualViewport === void 0 ? void 0 : $cd94b4896dd97759$var$visualViewport.scale) !== lastScale.current) return;
|
|
514
|
+
// Always reset the overlay's previous max height if not defined by the user so that we can compensate for
|
|
515
|
+
// RAC collections populating after a second render and properly set a correct max height + positioning when it populates.
|
|
516
|
+
if (!maxHeight && overlayRef.current) overlayRef.current.style.maxHeight = "none";
|
|
457
517
|
let position = (0, $5935ba4d7da2c103$export$b3ceb0cbf1056d98)({
|
|
458
518
|
placement: $cd94b4896dd97759$var$translateRTL(placement, direction),
|
|
459
519
|
overlayNode: overlayRef.current,
|
|
@@ -499,11 +559,16 @@ function $cd94b4896dd97759$export$d39e1813b3bdd0e1(props) {
|
|
|
499
559
|
}, 500);
|
|
500
560
|
updatePosition();
|
|
501
561
|
};
|
|
562
|
+
// Only reposition the overlay if a scroll event happens immediately as a result of resize (aka the virtual keyboard has appears)
|
|
563
|
+
// We don't want to reposition the overlay if the user has pinch zoomed in and is scrolling the viewport around.
|
|
564
|
+
let onScroll = ()=>{
|
|
565
|
+
if (isResizing.current) onResize();
|
|
566
|
+
};
|
|
502
567
|
$cd94b4896dd97759$var$visualViewport === null || $cd94b4896dd97759$var$visualViewport === void 0 ? void 0 : $cd94b4896dd97759$var$visualViewport.addEventListener("resize", onResize);
|
|
503
|
-
$cd94b4896dd97759$var$visualViewport === null || $cd94b4896dd97759$var$visualViewport === void 0 ? void 0 : $cd94b4896dd97759$var$visualViewport.addEventListener("scroll",
|
|
568
|
+
$cd94b4896dd97759$var$visualViewport === null || $cd94b4896dd97759$var$visualViewport === void 0 ? void 0 : $cd94b4896dd97759$var$visualViewport.addEventListener("scroll", onScroll);
|
|
504
569
|
return ()=>{
|
|
505
570
|
$cd94b4896dd97759$var$visualViewport === null || $cd94b4896dd97759$var$visualViewport === void 0 ? void 0 : $cd94b4896dd97759$var$visualViewport.removeEventListener("resize", onResize);
|
|
506
|
-
$cd94b4896dd97759$var$visualViewport === null || $cd94b4896dd97759$var$visualViewport === void 0 ? void 0 : $cd94b4896dd97759$var$visualViewport.removeEventListener("scroll",
|
|
571
|
+
$cd94b4896dd97759$var$visualViewport === null || $cd94b4896dd97759$var$visualViewport === void 0 ? void 0 : $cd94b4896dd97759$var$visualViewport.removeEventListener("scroll", onScroll);
|
|
507
572
|
};
|
|
508
573
|
}, [
|
|
509
574
|
updatePosition
|