跳到主要內容
+

Modal

modal 元件為建立對話框、彈出視窗、燈箱或任何其他內容提供了堅實的基礎。

簡介

Joy UI 提供了三個與 modal 相關的組件

  • Modal:一個容器,在其背景組件前方呈現其 children 節點。
  • ModalClose:用於關閉 modal 的按鈕。
  • ModalDialog:用於呈現 modal 對話框的組件。
<Modal>
  <ModalDialog>
    <ModalClose />
    <Typography>Modal title</Typography>
  </ModalDialog>
</Modal>

Playground


功能

  • 🥞 管理多個 modal 時的 modal 堆疊。
  • 🪟 自動建立背景元素以停用與應用程式其餘部分的互動。
  • 🔐 開啟時停用頁面滾動。
  • ⌨️ 正確管理 modal 及其父應用程式之間的焦點。
  • ♿️ 自動新增適當的 ARIA 角色。

組件

安裝後,您可以使用以下基本元素開始建構此組件

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

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

基本用法

Modal 僅接受單個 React 元素作為子元素。它可以是 Joy UI 組件,例如 Sheet,或任何其他自訂元素。

使用 Modal Close 組件來呈現一個關閉按鈕,該按鈕繼承 modal 的 onClose 函數。

關閉原因

onClose 的第二個參數會提供有關事件如何觸發的資訊。

可能的值為

  • backdropClick:使用者點擊 modal 的背景。
  • escapeKeyDown:使用者在鍵盤上按下 Escape 鍵。
  • closeClick:使用者點擊 ModalClose 元素。

若要建立 modal 對話框,請在 Modal 內呈現 Modal Dialog 組件。

Dialog 將對具有 aria-labelledbyaria-describedby 屬性的元素應用間距。

變體

Modal Dialog 支援全域變體功能。

Modal Close 組件的變體會自動調整以與 Modal Dialog 形成對比,如下所示

尺寸

Modal Dialog 提供 3 種尺寸:smmd(預設)和 lg

Modal Close 和 Modal Dialog Title 組件繼承 Modal Dialog 的尺寸,除非在每個組件中直接指定。

佈局

Modal Dialog 的版面配置可以是

  • center(預設):modal 對話框出現在視窗的中心。
  • fullScreen:modal 對話框覆蓋整個視窗。

若要新增更多版面配置,請使用 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 內部的內容可滾動。

若要使整個 modal 可滾動,以防其高於視窗,請使用 Modal Overflow 組件。它將允許 Modal Dialog 在垂直方向上溢出螢幕。

Modal Overflow 支援 centerfullScreen 內建版面配置。

您可以使用 Box 組件和 CSS 以及 sx 屬性來達到相同的結果。但是,Modal Overflow 組件增加了更大的便利性

  • 它使您的樣式設定更加一致,因為您無需跨不同實例複製樣式。
  • 您也可以直接從主題將主題自訂新增到其中。
  • 當使用者點擊 Modal 的背景時,它會自動處理關閉動作。

警示對話框

使用 role="alertdialog" 建立一個警示對話框,以中斷使用者的工作流程。

巢狀 Modals

modal 組件可以巢狀

過渡效果

modal 組件包含內建的過渡效果。

以下是使用 react-transition-group 建立淡入淡出動畫的一個範例

效能

modal 的內容在未開啟時會卸載。這表示每次開啟時都需要重新掛載。

如果您在 modal 內部呈現「昂貴」的組件樹,並且想要針對互動回應性進行最佳化,請啟用 keepMounted 屬性來變更預設行為。

使用 keepMounted 屬性使 modal 的內容可供搜尋引擎使用(即使 modal 已關閉)。

以下示範展示如何應用此屬性以保持 modal 掛載

與任何效能最佳化一樣,keepMounted 屬性不一定能解決您的所有問題。在實作此屬性之前,請探索其他可能的效能瓶頸,您可以在這些瓶頸上進行更顯著的改進。

伺服器端 modal

React 不支援伺服器上的 createPortal() API。因此,為了顯示在伺服器上呈現的 modal,請使用 disablePortal 屬性停用 portal 功能,如下面的示範所示

常見範例

行動裝置 modal

sx 屬性與 theme.breakpoints.only('xs') 搭配使用,以自訂 modal 對話框的樣式,使其在行動裝置視窗中貼在底部。

限制

焦點陷阱

如果焦點嘗試逃脫 MUI Base Modal,它會將焦點移回組件的主體。

這是為了協助工具目的而完成的,但可能會為您的使用者帶來問題。

如果使用者需要與頁面的另一部分互動,例如,在父應用程式中開啟 modal 時與聊天機器人視窗互動,您可以使用 disableEnforceFocus 屬性停用預設行為。

無障礙功能

請參閱 WAI-ARIA 關於對話框(Modal)模式的指南,以取得有關無障礙功能最佳實務的完整詳細資訊。以下是一些重點

  • 所有互動式元素都必須具有可存取的名稱。使用 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 製作實務,以協助您根據 modal 的內容將初始焦點設定在最相關的元素上。

無樣式

使用 Base UI Modal 完全擁有組件設計的所有權,而無需覆寫 Material UI 或 Joy UI 樣式。此組件的無樣式版本是大量自訂和更小套件大小的理想選擇。

API

請參閱以下文件,以取得此處提及的組件可用的所有屬性和類別的完整參考。