Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backdrop] Stuck open at 0% opacity and blocks all clicks on the page due to react-transition-group bug #32286

Open
joshribakoff-sm opened this issue Apr 13, 2022 · 17 comments
Labels
bug 🐛 Something doesn't work component: backdrop This is the name of the generic UI component, not the React module! external dependency Blocked by external dependency, we can’t do anything about it

Comments

@joshribakoff-sm
Copy link

joshribakoff-sm commented Apr 13, 2022

Current behavior 😯

backdrop should always unmount when animation is done

Expected behavior 🤔

backdrop gets stuck open, blocks interaction with page

Steps to reproduce 🕹

Honestly it is hard to replicate. Turn on strict mode and interact with the Menu rapidly, or hack the code to unmount & re-mount with the "existing" state when onExit fires but before onExited

Context 🔦

Please see this issue where I have done detailed work to isolate and write up what the issue is.
reactjs/react-transition-group#817

As shown here it gets stuck with in={false} and EXITING, it does not ever goto EXITED and unmount, from my user's perspective the whole app is crashed/frozen and they need to reload the page now.
Screen Shot 2022-04-13 at 11 55 48 AM

This is because onExited fails to fire, due to race conditions, and it never hits here https://github.com/mui/material-ui/blob/master/packages/mui-base/src/PopperUnstyled/PopperUnstyled.js#L202-L204

Your environment 🌎

Chrome, but it's irrelevant based on what I understand about this bug

`npx @mui/envinfo`

  System:
    OS: macOS 11.6.4
  Binaries:
    Node: 16.13.2 - ~/.nvm/versions/node/v16.13.2/bin/node
    Yarn: 1.22.17 - ~/.nvm/versions/node/v16.14.0/bin/yarn
    npm: 8.1.2 - ~/.nvm/versions/node/v16.13.2/bin/npm
  Browsers:
    Chrome: 100.0.4896.88
    Edge: Not Found
    Firefox: Not Found
    Safari: 15.4
  npmPackages:
    @emotion/react: ^11.7.1 => 11.8.1 
    @emotion/styled: ^11.6.0 => 11.8.1 
    @mui/base:  5.0.0-alpha.70 
    @mui/icons-material: ^5.3.1 => 5.4.4 
    @mui/lab: ^5.0.0-alpha.66 => 5.0.0-alpha.71 
    @mui/material: ^5.3.1 => 5.4.4 
    @mui/private-theming:  5.4.4 
    @mui/styled-engine:  5.4.4 
    @mui/system: ^5.4.0 => 5.4.4 
    @mui/types: ^7.1.0 => 7.1.2 
    @mui/utils: ^5.3.0 => 5.4.4 
    @types/react: 17.0.30 => 17.0.30 
    react: ^18.0.0 => 18.0.0 
    react-dom: ^18.0.0 => 18.0.0 
    styled-components: 5.3.3 => 5.3.3 
    typescript: ~4.4.3 => 4.4.4 
@joshribakoff-sm joshribakoff-sm added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Apr 13, 2022
@danilo-leal danilo-leal changed the title Backdrop gets stuck open at 0% opacity and blocks all clicks on the page due to react-transition-group bug [Backdrop] Stuck open at 0% opacity and blocks all clicks on the page due to react-transition-group bug Apr 14, 2022
@danilo-leal danilo-leal added component: backdrop This is the name of the generic UI component, not the React module! bug 🐛 Something doesn't work labels Apr 14, 2022
@mnajdova mnajdova added external dependency Blocked by external dependency, we can’t do anything about it and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels May 16, 2022
@mnajdova
Copy link
Member

Thanks for creating the issue and linking it to the react transition group's issue. Let's keep an eye on it to see if the maintainers will provide some feedback. I see that there is another issue opened related to React 18 there too.

@doflo-dfa
Copy link

doflo-dfa commented Oct 22, 2022

This is a very hacky solution but ... it does solve the issues caused by this on modern browsers which should solve for 90% of our applications users ... I would not normally promote such a solution but without it the bug is a complete show stopper

div:has(div[style*="opacity: 0"]) {
  pointer-events: none;
}

or

div.MuiModal-root:has(> div[style*="opacity: 0"]) {
  pointer-events: none;
}

@joacub
Copy link

joacub commented Feb 22, 2023

any updates in this ?

@yukiyokotani
Copy link

I have faced a similar problem. My application uses Next.js v12 and MUI v5, and the user makes screen transitions from the menu in the Drawer. In this situation, on rare occasions, the backdrop drawn by the MUI Drawer remains transparent on the screen, making the application inoperable. When the Drawer is working correctly, the Backdrop style is given visibility: hiddeen when the Drawer is closed, but when the above problem occurs, the Backdrop is not given visibility: hidden even though the Drawer is closed.

I debugged with React Developer Tools and confirmed that the state that the React Transition Group Transition is using internally is stuck at "exiting". I also checked the MUI source code and understood that the visibility: hidden is not given due to the following code control.

https://github.com/mui/material-ui/blob/master/packages/mui-material/src/Slide/Slide.js#L255

We do not have a procedure to reproduce this problem, as it requires a certain scale and occurs stochastically.

@gijsbotje
Copy link
Contributor

We have encountered the same problem with sites of two of our clients. Both are running on next 13 and using MUI 5. For us, it also happens when a route transition is triggered while a backdrop is visible. This happens while a dialog is open or our menu is open on which we add a backdrop.

I'm glad someone found the root of the problem, as it was impossible for us to recreate the bug consistently. Most of the time it will unmount as it should, but sometimes it gets stuck. Hope someone finds a fix for it soon.

@gijsbotje
Copy link
Contributor

I implemented the hack @doflo-dfa mentioned in our theme config, so it only applies for the backdrop. This works fine for until the issue gets fixed.

const theme = createTheme({
  // ...
  components: {
    MuiBackdrop: {
      styleOverrides: {
        root: {
          '&[style*="opacity: 0"]': {
            pointerEvents: 'none',
          },
        },
      },
    },
  },
});

I've also found a way to reproduce this bug in a specific instance. If I open https://nextjs-azalp-9294f0bzd-azalp-de.vercel.app/ in browserstack with edge 112, it gets stuck when I double-click on a sub menu item.
The open state of the backdrop is controlled by a state that gets set to false on click. Only the main menu items in the blue bar have the ability to change it to true on mouse over. Can't imagine a setState setting it to false running twice could trigger this.
Thats also not the only time this bug occurred. We also have reports while doing a route change with a drawer open. That one thankfully isn't as common as the one mentioned above. Hopefully this info helps finding the bug.

@tomas-c
Copy link

tomas-c commented May 3, 2023

I'm also encountering this with the Drawer component and CPU-throttled devices

@Ou7law007
Copy link

Ou7law007 commented Jul 20, 2023

I'm facing this with Autocomplete (I think). It's really difficult to reproduce.
Version 5.14.0

@jimmiebtlr
Copy link

Seeing the same on the @mui/x-date-pickers/DatePicker, I assume they share some code. Doesn't seem to be an opacity on it to hook into.

@divmgl
Copy link

divmgl commented Oct 1, 2023

I'm running into this problem right now after clicking a MenuItem inside of a Select component if it's wrapped by an outer element which has an equivalent event.stopPropagation() and event.preventDefault() call in the onClick handler. It's a complete showstopper.

I finally looked up "mui backdrop stays open" on Google and found this thread. This solution works but it'd be nice if the backdrop didn't stay permanently open...

@spicattutti
Copy link

spicattutti commented Nov 21, 2023

I implemented the hack @doflo-dfa mentioned in our theme config, so it only applies for the backdrop. This works fine for until the issue gets fixed.

const theme = createTheme({
  // ...
  components: {
    MuiBackdrop: {
      styleOverrides: {
        root: {
          '&[style*="opacity: 0"]': {
            pointerEvents: 'none',
          },
        },
      },
    },
  },
});

I've also found a way to reproduce this bug in a specific instance. If I open https://nextjs-azalp-9294f0bzd-azalp-de.vercel.app/ in browserstack with edge 112, it gets stuck when I double-click on a sub menu item. The open state of the backdrop is controlled by a state that gets set to false on click. Only the main menu items in the blue bar have the ability to change it to true on mouse over. Can't imagine a setState setting it to false running twice could trigger this. Thats also not the only time this bug occurred. We also have reports while doing a route change with a drawer open. That one thankfully isn't as common as the one mentioned above. Hopefully this info helps finding the bug.

To pick up the aforementioned workaround, I had to use

import { backdropClasses } from "@mui/material/Backdrop";

// within createTheme

      MuiModal: {
        styleOverrides: {
          root: {
            [`&:has(> div.${backdropClasses.root}[style*="opacity: 0"])`]: {
              pointerEvents: "none",
            },
          },
        },
      },

Since for me, it was the modal and not the backdrop that blocked pointer events.

Running

"@mui/material": "5.14.4",
"next": "13.5.5",

also observing issue when transitioning to another page by using a Link in a Menu.

@dchadcluff
Copy link

This bug just started happening for my project after updating from Remix.run version 1 to version 2.4. I've used the theme hack to get by as well.

@racc-oo-n
Copy link

racc-oo-n commented Feb 26, 2024

I'm getting the same bug in e2e tests, can't reproduce it manually.
Using

"@playwright/test": "^1.41.2",
"@mui/base": "5.0.0-beta.37",
"@mui/lab": "5.0.0-alpha.165",
"@mui/material": "5.15.10",

Testing error

Call log:
  - waiting for getByRole('dialog').getByRole('button', { name: /submit/i })
  -   locator resolved to <button id=":rd:" tabindex="0" type="button" class="MuiB…>…</button>
  - attempting click action
  -   waiting for element to be visible, enabled and stable
  -   element is visible, enabled and stable
  -   scrolling into view if needed
  -   done scrolling
  -   <div aria-hidden="true" class="MuiBackdrop-root MuiBa…></div> from <div id="menu-Status" aria-hidden="true" role="presen…>…</div> subtree intercepts pointer events
  - retrying click action, attempt #1
  -   waiting for element to be visible, enabled and stable
  -   element is visible, enabled and stable
  -   scrolling into view if needed
  -   done scrolling
  -   <div aria-hidden="true" class="MuiBackdrop-root MuiBa…></div> from <div id="menu-Status" aria-hidden="true" role="presen…>…</div> subtree intercepts pointer events
  - retrying click action, attempt #2
  ...

That's happening on the Select component, but the layout is: Page > Drawer > Select. Maybe that's the reason – we have nested Backdrop components.

this solution helped #32286 (comment)

@owenashurst
Copy link

owenashurst commented Apr 6, 2024

Any solution to this? I'm routing to other pages when this issue occurs (SPA). If I click on the same menu item to route to the same page, it doesn't happen. I have to click twice elsewhere on the page for the backdrop to be removed so I can continue interacting with the page.

The interesting thing is, once I've clicked off twice, and navigate to another page using the drawer, the backdrop works as expected. It seems to be a one off occurrence. If you do a full page refresh, then the issue appears again.

EDIT: If I downgrade from React 18 to React 17 (specifically 17.0.2), I don't see the issue anymore.

@MaRaSu
Copy link

MaRaSu commented Apr 10, 2024

I run into the same issue with NextJS 13 and MUI v5, specifically on Android Chrome and Drawer-components in certain (and very repeatable) situations. I had to adapt @spicattutti solution to apply to Drawer as well:

import { backdropClasses } from "@mui/material/Backdrop";

// within createTheme

      MuiDrawer: {
        styleOverrides: {
          root: {
            [`&:has(> div.${backdropClasses.root}[style*="opacity: 0"])`]: {
              pointerEvents: "none",
            },
          },
        },
      },

@patricksculley
Copy link

patricksculley commented Apr 25, 2024

Our users are also effected by this issue (Next 14, Mui 5.15.15). The Dialog component and backdrop are still intermittently rendered on the page with a 0 opacity when the app loads , even though open={false}.

The workaround above does allow the background to be clickable but the page is not scrollable.

This makes the UI unresponsive unless the user refreshes the page. Seems to effect some users more than others.

Upvote for a fix as it makes for a poor app experience.

@elfilalime
Copy link

Hello, I am facing the same problem on React 18.2.0 with Mui 5.13.4 or 5.15.15.

I'm using the Menu component which adds BackDrop on opening as expected.

But the strange thing is that the problem never happened before and after N build it only starts happening in production when the project is built. And never in devloppement webpack serve

After 3 days of investigating to find what changes are causing the issue, I discovered that this happens when the bundle size exceeds 1.8 MiB and it has nothing to do with any code I add.

The CSS trick worked fine but the BackDrop and its container are still on DOM.

Waiting for a fix

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 Something doesn't work component: backdrop This is the name of the generic UI component, not the React module! external dependency Blocked by external dependency, we can’t do anything about it
Projects
None yet
Development

No branches or pull requests