跳到内容
+

Modal

模态框组件为创建对话框、弹出框、灯箱或其他任何内容提供了坚实的基础。

简介

Joy UI 提供了三个与模态框相关的组件

  • Modal:一个容器,在其背景组件前面渲染其 children 节点。
  • ModalClose:用于关闭模态框的按钮。
  • ModalDialog:用于渲染模态对话框的组件。
<Modal>
  <ModalDialog>
    <ModalClose />
    <Typography>Modal title</Typography>
  </ModalDialog>
</Modal>

示例


特性

  • 🥞 在需要多个模态框时管理模态框堆叠。
  • 🪟 自动创建一个背景元素,以禁用与应用程序其余部分的交互。
  • 🔐 在打开时禁用页面滚动。
  • ⌨️ 正确管理模态框及其父应用程序之间的焦点。
  • ♿️ 自动添加适当的 ARIA 角色。

组件

安装之后,您可以使用以下基本元素开始构建此组件

import Modal from '@mui/joy/Modal';

export default function MyApp() {
  return <Modal>{children}</Modal>;
}

基本用法

Modal 组件仅接受单个 React 元素作为子元素。 它可以是 Joy UI 组件,例如 Sheet,或任何其他自定义元素。

使用 Modal Close 组件渲染一个关闭按钮,该按钮继承模态框的 onClose 函数。

关闭原因

onClose 的第二个参数为您提供有关事件如何触发的信息。

可能的值是

  • backdropClick:用户单击模态框的背景。
  • escapeKeyDown:用户在键盘上按下 Escape 键。
  • closeClick:用户单击 ModalClose 元素。

要创建模态对话框,请在 Modal 组件内渲染 Modal Dialog 组件。

Dialog 组件将对具有 aria-labelledbyaria-describedby 属性的元素应用间距。

Variant

Modal Dialog 组件支持全局变体功能。

Modal Close 组件的变体自动调整以与 Modal Dialog 形成对比,如下所示

Size

Modal Dialog 组件有 3 种尺寸:smmd(默认)和 lg

Modal Close 和 Modal Dialog Title 组件继承 Modal Dialog 的尺寸,除非在每个组件中直接指定。

布局

Modal Dialog 的布局可以是

  • center(默认):模态对话框出现在视口中心。
  • fullScreen:模态对话框覆盖整个视口。

要添加更多布局,请使用 styleOverrides 创建新主题,如下所示

const theme = extendTheme({
  components: {
    JoyModalDialog: {
      defaultProps: { layout: 'top' },
      styleOverrides: {
        root: ({ ownerState }) => ({
          ...(ownerState.layout === 'top' && {
            top: '12vh',
            left: '50%',
            transform: 'translateX(-50%)',
          }),
        }),
      },
    },
  },
});

对于 TypeScript,您需要模块增强功能才能将新值包含到 layout 属性中

// at the root or theme file
declare module '@mui/joy/ModalDialog' {
  interface ModalDialogPropsLayoutOverrides {
    top: true;
  }
}

垂直滚动

默认情况下,当 Modal Dialog 中的内容高度大于视口时,内容不会溢出屏幕。

为确保您的内容可见,请通过添加 overflow CSS 属性scrollauto 值来使容纳它的容器溢出。

上一节演示了如何使模态框的内容可滚动。

要使整个模态框可滚动,以防其高于视口,请使用 Modal Overflow 组件。 它将允许 Modal Dialog 在垂直方向上溢出屏幕。

Modal Overflow 组件支持 centerfullScreen 内置布局。

您可以使用 Box 组件和带有 sx 属性的 CSS 来实现相同的结果。 但是,Modal Overflow 组件增加了更大的便利性

  • 它使您的样式更加一致,因为您无需在不同的实例之间复制样式。
  • 您还可以直接从主题对其进行主题自定义。
  • 当用户单击模态框的背景时,它会自动处理关闭操作。

警告对话框

使用 role="alertdialog" 创建一个警告对话框,该对话框会中断用户的工作流程。

嵌套模态框

模态框组件可以嵌套

过渡效果

模态框组件带有内置过渡效果。

这是一个使用 react-transition-group 创建淡入动画的示例

性能

模态框的内容在未打开时会被卸载。 这意味着每次打开时都需要重新挂载它。

如果您在模态框内渲染“昂贵”的组件树,并且想要优化交互响应速度,请通过启用 keepMounted 属性来更改默认行为。

使用 keepMounted 属性使模态框的内容可供搜索引擎使用(即使模态框已关闭)。

以下演示展示了如何应用此属性以保持模态框挂载

与任何性能优化一样,keepMounted 属性不一定会解决您的所有问题。 在实施此属性之前,请探索其他可能的性能瓶颈,您可以在这些瓶颈上做出更显着的改进。

服务端模态框

React 不支持服务器上的 createPortal() API。 因此,为了显示在服务器上渲染的模态框,请使用 disablePortal 属性禁用 portal 功能,如下面的演示所示

常见示例

移动端模态框

使用带有 theme.breakpoints.only('xs')sx 属性来自定义模态对话框的样式,使其在移动视口中固定在底部。

局限性

焦点陷阱

MUI Base Modal 如果焦点试图逃脱,则会将焦点移回组件的主体。

这样做是为了可访问性目的,但可能会给您的用户带来问题。

如果用户需要与页面的另一部分进行交互——例如,在父应用程序中打开模态框时与聊天机器人窗口进行交互——您可以禁用带有 disableEnforceFocus 属性的默认行为。

可访问性

有关可访问性最佳实践的完整详细信息,请参阅 WAI-ARIA 关于对话框(模态框)模式的指南。 以下是一些亮点

  • 所有交互式元素都必须具有可访问的名称。 使用 aria-labelledby="id..." 为您的 Modal 组件提供一个可访问的名称。 您还可以使用 aria-describedby="id..." 来提供 Modal 的描述

    <Modal aria-labelledby="modal-title" aria-describedby="modal-description">
      <h2 id="modal-title">My Title</h2>
      <p id="modal-description">My Description</p>
    </Modal>
    
  • 遵循 WAI-ARIA 创作实践,以帮助您根据模态框的内容将初始焦点设置在最相关的元素上。

无样式

使用 Base UI Modal 完全拥有组件的设计,而无需覆盖 Material UI 或 Joy UI 样式。 此组件的无样式版本是重度自定义和更小捆绑包大小的理想选择。

API

请参阅下面的文档,以获取此处提及的组件的所有属性和类的完整参考。