Skip to content

Modal 对话框 ​

模态对话框,用于需要用户确认或输入的中断场景。

基础用法 ​

基础用法

打开对话框

这是一个基础对话框示例。

受控显示 ​

visible 为受控属性:由宿主(按钮 / JS)设置或移除,组件不会自动恢复;关闭后可监听 oas-ok / oas-cancel 后移除 visible。

受控显示(visible)

打开(设置 visible)关闭(移除 visible)

外部按钮直接设置 / 移除 visible 控制显隐,无需依赖底部按钮。

受控 / 非受控契约:组件自身是非受控 + 事件通知模型——用户关闭路径(遮罩 / ✕ / Esc / 取消)由组件自行移除 visible 并派发 oas-close(detail.source / detail.action 标明来源与动作),宿主上的 visible attribute 始终与真实状态同步、不会残留。声明式绑定场景(visible 由宿主 state 驱动)应在 oas-close 中把 state 置为关闭,避免关闭后 state 又把 visible 写回;若监听 oas-before-close 并 preventDefault(),则组件保持打开、visible 不动。

无底部按钮 ​

无底部按钮

打开无按钮对话框

隐藏底部操作区,仅通过 ✕ / Esc / 遮罩关闭。

禁止遮罩关闭 ​

禁止遮罩关闭

打开对话框

点击遮罩不会关闭,需通过按钮或 Esc 关闭。

自定义宽度 ​

自定义宽度

打开自定义宽度对话框

通过 width 指定对话框宽度,支持像素或百分比(如 50%),未设置时默认 520px。

垂直居中 ​

垂直居中

打开垂直居中对话框

默认对话框靠上偏移(顶部 100px),添加 centered 后垂直居中显示。

可拖拽 ​

可拖拽

打开可拖拽对话框

按住标题栏可拖动对话框;Esc、遮罩关闭与焦点行为保持不变。

全屏对话框 ​

fullscreen 让对话框铺满视口(无圆角、无外边距)。优先级定义:fullscreen 胜于 width / centered / draggable——width 被忽略、centered 无布局差异、拖拽被禁用;Esc / 遮罩关闭与焦点陷阱、ARIA 行为照常。

全屏对话框

打开全屏对话框

全屏对话框铺满视口、无圆角与边距。width / centered 被忽略、拖拽被禁用,Esc / 遮罩关闭照常。

可最大化(maximizable) ​

maximizable 在标题栏 ✕ 左侧显示最大化/还原按钮:最大化等同 fullscreen 语义(铺满视口、无圆角、width 被忽略、拖拽失效),再点还原回原尺寸;切换派发 oas-maximize(detail.maximized 标明状态)。显式设置 fullscreen 属性时按钮隐藏(宿主已强制全屏,切换无意义)。

可最大化对话框

打开可最大化对话框

点标题栏的最大化按钮铺满视口,再点还原;每次切换派发 oas-maximize(右上角消息反馈)。

命令式确认 ​

confirm() 命令式 API 基于 Promise,底层复用 oas-modal(返回 Promise<void>,确定 resolve、取消 reject)。传 onOk 异步回调可实现 loading 态确认:点击确定后 OK 按钮进入 loading(转圈、禁止重复触发),onOk resolve 后自动关闭并 resolve 外层 Promise;reject 则清除 loading、对话框保持打开可重试或取消。

命令式确认

异步确认loading 态确认

命令式确认框(modal API) ​

modal.confirm / info / success / warning / error 命令式 API 返回 { close() } 句柄,底层复用 oas-modal。选项:title、content(纯文本,杜绝 HTML 注入)、okText、cancelText、onOk、onCancel。传异步 onOk(返回 Promise)时点击确定后 OK 按钮进入 loading(转圈、禁止重复触发),resolve 自动关闭、reject 清除 loading 保持打开可重试或取消。取消按钮 / ✕ / 遮罩 / Esc 触发 onCancel 后关闭;句柄 close() 可编程关闭(不触发 onCancel)。多实例可叠放共存,destroyAllModal() 一次关闭全部;挂载到最近 oas-app 容器(无则 body)。

基础确认

基础确认自定义文案

语义变体

信息成功警告错误

异步 onOk loading

异步提交

多例与销毁全部

连开三个销毁全部

声明式语义变体 ​

命令式模块内部使用的 type / ok-text / cancel-text / no-cancel / focus-ok 均为 oas-modal 公开属性,可声明式使用。

声明式语义变体

打开成功对话框打开单按钮对话框

type 渲染语义图标;ok-text/cancel-text 自定义按钮文案;focus-ok 打开时聚焦「确定」。

no-cancel 隐藏取消按钮,底部仅剩「确定」。

事件反馈 ​

事件反馈

打开并监听事件

点击「确定」或「取消」,观察右上角消息提示。

Prompt 输入框 ​

modal.prompt(options) 命令式输入框:打开自动聚焦输入框,结果 resolve { value, action }(action:确定为 confirm,取消 / ✕ / 遮罩 / Esc 统一为 cancel)。支持 inputValue / placeholder / inputType(text / password / number / textarea)/ inputPattern(字符串正则校验,先 pattern 后 validator)/ validator(返回 true 通过、false 用默认文案、string 即错误文案)。校验失败保持打开并显示错误,输入修正后自动清除可再提交;异步 onOk 时确定按钮进入 loading。

prompt 能力(主路径已默认内含):主路径 @oas-ui/ui/feedback/modal 已内置 prompt 能力(import 即注册),无需显式引用。若想保留不含 prompt machinery 的纯核瘦身(确认/提示类消费者零开销),可改从纯核入口 @oas-ui/ui/feedback/modal/core 引入——它不含该能力,此时调用 modal.prompt 返回 null 并在 dev 控制台告警一次,需显式引用:

ts
import '@oas-ui/ui/feedback/modal/prompt'

或换回主路径。全量入口 @oas-ui/ui 与 CDN 反馈族包同样已内含。

prompt 基础输入

基础输入校验失败保持打开

prompt 进阶(textarea / password + pattern)

意见反馈(textarea)设置密码(pattern)

body 滚动锁 ​

打开时锁定 body 滚动(overflow hidden + 滚动条宽度补偿防跳动),关闭还原;多实例嵌套计数,全部关闭才解锁。no-scroll-lock 可关闭该行为。

body 滚动锁

打开并锁定滚动

打开后页面滚动被锁定;关闭后恢复。试试打开状态下滚动页面,内容不再移动。

关闭拦截(before-close) ​

监听可取消的 oas-before-close(event.detail.source 标明来源:ok / cancel / close-btn / mask / esc),preventDefault() 可阻止关闭——表单未保存等数据保护场景。命令式确认框的确定路径由 onOk Promise 控制(resolve 才关闭),取消类路径同样可被拦截。

关闭拦截

打开表单对话框

点「取消」/ ✕ / 遮罩 / Esc 都会被拦截并提示;点「保存」正常关闭。

关闭入口三开关 ​

no-esc-close(禁 Esc)、no-mask-close(禁遮罩点击)、no-close-btn(隐藏 ✕)——三个关闭入口各自独立可配,把关闭控制权交给宿主。

关闭入口三开关

打开极简对话框

Esc 与 ✕ 均不可用(遮罩点击仍可关闭),关闭入口只剩底部按钮。

slot="footer" 有内容时自动隐藏内置确定/取消按钮,底部完全由插槽接管。

footer 插槽

打开自定义底部

底部按钮由插槽完全接管(内置确定/取消自动隐藏)。

取消提交任务

运行时更新(handle.update) ​

handle.update(partialOptions) 运行时增量更新标题 / 内容 / 按钮文案,不影响已绑定的回调。

handle.update()

打开并 3 秒后更新

命令式语义 alertdialog ​

命令式确认框 / prompt 的 dialog 语义为 role="alertdialog"(读屏立即打断播报);声明式 <oas-modal> 缺省保持 dialog,可用 role 属性手动指定。

alertdialog 语义

打开 alertdialog

role="alertdialog":读屏立即打断当前播报;声明式缺省为 dialog。

遮罩样式与顶部贴边 ​

遮罩背景走 --oas-modal-mask-bg 变量(缺省 overlay token),--oas-modal-mask-blur 可选背景模糊;position="top" 让对话框贴视口顶缘(默认靠上偏移 100px,centered 时居中)。

遮罩样式 / position top

定制遮罩顶部贴边

遮罩背景来自 --oas-modal-mask-bg(此处红色 18% + 2px 模糊)。

position="top" 让对话框贴视口顶缘;默认靠上偏移 100px(centered 时垂直居中)。

层级(z-index) ​

z-index 显式覆盖默认 modal 档位(--oas-z-modal):数值叠加在 --oas-z-index-base(config-provider 浮层起始值)之上,对话框恒比遮罩高 1;缺省走默认档位。多实例叠开时可用它精确控制谁在上。

层级覆盖(z-index)

打开底层对话框(默认档位)再叠开一个 z-index=3000 的对话框

这是默认层级的对话框。点上面的按钮再叠开一个显式 z-index 的对话框,观察覆盖关系。

z-index="3000":遮罩与对话框层级显式抬升(对话框仍比遮罩高 1),盖在底层对话框之上;Esc 先关最上层。

关闭来源事件 ​

oas-close 携带 detail.source(ok / cancel / close-btn / mask / esc / programmatic)与 detail.action(confirm / cancel / close);非确定路径保留 oas-cancel(旧语义)。

关闭来源

打开并观察来源

分别用确定 / 取消 / ✕ / 遮罩 / Esc 关闭,观察右上角来源消息。

开合动画 ​

打开 / 关闭默认播放 fade + scale 动画(只走 transform/opacity,prefers-reduced-motion 下自动停用)。oas-open 在打开开始派发,oas-after-open / oas-after-close 在动画结束后派发——命令式对话框据此「等动画结束再卸载」。transition 可选预设:zoom(默认,淡入 + 缩放)/ fade(仅淡入淡出)/ none(无过渡、即时显隐)。

开合动画 + 生命周期事件

打开(观察动画与事件)

默认 fade + scale 动画;右上角消息展示 oas-after-open / oas-after-close(动画结束才派发)。

transition 预设(fade / none)

fade(仅透明度)none(即时显隐)

transition="fade":只做透明度过渡,不做缩放。

transition="none":打开 / 关闭即时显隐(适合高性能或降级场景)。

点击位置动画原点 ​

打开瞬间会记录触发指针的位置,对话框从该点向外展开(transform-origin 指向点击处);键盘 / 编程打开时回退居中展开。

点击位置动画原点

点这里打开(动画从按钮处展开)

缩放动画的原点跟随最近一次点击位置:从你点击的按钮处向外展开,而不是固定在中心。

非模态(no-mask) ​

no-mask:遮罩不渲染 + 焦点陷阱关闭 + 打开不抢焦点(语义对齐原生 <dialog>.show(),适合通知 / 画布辅助等非中断场景)。关闭通道照常(✕ / 底部按钮 / Esc;Esc 可另行用 no-esc-close 关闭)。

no-mask 非模态

打开非模态对话框

无遮罩、焦点不被圈禁——页面其余部分仍可交互(试试打开后点页面上的按钮)。

拖拽钳制(keep in viewport) ​

对话框可拖拽时,坐标被钳制在视口内(默认开启):即使大幅拖动也不会整框拖出视口找不回。

拖拽钳制

打开并拖拽

按住标题栏随便拖:对话框始终留在视口内(右 / 下边缘被钳住),不会拖出找不回。

声明式 trigger ​

trigger="元素id" 把任意页面元素绑定为打开触发器:点击该元素即 setAttribute('visible')(纯语法糖,不改变受控模型——关闭仍需宿主移除 visible)。

声明式 trigger

点我打开(trigger 绑定)

这个按钮没有写任何 onclick——由 oas-modal 的 trigger 属性自动绑定点击打开。

尺寸预设与全屏断点 ​

size 预设档位:sm(400px)/ lg(720px),显式 width 优先。fullscreen-breakpoint="800":视口宽度低于阈值自动进入全屏(拖宽视口自动还原),移动端窄屏适配无需 JS 监听。

尺寸预设 sm / lg

size=smsize=lg

size="sm":宽度 400px。

size="lg":宽度 720px。

fullscreen-breakpoint

打开(把窗口缩窄到 800px 以下试试)

fullscreen-breakpoint="800":视口宽度低于 800px 自动铺满全屏(无圆角、忽略宽度);拉宽后自动还原为常规对话框。

回车确认(confirm-on-enter) ​

confirm-on-enter(显式开启,默认关):弹窗内没有文本输入控件时按 Enter 触发「确定」(loading 中忽略;焦点在按钮上时交还按钮原生激活,避免重复触发)。适合快速确认类对话框。

confirm-on-enter

打开(先点内容区再回车)

点击正文空白处让焦点离开按钮,再按 Enter —— 等同点击「确定」。弹窗内若放了输入框,Enter 不会被劫持。

拦截抖动反馈(shake) ​

oas-before-close 被 preventDefault() 拦截(数据保护等场景)时,对话框播放一次水平抖动提示「这条关闭路径不可用」;动画结束后自动移除,可重复触发。

shake 防误关反馈

打开并尝试关闭

此对话框拦截取消类关闭:点「取消」/ ✕ / Esc 会看到对话框抖动提示,不会真的关闭。

自定义关闭图标(close-icon 插槽) ​

slot="close-icon" 覆盖默认 ✕,富内容自定义关闭图标(aria-label 语义保持)。

close-icon 插槽

打开自定义关闭图标

右上角关闭图标由插槽接管(此处为自定义样式)。

✕

options 选项模式 ​

modal.options({ items, type }) 命令式选择框:确认框内嵌选项组,结果 resolve { value, action }。type:radio(单选,value 为字符串)/ checkbox(多选,数组)/ toggle(开关组,数组);支持 disabled 项、异步 onOk loading、close() / update() 句柄(与 prompt 同形态)。

options 单选 / 多选 / 开关

单选(radio)多选(checkbox)开关组(toggle)

渲染策略 ​

destroy-on-close 关闭后清空内容节点(下次打开前重新填充);append-to 把对话框挂载到指定容器(突破宿主 overflow 裁切)。

destroy-on-close / append-to

destroy-on-closeappend-to

关闭后内容被清空;再次打开前由按钮重新填充。

对话框已挂载到 body 级容器(portal),即使宿主在 overflow:hidden 容器内也不被裁切。

焦点陷阱与滚动锁开关 ​

initial-focus 指定打开时聚焦的元素(CSS 选择器,面板内优先、其次 light DOM,无匹配回退默认焦点);no-focus-trap 关闭 Tab 焦点圈禁(焦点交给宿主自管的场景);no-scroll-lock 关闭 body 滚动锁(页面可继续滚动)。

initial-focus / no-focus-trap / no-scroll-lock

打开即聚焦输入框

打开后焦点直接落在输入框(initial-focus);不圈禁 Tab、不锁页面滚动。

媒体区(media 插槽) ​

slot="media" 提供正文顶部的媒体区(图标 / 插图 / 缩略图等富媒体),有内容才显示——未提供内容时该区域不渲染、不占位。

media 媒体插槽

打开带媒体区对话框

顶部媒体区来自 slot="media";未提供内容时该区域不渲染、不留白。

sticky-footer 让正文区在 --oas-modal-body-max-height(默认 60vh)内滚动,页脚常驻对话框底部、不随正文滚走(全屏态自动豁免该限高)。默认关闭——不设时布局与原来完全一致;可在宿主上覆盖该变量调整正文滚动区高度。

sticky-footer 页脚吸底

打开长内容对话框

正文很长(此块高 90vh):正文区在限定高度内滚动,底部按钮始终吸底可见。

API ​

方法 ​

方法说明
modal.confirm({ title?, content?, okText?, cancelText?, onOk?, onCancel? })打开确认框(确定/取消双按钮),返回 { close }
modal.info(options) / modal.success(options) / modal.warning(options) / modal.error(options)语义确认框:对应图标 + 单「确定」按钮,返回 { close }
modal.prompt({ title?, inputValue?, placeholder?, inputType?, validator?, onOk? })输入框确认:结果 resolve { value, action },返回 Promise & { close, update }
modal.options({ title?, content?, items?, type?, okText?, cancelText?, onOk? })选项选择框(type:radio / checkbox / toggle):结果 resolve { value, action }(radio 单个字符串;checkbox/toggle 数组),返回 Promise & { close, update }
destroyAllModal()关闭并销毁全部命令式确认框(等各自关闭动画结束)
  • 选项:{ title?, content?, okText?, cancelText?, onOk?, onCancel? }。content 为纯文本;onOk 返回 Promise 时确定按钮进入 loading(resolve 关闭、reject 保持打开可重试或取消)。
  • 返回 { close() } 句柄:编程关闭当前实例,不触发 onOk / onCancel。
  • 挂载到最近 oas-app 容器(无则 body);多实例可叠放;命令式实例在关闭动画结束(oas-after-close)后才卸载。

oas-modal ​

属性 ​

属性说明类型默认值
append-toportal 挂载点:把遮罩与对话框移入目标容器(body 或 CSS 选择器)内的独立 shadow(样式作用域保真),脱离宿主 overflow 裁剪;属性移除/无匹配时移回宿主 shadow——
cancel-text取消按钮文案;缺省走 locale modal.cancel——
centered对话框垂直居中显示boolean—
confirm-on-enter显式开启后回车触发确定(仅最上层响应;弹窗内无文本输入控件且焦点不在按钮/链接等原生交互控件上才生效,防双触发;默认关闭)boolean—
destroy-on-close关闭动画完成后清空宿主子内容(下次打开重新渲染)boolean—
draggable可通过标题栏拖动对话框boolean—
focus-ok打开时焦点移入「确定」按钮(默认移入「取消」按钮)boolean—
fullscreen全屏显示:对话框铺满视口、无圆角与边距(优先级高于 width / centered / draggable)boolean—
fullscreen-breakpoint视口宽度低于该阈值(px)时自动全屏(打开期间随 resize 重算;与显式 fullscreen 取并集)——
initial-focus打开时聚焦指定选择器元素(对话框内优先,其次宿主 light DOM);未设置回落 focus-ok / 取消按钮 / 确定 / ✕——
loading确定按钮进入 loading 态(禁用 + 转圈),禁止重复触发确定boolean—
maximizable标题栏显示最大化/还原按钮:最大化等同 fullscreen 语义,再点还原;显式 fullscreen 下隐藏boolean—
no-cancel隐藏取消按钮(底部仅剩「确定」;语义变体确认框内置)boolean—
no-close-btn隐藏标题栏 ✕ 关闭按钮boolean—
no-esc-close禁用 Esc 关闭(Esc 仅由最上层可见 modal 响应)boolean—
no-focus-trap关闭焦点陷阱(Tab 不再圈定在对话框内)boolean—
no-footer隐藏底部操作按钮boolean—
no-mask无遮罩非模态:遮罩不渲染、焦点陷阱关闭、打开时不抢焦点(对齐 HTML dialog.show(),可与页面其余部分交互)boolean—
no-mask-close禁用点击遮罩关闭boolean—
no-scroll-lock打开时不锁定 body 滚动(默认锁定时带滚动条宽度补偿,防布局跳动)boolean—
ok-text确定按钮文案;缺省走 locale modal.ok——
position垂直定位:top 贴视口顶缘;缺省距顶 100px;与 centered 同设时 top 规则后置生效——
role对话框 ARIA 角色(默认 dialog;语义变体确认场景可设 alertdialog)stringdialog
size尺寸预设:sm(400px)/ lg(720px);width 显式值优先;非法值回落主题默认 520pxModalSizePreset—
sticky-footer页脚吸底:正文区在 --oas-modal-body-max-height(默认 60vh)内滚动、页脚常驻对话框底部不随正文滚走;全屏态(data-fullscreen)自动豁免该限高。默认关闭——不设时布局不变(非破坏)——
title标题文案(渲染进可见标题区;读取后即从宿主移除,不残留原生悬浮提示;清空传空串);富内容用 slot="title"string—
transition开合动画预设:zoom(默认,淡入 + 缩放,缩放原点跟随打开前的点击位置)/ fade(仅透明度)/ none(无过渡即时显隐)——
trigger声明式触发元素 id:点击该元素设置 visible 打开弹窗(不动受控模型);元素不存在时静默,后续 update 重试——
type语义变体:info/success/warning/error,正文顶部渲染对应语义图标ModalVariant—
visible是否显示boolean—
width对话框宽度(px 或百分比)——
z-index显式层级基准(叠加在 --oas-z-index-base 之上,对话框比遮罩高 1;缺省走 --oas-z-modal 档位)——

事件 ​

事件说明
oas-after-close关闭动画完成(规范名,对齐 after-* 家族),detail 无;destroy-on-close 清空内容在此之后
oas-after-open打开动画完成(规范名,对齐 after-* 家族),detail 无;等价 oas-opened
oas-before-close关闭请求前派发(确定/取消/✕/遮罩/Esc),cancelable,detail: { source };preventDefault 阻止关闭并触发对话框 shake 提示(programmatic 关闭绕过拦截)
oas-cancel取消:取消按钮 / ✕ / 遮罩点击 / Esc
oas-close开始关闭时派发,detail: { source, action }(source: ok/cancel/close-btn/mask/esc/programmatic;action: confirm/cancel/close)
oas-closed【兼容别名】关闭动画完成,等价 oas-after-close;后续版本移除
oas-maximize最大化/还原切换时派发,detail: { maximized }
oas-ok点击「确定」
oas-open开始打开时派发(锁滚动、焦点移入之后),detail 无
oas-opened【兼容别名】打开动画完成,等价 oas-after-open;后续版本移除

插槽 ​

名称说明
默认对话框主体内容
close-icon自定义关闭图标(替代默认 ✕)
description描述文案(标题下方说明)
footer底部操作区
media媒体区插槽(图标 / 插图 / 缩略图等富媒体),正文顶部居中;有内容才显示,无内容不占位
title标题富内容插槽,有内容时覆盖 title 属性文案

CSS 变量 ​

CSS 变量默认值
--oas-glass-blurnone
--oas-glass-ringtransparent
--oas-modal-body-max-height60vh
--oas-modal-mask-bgvar(--oas-color-overlay)
--oas-modal-mask-blur0px
--oas-modal-max-height90vh
--oas-modal-origin-xcenter
--oas-modal-origin-ycenter

role="dialog" + aria-modal="true",打开时焦点移入「取消」按钮(focus-ok 时移入「确定」按钮),关闭后还原。

基于 MIT OR Apache-2.0 双许可发布