Material-UI的Dialog如何允许在dialog后面进行交互?

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

我在我的 React 应用程序中使用 Material-UI,并且我有一个 Dialog 在我单击按钮后出现在多个表单元素上。

我还设置了该对话框,允许使用 react-draggable 拖动它。

当对话框显示时,它后面的 none 个表单元素是可以访问的 。我意识到阻止与对话框后面的元素的交互在直觉上是有意义的。

但是,我正在尝试弄清楚如何显示对话框,同时仍然能够编辑它后面的表单元素。

代码示例here:

有谁知道是否可以显示 MaterialUI 对话框并且仍然能够与对话框后面的表单元素交互(即,当对话框被拖走时)?

该对话框旨在阻止所有其他交互,以便用户可以专注于其内容。无论如何,我找到了一个解决方案,可能不是更好但在这里工作,代码是这样的:

<Dialog
  hideBackdrop // Disable the backdrop color/image
  disableEnforceFocus // Let the user focus on elements outside the dialog
  style={{ position: 'initial' }} // This was the key point, reset the position of the dialog, so the user can interact with other elements
  disableBackdropClick // Remove the backdrop click (just to be sure)
  ...
>
  ...
</Dialog>

Here a working example

这是可能的,而且不会太麻烦!当对话框打开时,它的根容器是 div,class 为 MuiDialog-root,直接在您的 <body> 中生成。我们没有将 react-draggable 组件放在对话框的 PaperComponent 周围,而是放在整个对话框周围:

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

然后,有必要稍微调整一下对话框的样式。我们需要确保禁用背景,然后减小容器大小,这样当我们在它后面单击时,我们实际上是在选择其他组件:

<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>

注意 PaperComponent 属性。根据可拖动对话框的 material-ui docs,这是指保存对话框内容的表面。但是,我们需要创建此组件来设置样式,而不是将纸张包装在 <Draggable> 中。如果我们不这样做,PaperComponent 将有大的、令人讨厌的边距,并且不能正确地适合其父级。

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

一定要把这个函数放在渲染组件之外。否则,每次状态改变时,你的对话框内容都会被重新加载。这对我来说很糟糕,因为我在对话框中使用了自动完成字段,每次我选择一个选项并使用 onChange() 进行操作时,文本输入都会消失。更改功能范围解决了这个问题。

禁用强制聚焦也会扰乱原点和位置 使用禁用自动对焦

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