@@ -42,6 +42,8 @@ import {
4242 useFlyoutId ,
4343 useFlyoutWidth ,
4444 useIsFlyoutActive ,
45+ useFlyoutManager ,
46+ useHasPushPadding ,
4547} from './manager' ;
4648
4749import { CommonProps , PropsOfElement } from '../common' ;
@@ -51,7 +53,6 @@ import type { EuiButtonIconPropsForButton } from '../button';
5153import { EuiI18n } from '../i18n' ;
5254import { useResizeObserver } from '../observer/resize_observer' ;
5355import { EuiScreenReaderOnly } from '../accessibility' ;
54- import { useMutationObserver } from '../observer/mutation_observer' ;
5556
5657import { EuiFlyoutCloseButton } from './_flyout_close_button' ;
5758import { euiFlyoutStyles , composeFlyoutInlineStyles } from './flyout.styles' ;
@@ -276,6 +277,13 @@ export const EuiFlyoutComponent = forwardRef(
276277 const flyoutId = useFlyoutId ( id ) ;
277278 const layoutMode = useFlyoutLayoutMode ( ) ;
278279 const isActiveManagedFlyout = useIsFlyoutActive ( flyoutId ) ;
280+ const flyoutManager = useFlyoutManager ( ) ;
281+
282+ // Use a ref to access the latest flyoutManager without triggering effect re-runs
283+ const flyoutManagerRef = useRef ( flyoutManager ) ;
284+ useEffect ( ( ) => {
285+ flyoutManagerRef . current = flyoutManager ;
286+ } , [ flyoutManager ] ) ;
279287
280288 const {
281289 onMouseDown : onMouseDownResizableButton ,
@@ -325,18 +333,27 @@ export const EuiFlyoutComponent = forwardRef(
325333 const cssVarName = `--euiPushFlyoutOffset${
326334 side === 'left' ? 'InlineStart' : 'InlineEnd'
327335 } `;
336+ const managerSide = side === 'left' ? 'left' : 'right' ;
328337
329338 if ( shouldApplyPadding ) {
330339 document . body . style [ paddingSide ] = `${ width } px` ;
331340 setGlobalCSSVariables ( {
332341 [ cssVarName ] : `${ width } px` ,
333342 } ) ;
343+ // Update manager state if in managed context
344+ if ( isInManagedContext && flyoutManagerRef . current ) {
345+ flyoutManagerRef . current . setPushPadding ( managerSide , width ) ;
346+ }
334347 } else {
335348 // Explicitly remove padding when this push flyout becomes inactive
336349 document . body . style [ paddingSide ] = '' ;
337350 setGlobalCSSVariables ( {
338351 [ cssVarName ] : null ,
339352 } ) ;
353+ // Clear manager state if in managed context
354+ if ( isInManagedContext && flyoutManagerRef . current ) {
355+ flyoutManagerRef . current . setPushPadding ( managerSide , 0 ) ;
356+ }
340357 }
341358
342359 // Cleanup on unmount
@@ -345,6 +362,10 @@ export const EuiFlyoutComponent = forwardRef(
345362 setGlobalCSSVariables ( {
346363 [ cssVarName ] : null ,
347364 } ) ;
365+ // Clear manager state on unmount if in managed context
366+ if ( isInManagedContext && flyoutManagerRef . current ) {
367+ flyoutManagerRef . current . setPushPadding ( managerSide , 0 ) ;
368+ }
348369 } ;
349370 } , [
350371 isPushed ,
@@ -632,44 +653,13 @@ export const EuiFlyoutComponent = forwardRef(
632653 const maskCombinedRefs = useCombinedRefs ( [ maskProps ?. maskRef , maskRef ] ) ;
633654
634655 /**
635- * Track whether body padding from a push flyout exists to coordinate scroll locking.
636- * Use state to allow updates when padding changes.
637- */
638- const [ hasPushFlyoutPadding , setHasPushFlyoutPadding ] = useState ( ( ) => {
639- if ( isPushed || ! isInManagedContext ) return false ;
640- const leftPadding = document . body . style . paddingInlineStart ;
641- const rightPadding = document . body . style . paddingInlineEnd ;
642- return ! ! ( leftPadding || rightPadding ) ;
643- } ) ;
644-
645- /**
646- * Monitor body padding and update state when it changes.
647- * This allows overlay flyouts to enable scroll lock once push padding is removed.
656+ * For overlay flyouts in managed contexts, coordinate scroll locking with push flyout state.
657+ * Only enable scroll lock when there's no active push padding in the manager.
648658 */
649- const checkPadding = useCallback ( ( ) => {
650- const leftPadding = document . body . style . paddingInlineStart ;
651- const rightPadding = document . body . style . paddingInlineEnd ;
652- const hasPadding = ! ! ( leftPadding || rightPadding ) ;
653- setHasPushFlyoutPadding ( hasPadding ) ;
654- } , [ ] ) ;
655-
656- // Monitor body style changes for overlay flyouts in managed contexts
657- useMutationObserver (
658- isPushed || ! isInManagedContext ? null : document . body ,
659- checkPadding ,
660- { attributeFilter : [ 'style' ] }
661- ) ;
662-
663- // Check padding state immediately after render
664- useLayoutEffect ( ( ) => {
665- if ( ! isPushed && isInManagedContext ) {
666- checkPadding ( ) ;
667- } else {
668- setHasPushFlyoutPadding ( false ) ;
669- }
670- } , [ isPushed , isInManagedContext , checkPadding ] ) ;
671-
672- const shouldUseScrollLock = hasOverlayMask && ! hasPushFlyoutPadding ;
659+ const hasPushPaddingInManager = useHasPushPadding ( ) ;
660+ const shouldDeferScrollLock =
661+ ! isPushed && isInManagedContext && hasPushPaddingInManager ;
662+ const shouldUseScrollLock = hasOverlayMask && ! shouldDeferScrollLock ;
673663
674664 return (
675665 < EuiFlyoutOverlay
0 commit comments