Skip to content

Commit 2f2e7fe

Browse files
authored
Wait until after a layout effect to prevent scroll in popovers (#3697)
1 parent 286dbcd commit 2f2e7fe

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

packages/@react-aria/overlays/src/usePopover.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {mergeProps, useLayoutEffect} from '@react-aria/utils';
1717
import {OverlayContext} from './Overlay';
1818
import {OverlayTriggerState} from '@react-stately/overlays';
1919
import {PlacementAxis} from '@react-types/overlays';
20-
import {RefObject, useContext} from 'react';
20+
import {RefObject, useContext, useState} from 'react';
2121
import {useOverlay} from './useOverlay';
2222
import {usePreventScroll} from './usePreventScroll';
2323

@@ -89,10 +89,19 @@ export function usePopover(props: AriaPopoverProps, state: OverlayTriggerState):
8989
overlayRef: popoverRef,
9090
isOpen: state.isOpen
9191
});
92-
92+
93+
// Delay preventing scroll until popover is positioned to avoid extra scroll padding.
94+
// This requires a layout effect so that positioning has been committed to the DOM
95+
// by the time usePreventScroll measures the element.
96+
let [isPositioned, setPositioned] = useState(false);
97+
useLayoutEffect(() => {
98+
if (!isNonModal && placement) {
99+
setPositioned(true);
100+
}
101+
}, [isNonModal, placement]);
102+
93103
usePreventScroll({
94-
// Delay preventing scroll until popover is positioned to avoid extra scroll padding.
95-
isDisabled: isNonModal || !placement
104+
isDisabled: isNonModal || !isPositioned
96105
});
97106

98107
useLayoutEffect(() => {

0 commit comments

Comments
 (0)