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-labelledby
或 aria-describedby
属性的元素应用间距。
Size
Modal Dialog 组件有 3 种尺寸:sm
、md
(默认)和 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 属性 和 scroll
或 auto
值来使容纳它的容器溢出。
模态框溢出
上一节演示了如何使模态框内的内容可滚动。
要使整个模态框可滚动,以防其高于视口,请使用 Modal Overflow 组件。 它将允许 Modal Dialog 在垂直方向上溢出屏幕。
Modal Overflow 组件支持 center
和 fullScreen
内置布局。
您可以使用 Box 组件和带有 sx
属性的 CSS 来实现相同的结果。 但是,Modal Overflow 组件增加了更大的便利性
- 它使您的样式更加一致,因为您无需在不同的实例之间复制样式。
- 您还可以直接从主题对其进行主题自定义。
- 当用户单击模态框的背景时,它会自动处理关闭操作。
警告对话框
使用 role="alertdialog"
创建一个警告对话框,该对话框会中断用户的工作流程。
嵌套模态框
模态框组件可以嵌套
性能
模态框的内容在未打开时会被卸载。 这意味着每次打开时都需要重新挂载它。
如果您在模态框内渲染“昂贵”的组件树,并且想要优化交互响应速度,请通过启用 keepMounted
属性来更改默认行为。
使用 keepMounted
属性使模态框的内容可供搜索引擎使用(即使模态框已关闭)。
以下演示展示了如何应用此属性以保持模态框挂载
与任何性能优化一样,keepMounted
属性不一定会解决您的所有问题。 在实施此属性之前,请探索其他可能的性能瓶颈,您可以在这些瓶颈上做出更显着的改进。
服务端模态框
React 不支持服务器上的 createPortal()
API。 因此,为了显示在服务器上渲染的模态框,请使用 disablePortal
属性禁用 portal 功能,如下面的演示所示
服务端模态框
如果您禁用 JavaScript,您仍然会看到我。
局限性
焦点陷阱
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
请参阅下面的文档,以获取此处提及的组件的所有属性和类的完整参考。