Drawer 抽屉
从屏幕边缘滑出的浮层面板,常用于筛选条件、详情信息、表单编辑等场景。
四向滑出
placement 支持 left / right / top / bottom 四向;横向管宽、纵向管高——width / size 在 top/bottom 下作用于面板高度。
四向 placement
从顶部滑出;`size="small"` 此时把高度设为 256px。
从底部滑出,移动端操作面板的主流形态。
状态:全部
分类:全部
排序:创建时间
右侧是默认方向,点击遮罩、关闭按钮或按 Esc 均可关闭。
纵向高度(height)
height 直接指定 top/bottom 抽屉的高度(优先于 width / size 的纵向映射;左右抽屉静默忽略该属性)。支持纯数字(视为 px)与长度/百分比。
纵向高度(height)
height="40vh":高度为视口的 40%,比默认 320px 更高。
height="280":纯数字视为像素。
动画与生命周期事件
打开/关闭有过渡动画(transform/opacity,prefers-reduced-motion 下自动降级为直切)。生命周期事件:oas-open / oas-after-open / oas-close(detail 含关闭来源)/ oas-after-close。
生命周期事件
操作下方按钮/遮罩/Esc,观察右上角事件消息(`oas-close` 会带上关闭来源)。
取消语义事件(oas-cancel)
取消语义关闭(取消按钮 / 遮罩点击 / Esc)派发 oas-cancel(detail.source 标明来源),与确认关闭(oas-ok)区分;✕ / 手势 / 编程关闭不派发。可在取消时清理临时状态或打点。
取消语义事件
点「取消」/ 遮罩 / Esc 关闭 → 右上角提示 oas-cancel;点「保存」→ 提示 oas-ok;✕ 两者都不提示。
关闭拦截(before-close)
监听可取消的 oas-before-close(event.detail.source 标明关闭来源),preventDefault() 可阻止关闭——表单未保存等数据保护场景。
关闭拦截
点「放弃」/ ✕ / 遮罩 / Esc 都会被拦截:提示「有未保存的修改」并保持打开。点「保存」正常关闭。
自定义底部 / 头部扩展
footer 插槽有内容时自动隐藏内置确定/取消按钮;header-actions 插槽在标题右侧渲染扩展操作区;ok-text / cancel-text 可覆盖按钮文案。
插槽与文案
标题右侧的标签来自 `header-actions` 插槽。
loading 与确定按钮异步态
loading 在内容区显示骨架占位并禁用按钮(详情异步加载);ok-loading 让确定按钮进入 loading(转圈 + 防重复触发),配合异步提交。
loading / 确定异步态
内容异步加载中,此段会被骨架占位。
点「提交」后确定按钮进入 loading,2 秒后自动关闭并提示成功。
拖拽调宽(resizable)
resizable 在面板自由边显示拖拽条,可拖拽或方向键调整宽度/高度(resize-min / resize-max 钳制),结束派发 oas-resize。
拖拽调宽
拖拽面板左侧边缘的竖条调宽(也可用方向键),释放后右上角提示新宽度。
移动端手势:拖拽关闭 + 吸附点
swipeable 开启拖拽关闭(把手/标题栏起手,超过阈值或快速滑动即关);底部抽屉配 snap-points(视口比例或像素)可在释放后吸附最近点。
底部手势抽屉
拖拽顶部把手:释放后吸附到 40% / 85% 视口高度;拖过阈值或快速滑动即关闭。
向下拖拽把手即可关闭。
命令式 API
drawer(options) 免模板即时开启,返回 { close() } 句柄;onOk 返回 Promise 时自动管理确定按钮 loading。
命令式开启
嵌套抽屉
多个抽屉叠开时自动栈管理:后开者层级更高(z-index 递增),Esc 逐层关闭,焦点陷阱只作用于最上层。
嵌套层级
在外层里再打开一个内层抽屉,观察层级叠加。
内层抽屉盖在外层之上;按 Esc 先关内层,再按一次关外层。
渲染与挂载策略
destroy-on-close 关闭动画结束后清空内容(下次打开重新初始化);append-to 把面板挂载到指定容器(突破 overflow 裁切)。
destroy-on-close / append-to
关闭后内容被清空,下次打开前重新填充(见下方演示按钮)。
面板已挂载到 body 级容器,即使宿主处于 overflow:hidden 容器内也不被裁切。
标题区 / 关闭按钮 / Esc 开关
no-header 隐藏整个标题区、no-close-btn 隐藏 ✕、no-esc-close 禁用 Esc 关闭——把关闭入口的控制权交给宿主。
入口开关
无标题、无 ✕、Esc 不关——只能通过下方按钮或遮罩点击关闭(遮罩点击仍有效)。
初始焦点
initial-focus 指定打开时聚焦的元素(CSS 选择器,面板内优先、其次 light DOM);无匹配回退 ✕。
初始焦点
受控显示
visible 为受控属性:由宿主(按钮 / JS)设置或移除;关闭后可通过监听事件移除 visible。
受控显示(visible)
外部按钮直接设置 / 移除 `visible` 控制显隐,无需依赖底部按钮。
受控 / 非受控契约:组件自身是非受控 + 事件通知模型——用户关闭路径(遮罩 / ✕ / Esc / 取消)由组件自行移除 visible 并派发 oas-close(detail.source 标明来源),宿主上的 visible attribute 始终与真实状态同步、不会残留。声明式绑定场景(visible 由宿主 state 驱动)应在 oas-close 中把 state 置为关闭,避免关闭后 state 又把 visible 写回;若监听 oas-before-close 并 preventDefault(),则组件保持打开、visible 不动。
无底部按钮 / 禁止遮罩关闭
no-footer / no-mask-close
隐藏底部操作区,仅保留 ✕ 与 Esc 关闭入口。
点击遮罩不会关闭,需通过 ✕ / Esc 或底部按钮关闭。
无遮罩模式(no-mask)
no-mask 无遮罩模式:不渲染遮罩层(页面不变暗、不被拦截),点击抽屉外部任意区域仍可关闭(沿用遮罩点击的 mask 取消语义,派发 oas-close / oas-cancel)。适合侧边工具面板、常驻筛选栏等需要看到页面内容的轻量场景;与 no-mask-close 同设时点外部不关(关闭入口只留 ✕ / Esc / 按钮)。非模态语义对齐 dialog.show():aria-modal="false"、打开不抢焦点、Tab 不圈禁、关闭不归还焦点;焦点语义以打开瞬间的 no-mask 状态为准(运行期增删该属性只影响 aria 与焦点陷阱,不改变已打开抽屉的焦点归还行为)。
无遮罩模式
页面无遮罩变暗;点击抽屉外部任意区域即关闭(Esc 与 ✕ 照常可用)。
尺寸档位
尺寸档位
small 档:256px,适合窄屏辅助信息。
large 档:736px,适合复杂表单或详情场景。
焦点陷阱 / 滚动锁 / 层级开关
no-focus-trap 关闭 Tab 焦点圈禁(适合抽屉内嵌于宿主弹窗、焦点交给外层管理的场景);no-scroll-lock 关闭 body 滚动锁(页面可继续滚动);z-index 显式指定面板层级档位(缺省走 overlay 档 + 栈深偏移)。
no-focus-trap / no-scroll-lock / z-index
此抽屉不圈禁 Tab 焦点、不锁页面滚动,层级显式指定为 z-index="10";✕ / Esc / 遮罩关闭照常。
事件绑定(onoas-*)
抽屉事件可在模板上直接经 onoas-* 属性绑定(onoas-ok / onoas-close / onoas-open …),等价于宿主框架里的 @oas-ok 监听。
事件反馈
点「确定」或「取消」/ ✕,观察右上角消息提示。
API
oas-drawer
属性
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
append-to | portal 挂载点:把遮罩与面板移入目标容器(body 或 CSS 选择器)内的独立 shadow(样式作用域保真),脱离宿主 overflow 裁剪;属性移除/无匹配时移回宿主 shadow | — | — |
cancel-text | 取消按钮文案;缺省走 locale drawer.cancel | — | — |
destroy-on-close | 关闭动画完成后清空宿主子内容(下次打开重新渲染) | boolean | — |
height | 纵向抽屉(placement=top/bottom)显式高度,优先于 width/size;左右抽屉忽略 | — | — |
initial-focus | 打开时聚焦指定选择器元素(面板内优先,其次宿主 light DOM);未设置回落 ✕ 关闭按钮/首个可聚焦元素 | — | — |
loading | 内容加载态:主体隐藏并显示骨架占位,确定/取消按钮同时禁用 | boolean | — |
no-close-btn | 隐藏标题栏 ✕ 关闭按钮 | boolean | — |
no-esc-close | 禁用 Esc 关闭 | boolean | — |
no-focus-trap | 关闭焦点陷阱(Tab 不再圈定在抽屉内) | boolean | — |
no-footer | 隐藏底部操作按钮 | boolean | — |
no-header | 隐藏整个标题区(同时移除 aria-labelledby 可访问名关联) | boolean | — |
no-mask | 无遮罩模式:不渲染遮罩,点击外部仍关闭(沿用 mask 取消语义) | boolean | — |
no-mask-close | 禁用点击遮罩关闭 | boolean | — |
no-scroll-lock | 打开时不锁定 body 滚动 | boolean | — |
ok-loading | 确定按钮 loading 态:转 spinner + 禁用(aria-busy),阻止重复触发 | boolean | — |
ok-text | 确定按钮文案;缺省走 locale drawer.ok | — | — |
placement | 滑出方向 | string | right |
resizable | 显示边缘拖拽条:指针拖拽调整主轴尺寸(随 placement 取宽/高),方向键微调 ±8px,Home/End 跳 min/max | boolean | — |
resize-max | 拖拽调整上限(px,默认 1000) | string | 1000 |
resize-min | 拖拽调整下限(px,默认 160) | string | 160 |
size | 预设尺寸档位或具体值:small(256px)/ medium(378px)/ large(736px),或直接写如 512px、40% | — | — |
snap-points | 吸附点数组(逗号分隔;≤1 视为视口高度比例,>1 为像素,如 0.35,0.6):bottom/top 抽屉拖拽释放后吸附最近点,打开初始吸附最高点;bottom + snap-points 隐含启用手势 | — | — |
swipeable | 启用手势:从拖拽把手/标题栏拖拽关闭(位移超面板尺寸 35% 或快速甩动判定关闭);snap-points(bottom/top)隐含开启 | boolean | — |
title | 标题文案(渲染进可见标题区;读取后即从宿主移除,不残留原生悬浮提示;清空传空串);富内容用 slot="title" | string | — |
visible | 是否显示 | boolean | — |
width | 抽屉宽度(px 或百分比),优先级高于 size | — | — |
z-index | 显式层级基准:叠加在 --oas-z-index-base 之上(面板比遮罩高 1);缺省走 overlay 档位 --oas-z-overlay,嵌套打开时随栈深递增 | — | — |
事件
| 事件 | 说明 |
|---|---|
oas-after-close | 关闭动画完成(规范名,对齐 after-* 家族),detail 无;滚动解锁与焦点归还在此之后 |
oas-after-open | 打开动画完成(规范名,对齐 after-* 家族),detail 无;等价 oas-opened |
oas-before-close | 关闭请求前派发(✕/取消/遮罩/Esc/确定/手势),cancelable,detail: { source },preventDefault 阻止关闭 |
oas-cancel | 取消语义关闭(取消钮/遮罩/Esc)时派发,detail: { source } |
oas-close | 关闭:取消按钮 / ✕ / 遮罩点击 / Esc,detail: { source } |
oas-closed | 【兼容别名】关闭动画完成,等价 oas-after-close;后续版本移除 |
oas-ok | 点击「确定」 |
oas-open | 开始打开时派发(锁滚动后、初始聚焦前),detail 无 |
oas-opened | 【兼容别名】打开动画完成,等价 oas-after-open;后续版本移除 |
oas-resize | 拖拽调整尺寸 / 方向键微调 / snap 吸附后派发,detail: { size }(当前主轴尺寸 px) |
插槽
| 名称 | 说明 |
|---|---|
| 默认 | 抽屉主体内容 |
footer | 底部操作区 |
header-actions | 标题栏右侧操作区 |
title | 标题富内容插槽,有内容时覆盖 title 属性文案 |
CSS 变量
| CSS 变量 | 默认值 |
|---|---|
--oas-glass-blur | none |
--oas-glass-ring | transparent |
role="dialog" + aria-modal="true";打开时移入焦点(默认 ✕,可 initial-focus 指定),关闭后归还来源焦点。