'How can Material-UI's Dialog allow interaction behind the dialog?

I am using Material-UI in my React app, and I have a Dialog that appears over several form elements after I click a button.

I also have that dialog set to allow it to be dragged using react-draggable.

When the dialog is showing, none of the form elements behind it are ale to be accessed. I realize it intuitively makes sense to block interaction with the elements behind the dialog.

However, I am trying to figure out how to have the dialog showing, and yet still being able to edit the form elements behind it.

Code example here:

Does anyone know if it's possible to show a MaterialUI Dialog and still be able to interact with form elements behind the dialog (ie, when the dialog is dragged away)?



Solution 1:[1]

It is possible, and without too much trouble! When the Dialog is opened, its root container is a div with a class of MuiDialog-root, spawned directly in your <body>. Instead of putting the react-draggable component around the dialog's PaperComponent, we put it around the entire dialog:

<Draggable 
  handle={'[class*="MuiDialog-root"]'} 
  cancel={'[class*="MuiDialogContent-root"]'}>
    <Dialog 
      // Styling goes here
     > 
     ... // Dialog contents
    </Dialog>
</Draggable>

Then, it's necessary to style the Dialog a little. We need to make sure to disable the backdrop, then bring the container size down so that when we click behind it, we are actually selecting other components:

<Dialog
    open={open}
    onClose={handleClose}
    disableEnforceFocus // Allows other things to take focus
    hideBackdrop  // Hides the shaded backdrop
    disableBackdropClick  // Prevents backdrop clicks
    PaperComponent={PaperComponent}
    style={{
        top: '30%', // Position however you like
        left: '30%',
        height: 'fit-content',  // Ensures that the dialog is 
        width: 'fit-content',   // exactly the same size as its contents
    }}
    >
...
</Dialog>

Note the PaperComponent property. As per the material-ui docs on draggable dialogs, this refers to the surface that holds the dialog contents. However, instead of wrapping the paper in a <Draggable>, we need to create this component for styling. If we don't, the PaperComponent will have large, obnoxious margins and won't fit properly in its parent.

function PaperComponent(props: PaperProps) { 
// PaperProps is an import from '@material-ui/core'
    return (
        <Paper {...props} style={{ margin: 0, maxHeight: '100%' }} />
    );
}

Be sure to place this function outside of the rendering component. Otherwise, every time the state changes, your dialog contents will be remounted. This was bad for me because I was using an Autocomplete field in the dialog, and every time I selected an option and did something with the onChange(), the text input would disappear. Changing the function scope fixed this problem.

Solution 2:[2]

disabling enforce focus can also disturb the origin and position Use disableAutoFocus

<Dialog
    hideBackdrop={true}
    disableBackdropClick
    disableAutoFocus
    ...
>
    ....
</Dialog>
    
    

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 April
Solution 2 Priyanshu Dwivedi