JGuang / HeroUI

Modal 模态框

用于聚焦用户交互与重要内容的对话框遮罩层。

引入

import { Modal } from "@heroui/react";

用法

HeroUI 示例

组件结构

导入 Modal 组件后,可通过点语法访问所有子部分。

import {Modal, Button} from "@heroui/react";

export default () => (
  <Modal>
    <Button>Open Modal</Button>
    <Modal.Backdrop>
      <Modal.Container>
        <Modal.Dialog>
          <Modal.CloseTrigger /> {/* Optional: Close button */}
          <Modal.Header>
            <Modal.Icon /> {/* Optional: Icon */}
            <Modal.Heading />
          </Modal.Header>
          <Modal.Body />
          <Modal.Footer />
        </Modal.Dialog>
      </Modal.Container>
    </Modal.Backdrop>
  </Modal>
);

位置

HeroUI 示例

遮罩变体

HeroUI 示例

尺寸

HeroUI 示例

自定义遮罩

HeroUI 示例

关闭行为

HeroUI 示例

关闭方式

HeroUI 示例

滚动行为

HeroUI 示例

受控状态

HeroUI 示例

带表单

HeroUI 示例

自定义触发器

HeroUI 示例

自定义动画

HeroUI 示例

自定义 Portal

HeroUI 示例

样式

传入 Tailwind CSS 类

import {Modal, Button} from "@heroui/react";

function CustomModal() {
  return (
    <Modal>
      <Button>Open Modal</Button>
      <Modal.Backdrop className="bg-black/80">
        <Modal.Container className="items-start pt-20">
          <Modal.Dialog className="bg-linear-to-br from-purple-500 to-pink-500 text-white">
            <Modal.CloseTrigger />
            <Modal.Header>
              <Modal.Heading>Custom Styled Modal</Modal.Heading>
            </Modal.Header>
            <Modal.Body>
              <p>This modal has custom styling applied via Tailwind classes</p>
            </Modal.Body>
            <Modal.Footer>
              <Button slot="close">Close</Button>
            </Modal.Footer>
          </Modal.Dialog>
        </Modal.Container>
      </Modal.Backdrop>
    </Modal>
  );
}

自定义组件类

要自定义 Modal 的组件类,可使用 @layer components 指令。

了解更多。

@layer components {
  .modal__backdrop {
    @apply bg-gradient-to-br from-black/50 to-black/70;
  }

  .modal__dialog {
    @apply rounded-2xl border border-white/10 shadow-2xl;
  }

  .modal__header {
    @apply text-center;
  }

  .modal__close-trigger {
    @apply rounded-full bg-white/10 hover:bg-white/20;
  }
}

HeroUI 遵循 BEM 方法论,确保组件变体与状态可复用且易于自定义。

CSS 类

Modal 使用以下 CSS 类(查看源码样式):

基础类

  • .modal__trigger — 打开 Modal 的触发元素
  • .modal__backdrop — Modal 背后的遮罩层
  • .modal__container — 支持 placement 的定位包裹层
  • .modal__dialog — Modal 内容容器
  • .modal__header — 标题与图标区域
  • .modal__body — 主内容区域
  • .modal__footer — 操作区域
  • .modal__close-trigger — 关闭按钮元素

遮罩变体

  • .modal__backdrop--opaque — 不透明有色遮罩(默认)
  • .modal__backdrop--blur — 带玻璃效果的模糊遮罩
  • .modal__backdrop--transparent — 透明遮罩(无叠加层)

滚动变体

  • .modal__container--scroll-outside — 允许整个 Modal 滚动
  • .modal__dialog--scroll-inside — 限制 Modal 高度,由 body 区域滚动
  • .modal__body--scroll-inside — 仅 body 区域可滚动
  • .modal__body--scroll-outside — 允许整页滚动

交互状态

组件支持以下交互状态:

  • 焦点::focus-visible 或 [data-focus-visible="true"] — 应用于触发器、对话框与关闭按钮
  • 悬停::hover 或 [data-hovered="true"] — 应用于关闭按钮悬停
  • 按下::active 或 [data-pressed="true"] — 应用于关闭按钮按下
  • 进入:[data-entering] — Modal 打开动画期间
  • 离开:[data-exiting] — Modal 关闭动画期间
  • 位置:[data-placement="*"] — 基于 Modal 位置(auto、top、center、bottom)

API 参考

Prop类型默认值描述
childrenReactNode-触发器与容器元素

Modal.Trigger

Prop类型默认值描述
childrenReactNode-自定义触发内容
classNamestring-CSS 类

Modal.Backdrop

Prop类型默认值描述
variant"opaque" | "blur" | "transparent""opaque"遮罩叠加样式
isDismissablebooleantrue点击遮罩是否关闭
isKeyboardDismissDisabledbooleanfalse是否禁用 ESC 关闭
isOpenboolean-受控打开状态
onOpenChange(isOpen: boolean) => void-打开状态变化处理函数
classNamestring | (values) => string-遮罩 CSS 类
UNSTABLE_portalContainerHTMLElement-自定义 portal 容器

Modal.Container

Prop类型默认值描述
placement"auto" | "center" | "top" | "bottom""auto"Modal 在屏幕上的位置
scroll"inside" | "outside""inside"滚动行为
size"xs" | "sm" | "md" | "lg" | "cover" | "full""md"Modal 尺寸变体
classNamestring | (values) => string-容器 CSS 类

Modal.Dialog

Prop类型默认值描述
childrenReactNode | ({close}) => ReactNode-内容或渲染函数
classNamestring | (values) => string-CSS 类
rolestring"dialog"ARIA role
aria-labelstring-无障碍标签
aria-labelledbystring-标签元素的 id
aria-describedbystring-描述元素的 id

Modal.Header

Prop类型默认值描述
childrenReactNode-头部内容
classNamestring-CSS 类

Modal.Body

Prop类型默认值描述
childrenReactNode-正文内容
classNamestring-CSS 类

Modal.Footer

Prop类型默认值描述
childrenReactNode-底部内容
classNamestring-CSS 类

Modal.CloseTrigger

Prop类型默认值描述
childrenReactNode-自定义关闭按钮
classNamestring | (values) => string-CSS 类

useOverlayState Hook

import {useOverlayState} from "@heroui/react";

const state = useOverlayState({
  defaultOpen: false,
  onOpenChange: (isOpen) => console.log(isOpen),
});

state.isOpen; // 当前状态
state.open(); // 打开 modal
state.close(); // 关闭 modal
state.toggle(); // 切换状态
state.setOpen(); // 直接设置状态

无障碍

实现 WAI-ARIA Dialog 模式:

  • 焦点陷阱:焦点锁定在 Modal 内
  • 键盘:ESC 关闭(启用时)、Tab 在元素间循环
  • 屏幕阅读器:正确的 ARIA 属性
  • 滚动锁定:打开时禁用 body 滚动

本地来源: vendor/zh/react/components/(overlays)/modal.mdx

文档根据 HeroUI v3 固定提交生成,已调整内部链接与交互预览以适配 JGuang。

On this page