Search code examples
reactjsmaterial-uipopover

How to prevent material-ui popover from scrolling an iFrame on open?


I'm working on an application using MaterialUI that embeds in other pages using an iFrame. Whenever we show a component that renders into a Popover (both MUI select and menu components do this), the iFrame scrolls / jumps position as the popover opens.

Here is an example where this happens. https://erehd6.csb.app

Happens in Chrome and Firefox, but not Safari.

To reproduce, you will need to scroll the iFrame off the top of the page. Then the popover demo buttons will exhibit this behavior, or the overflow menus to access code sources off the site (github/stackblitz/copy JS source/copy TS source):

<!doctype html>
<html lang="en">
    <body style="margin: 0;">
        <div style="height: 1000px;"></div>
        <iframe src="https://v4.mui.com/api/popover/" style="border: 0; width: 100vw; height: 100vh;"></iframe>
        <div style="height: 1000px;"></div>
    </body>
</html>

How do I prevent this scrolling/jump from happening? The Popper component does not have this same issue, but I can't figure out how to replace the Popover with the Popper in a way that doesn't require a library fork (and a huge amount of re-testing our application). This happens in all versions of MUI btw, but I couldn't put the current site into an iFrame.

I tried replacing the transition component of Grow with Fade but that did not help. I'm still trying to pinpoint the exact issue, it's somewhere in the positioning code for the Popover.


Solution

  • Adding the disableAutoFocus={true} property to any Popover or any other component relying on Popover should prevent any scrolling weirdness. You might need to use disableEnforceFocus as well, depending on what behavior you desire. These are props from the Modal component (of which Popover is a "child" of): https://mui.com/material-ui/api/modal/

    I just ran into a similar problem when using a <Menu /> in an iframe, which when opened, caused the browser to scroll the page and focus on the iframe. In the case of this <Menu />, I also had to add a autoFocusItem: false property to the MenuListProps, so these are the relevant props for me:

    <Menu
      MenuListProps={{
        autoFocusItem: false,
      }}
      disableAutoFocus
      /* other props */
    >
      {/* MenuList components */}
    </Menu>