Free pack

Dialog <mv-dialog>

带动画的原生 <dialog> 模态框;还涵盖 Alert Dialog(持久)、Sheet(四个方向)以及可滑动关闭的移动端 Drawer。

分类浮层
类型Web Component(<mv-dialog>)
状态稳定版
Keywordsmodal, dialog, alert-dialog, confirm, sheet, drawer, side-panel, slide-over, swipe

When to use

  • A blocking confirmation is needed before a destructive or irreversible action
  • A short form or detail view must stay in context without leaving the page
  • A side sheet must slide in from an edge for settings, filters or a cart
  • On mobile, a bottom drawer the user can swipe away fits better than a centered modal

Avoid when

  • The message is transient feedback that shouldn't interrupt the user → use Toast instead
  • The content is a small panel anchored to a trigger that shouldn't block the page → use Popover instead
  • The flow has many steps or needs its own URL; use a dedicated page instead

安装

node scripts/add.mjs dialog --out ./src/marvelous

使用 Marvelous UI MCP 服务器的 AI 智能体:install_components({ slugs: ["dialog"], target_dir: "<absolute path>/src/marvelous", framework: "react" })。

复制的文件(包括依赖):tokens/tokens.css、core/base.css、core/dom.js、core/element.js、core/motion.js、components/dialog/dialog.js、components/dialog/dialog.css。

用法

标准标记,可在此基础上通过属性、data-* 和 CSS 变量进行定制:

<div style="display:flex;flex-wrap:wrap;gap:.75rem;justify-content:center">
  <mv-dialog>
    <button class="mv-button" data-mv-open>Edit profile</button>
    <dialog>
      <button class="mv-dialog-close" data-mv-close aria-label="Close"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M18 6 6 18M6 6l12 12"/></svg></button>
      <header class="mv-dialog-header">
        <h2 class="mv-dialog-title">Edit profile</h2>
        <p class="mv-dialog-description">Changes are saved when you click Save.</p>
      </header>
      <form method="dialog" style="display:grid;gap:.75rem">
        <label style="display:grid;gap:.35rem;font-size:.875rem">Name
          <input class="mv-input" value="Ada Lovelace">
        </label>
        <div class="mv-dialog-footer">
          <button type="button" class="mv-button" data-variant="outline" data-mv-close>Cancel</button>
          <button class="mv-button" value="save">Save</button>
        </div>
      </form>
    </dialog>
  </mv-dialog>

  <mv-dialog persistent>
    <button class="mv-button" data-variant="destructive" data-mv-open>Delete…</button>
    <dialog style="--mv-dialog-width:26rem">
      <header class="mv-dialog-header">
        <h2 class="mv-dialog-title">Delete project?</h2>
        <p class="mv-dialog-description">This action can’t be undone. All data will be lost.</p>
      </header>
      <div class="mv-dialog-footer">
        <button class="mv-button" data-variant="outline" data-mv-close="cancel">Cancel</button>
        <button class="mv-button" data-variant="destructive" data-mv-close="confirm">Delete</button>
      </div>
    </dialog>
  </mv-dialog>

  <mv-dialog>
    <button class="mv-button" data-variant="outline" data-mv-open>Side panel</button>
    <dialog data-variant="sheet" data-side="right">
      <button class="mv-dialog-close" data-mv-close aria-label="Close"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M18 6 6 18M6 6l12 12"/></svg></button>
      <header class="mv-dialog-header">
        <h2 class="mv-dialog-title">Filters</h2>
        <p class="mv-dialog-description">Slides in from the right.</p>
      </header>
    </dialog>
  </mv-dialog>

  <mv-dialog swipe>
    <button class="mv-button" data-variant="outline" data-mv-open>Mobile drawer</button>
    <dialog data-variant="sheet" data-side="bottom">
      <header class="mv-dialog-header">
        <h2 class="mv-dialog-title">Drawer</h2>
        <p class="mv-dialog-description">Swipe down to close it.</p>
      </header>
      <div style="height:30vh"></div>
    </dialog>
  </mv-dialog>
</div>

API

Attributes

Name类型Description
openbooleanOpens/closes the modal.
persistentbooleanAlert mode: no closing via Escape or outside click, role=alertdialog (follows later changes).
swipebooleanSwipe to close (sheets / drawers); can be turned on or off at any time.

Methods

NameDescription
show()Opens as a modal.
close(returnValue?)Closes with a return value.

Events

NameDescription
mv-before-openCancelable (preventDefault).
mv-openAfter opening.
mv-closedetail.returnValue: value of the [data-mv-close] button, or “dismiss” / “swipe”.

Content structure

NameDescription
[data-mv-open]Internal trigger; for an external one: data-mv-open="#id".
<dialog>Content; data-variant="sheet" + data-side="right|left|top|bottom". May be rendered or replaced after the element connects (Angular, a late v-if): it is looked up when needed, and a pending open applies once it exists.
[data-mv-close]Closes; its value becomes returnValue.

CSS classes

NameDescription
mv-dialog-header / -title / -description / -footer / -closeContent layout.

CSS variables

NameDefaultDescription
--mv-dialog-width30remWidth (sheet: 24rem).
--mv-dialog-radiusRadius.
--mv-dialog-backdrop-blur3pxBackdrop blur.

Accessibility

Focus trapped and restored by the native <dialog>, inert page, Escape. aria-labelledby/-describedby wired automatically from .mv-dialog-title / .mv-dialog-description, checked again at each opening so a title rendered late by a framework is still used.

本页面由 AI 翻译。报告翻译问题