@react-aria/overlays 3.16.0 → 3.18.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.
- package/dist/import.mjs +55 -42
- package/dist/main.js +54 -41
- package/dist/main.js.map +1 -1
- package/dist/module.js +55 -42
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +12 -12
- package/src/Overlay.tsx +13 -12
- package/src/calculatePosition.ts +16 -6
- package/src/useOverlay.ts +7 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-aria/overlays",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.18.0",
|
|
4
4
|
"description": "Spectrum UI components in React",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "dist/main.js",
|
|
@@ -22,16 +22,16 @@
|
|
|
22
22
|
"url": "https://github.com/adobe/react-spectrum"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@react-aria/focus": "^3.14.
|
|
26
|
-
"@react-aria/i18n": "^3.8.
|
|
27
|
-
"@react-aria/interactions": "^3.
|
|
28
|
-
"@react-aria/ssr": "^3.
|
|
29
|
-
"@react-aria/utils": "^3.
|
|
30
|
-
"@react-aria/visually-hidden": "^3.8.
|
|
31
|
-
"@react-stately/overlays": "^3.6.
|
|
32
|
-
"@react-types/button": "^3.
|
|
33
|
-
"@react-types/overlays": "^3.8.
|
|
34
|
-
"@react-types/shared": "^3.
|
|
25
|
+
"@react-aria/focus": "^3.14.2",
|
|
26
|
+
"@react-aria/i18n": "^3.8.3",
|
|
27
|
+
"@react-aria/interactions": "^3.19.0",
|
|
28
|
+
"@react-aria/ssr": "^3.8.0",
|
|
29
|
+
"@react-aria/utils": "^3.21.0",
|
|
30
|
+
"@react-aria/visually-hidden": "^3.8.5",
|
|
31
|
+
"@react-stately/overlays": "^3.6.3",
|
|
32
|
+
"@react-types/button": "^3.9.0",
|
|
33
|
+
"@react-types/overlays": "^3.8.3",
|
|
34
|
+
"@react-types/shared": "^3.21.0",
|
|
35
35
|
"@swc/helpers": "^0.5.0"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
@@ -41,5 +41,5 @@
|
|
|
41
41
|
"publishConfig": {
|
|
42
42
|
"access": "public"
|
|
43
43
|
},
|
|
44
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "4122e44d1991c90507d630d35ed297f89db435d3"
|
|
45
45
|
}
|
package/src/Overlay.tsx
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
+
import {ClearPressResponder} from '@react-aria/interactions';
|
|
13
14
|
import {FocusScope} from '@react-aria/focus';
|
|
14
15
|
import React, {ReactNode, useContext, useMemo, useState} from 'react';
|
|
15
16
|
import ReactDOM from 'react-dom';
|
|
@@ -53,23 +54,23 @@ export function Overlay(props: OverlayProps) {
|
|
|
53
54
|
return null;
|
|
54
55
|
}
|
|
55
56
|
|
|
56
|
-
let contents;
|
|
57
|
+
let contents = props.children;
|
|
57
58
|
if (!props.disableFocusManagement) {
|
|
58
59
|
contents = (
|
|
59
|
-
<
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
</FocusScope>
|
|
63
|
-
</OverlayContext.Provider>
|
|
64
|
-
);
|
|
65
|
-
} else {
|
|
66
|
-
contents = (
|
|
67
|
-
<OverlayContext.Provider value={contextValue}>
|
|
68
|
-
{props.children}
|
|
69
|
-
</OverlayContext.Provider>
|
|
60
|
+
<FocusScope restoreFocus contain={contain && !isExiting}>
|
|
61
|
+
{contents}
|
|
62
|
+
</FocusScope>
|
|
70
63
|
);
|
|
71
64
|
}
|
|
72
65
|
|
|
66
|
+
contents = (
|
|
67
|
+
<OverlayContext.Provider value={contextValue}>
|
|
68
|
+
<ClearPressResponder>
|
|
69
|
+
{contents}
|
|
70
|
+
</ClearPressResponder>
|
|
71
|
+
</OverlayContext.Provider>
|
|
72
|
+
);
|
|
73
|
+
|
|
73
74
|
return ReactDOM.createPortal(contents, portalContainer);
|
|
74
75
|
}
|
|
75
76
|
|
package/src/calculatePosition.ts
CHANGED
|
@@ -140,19 +140,26 @@ function getDelta(
|
|
|
140
140
|
axis: Axis,
|
|
141
141
|
offset: number,
|
|
142
142
|
size: number,
|
|
143
|
+
// The dimensions of the boundary element that the popover is
|
|
144
|
+
// positioned within (most of the time this is the <body>).
|
|
145
|
+
boundaryDimensions: Dimensions,
|
|
146
|
+
// The dimensions of the containing block element that the popover is
|
|
147
|
+
// positioned relative to (e.g. parent with position: relative).
|
|
148
|
+
// Usually this is the same as the boundary element, but if the popover
|
|
149
|
+
// is portaled somewhere other than the body and has an ancestor with
|
|
150
|
+
// position: relative/absolute, it will be different.
|
|
143
151
|
containerDimensions: Dimensions,
|
|
144
152
|
padding: number
|
|
145
153
|
) {
|
|
146
154
|
let containerScroll = containerDimensions.scroll[axis];
|
|
147
|
-
let
|
|
148
|
-
|
|
155
|
+
let boundaryHeight = boundaryDimensions[AXIS_SIZE[axis]];
|
|
149
156
|
let startEdgeOffset = offset - padding - containerScroll;
|
|
150
157
|
let endEdgeOffset = offset + padding - containerScroll + size;
|
|
151
158
|
|
|
152
159
|
if (startEdgeOffset < 0) {
|
|
153
160
|
return -startEdgeOffset;
|
|
154
|
-
} else if (endEdgeOffset >
|
|
155
|
-
return Math.max(
|
|
161
|
+
} else if (endEdgeOffset > boundaryHeight) {
|
|
162
|
+
return Math.max(boundaryHeight - endEdgeOffset, -startEdgeOffset);
|
|
156
163
|
} else {
|
|
157
164
|
return 0;
|
|
158
165
|
}
|
|
@@ -287,6 +294,7 @@ export function calculatePositionInternal(
|
|
|
287
294
|
padding: number,
|
|
288
295
|
flip: boolean,
|
|
289
296
|
boundaryDimensions: Dimensions,
|
|
297
|
+
containerDimensions: Dimensions,
|
|
290
298
|
containerOffsetWithBoundary: Offset,
|
|
291
299
|
offset: number,
|
|
292
300
|
crossOffset: number,
|
|
@@ -329,7 +337,7 @@ export function calculatePositionInternal(
|
|
|
329
337
|
}
|
|
330
338
|
}
|
|
331
339
|
|
|
332
|
-
let delta = getDelta(crossAxis, position[crossAxis], overlaySize[crossSize], boundaryDimensions, padding);
|
|
340
|
+
let delta = getDelta(crossAxis, position[crossAxis], overlaySize[crossSize], boundaryDimensions, containerDimensions, padding);
|
|
333
341
|
position[crossAxis] += delta;
|
|
334
342
|
|
|
335
343
|
let maxHeight = getMaxHeight(
|
|
@@ -348,7 +356,7 @@ export function calculatePositionInternal(
|
|
|
348
356
|
overlaySize.height = Math.min(overlaySize.height, maxHeight);
|
|
349
357
|
|
|
350
358
|
position = computePosition(childOffset, boundaryDimensions, overlaySize, placementInfo, normalizedOffset, crossOffset, containerOffsetWithBoundary, isContainerPositioned, arrowSize, arrowBoundaryOffset);
|
|
351
|
-
delta = getDelta(crossAxis, position[crossAxis], overlaySize[crossSize], boundaryDimensions, padding);
|
|
359
|
+
delta = getDelta(crossAxis, position[crossAxis], overlaySize[crossSize], boundaryDimensions, containerDimensions, padding);
|
|
352
360
|
position[crossAxis] += delta;
|
|
353
361
|
|
|
354
362
|
let arrowPosition: Position = {};
|
|
@@ -416,6 +424,7 @@ export function calculatePosition(opts: PositionOpts): PositionResult {
|
|
|
416
424
|
|
|
417
425
|
let scrollSize = getScroll(scrollNode);
|
|
418
426
|
let boundaryDimensions = getContainerDimensions(boundaryElement);
|
|
427
|
+
let containerDimensions = getContainerDimensions(container);
|
|
419
428
|
let containerOffsetWithBoundary: Offset = boundaryElement.tagName === 'BODY' ? getOffset(container) : getPosition(container, boundaryElement);
|
|
420
429
|
|
|
421
430
|
return calculatePositionInternal(
|
|
@@ -427,6 +436,7 @@ export function calculatePosition(opts: PositionOpts): PositionResult {
|
|
|
427
436
|
padding,
|
|
428
437
|
shouldFlip,
|
|
429
438
|
boundaryDimensions,
|
|
439
|
+
containerDimensions,
|
|
430
440
|
containerOffsetWithBoundary,
|
|
431
441
|
offset,
|
|
432
442
|
crossOffset,
|
package/src/useOverlay.ts
CHANGED
|
@@ -125,10 +125,16 @@ export function useOverlay(props: AriaOverlayProps, ref: RefObject<Element>): Ov
|
|
|
125
125
|
let {focusWithinProps} = useFocusWithin({
|
|
126
126
|
isDisabled: !shouldCloseOnBlur,
|
|
127
127
|
onBlurWithin: (e) => {
|
|
128
|
+
// Do not close if relatedTarget is null, which means focus is lost to the body.
|
|
129
|
+
// That can happen when switching tabs, or due to a VoiceOver/Chrome bug with Control+Option+Arrow navigation.
|
|
130
|
+
// Clicking on the body to close the overlay should already be handled by useInteractOutside.
|
|
131
|
+
// https://github.com/adobe/react-spectrum/issues/4130
|
|
132
|
+
// https://github.com/adobe/react-spectrum/issues/4922
|
|
133
|
+
//
|
|
128
134
|
// If focus is moving into a child focus scope (e.g. menu inside a dialog),
|
|
129
135
|
// do not close the outer overlay. At this point, the active scope should
|
|
130
136
|
// still be the outer overlay, since blur events run before focus.
|
|
131
|
-
if (e.relatedTarget
|
|
137
|
+
if (!e.relatedTarget || isElementInChildOfActiveScope(e.relatedTarget)) {
|
|
132
138
|
return;
|
|
133
139
|
}
|
|
134
140
|
|