iter(g98): 弹窗与抽屉补遮罩关闭开关
This commit is contained in:
@@ -1140,6 +1140,14 @@
|
|||||||
"acceptance": "npm run changelog 重新生成(267 提交),changelog:check 一致(提交本条后按约定再差一条);npm run check 全绿",
|
"acceptance": "npm run changelog 重新生成(267 提交),changelog:check 一致(提交本条后按约定再差一条);npm run check 全绿",
|
||||||
"notes": "自补:发版前刷新步骤,收尾统一执行",
|
"notes": "自补:发版前刷新步骤,收尾统一执行",
|
||||||
"status": "done"
|
"status": "done"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "g98",
|
||||||
|
"title": "弹窗与抽屉补遮罩关闭开关",
|
||||||
|
"motivation": "modal/drawer 点遮罩必关,表单类弹窗填到一半误触就丢内容;调用方没有任何开关能保留 × 与 Esc 的同时禁掉遮罩关闭",
|
||||||
|
"acceptance": "ModalProps / DrawerProps 新增 closeOnOverlay(缺省 true);传 false 时点遮罩不关闭,× 与 Esc 行为不变;文档参数表与演示(防误关弹窗实例)同步;npm run check 全绿",
|
||||||
|
"notes": "自补:可用性;遮罩点击处理改成显式卫语句,语义比一长串 && 更清楚",
|
||||||
|
"status": "open"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "ui-arch-registry-index/0.1",
|
"$schema": "ui-arch-registry-index/0.1",
|
||||||
"generatedAt": "2026-10-26T05:14:42.470Z",
|
"generatedAt": "2026-10-26T05:15:56.401Z",
|
||||||
"repoRoot": ".",
|
"repoRoot": ".",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
@@ -1578,6 +1578,11 @@
|
|||||||
"t": "unknown",
|
"t": "unknown",
|
||||||
"d": "底部操作区内容(常见为按钮组,右对齐);缺省不渲染"
|
"d": "底部操作区内容(常见为按钮组,右对齐);缺省不渲染"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"n": "closeOnOverlay",
|
||||||
|
"t": "boolean",
|
||||||
|
"d": "点遮罩是否关闭弹窗;缺省 true,表单类可传 false 防误关(× 与 Esc 仍可用)"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"n": "onClose",
|
"n": "onClose",
|
||||||
"t": "() => void",
|
"t": "() => void",
|
||||||
@@ -1634,6 +1639,11 @@
|
|||||||
"t": "unknown",
|
"t": "unknown",
|
||||||
"d": "底部操作区内容;缺省不渲染"
|
"d": "底部操作区内容;缺省不渲染"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"n": "closeOnOverlay",
|
||||||
|
"t": "boolean",
|
||||||
|
"d": "点遮罩是否关闭抽屉;缺省 true(× 与 Esc 始终可用)"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"n": "onClose",
|
"n": "onClose",
|
||||||
"t": "() => void",
|
"t": "() => void",
|
||||||
|
|||||||
+13
-1
@@ -140,6 +140,7 @@ const name = signal('');
|
|||||||
const agreed = signal(false);
|
const agreed = signal(false);
|
||||||
const nightMode = signal(true);
|
const nightMode = signal(true);
|
||||||
const sheetOpen = signal(false); // 底部抽屉开合
|
const sheetOpen = signal(false); // 底部抽屉开合
|
||||||
|
const stickyOpen = signal(false); // 防误关弹窗开合
|
||||||
const sound = signal(true); // 无可见文案的开关演示
|
const sound = signal(true); // 无可见文案的开关演示
|
||||||
const city = signal('');
|
const city = signal('');
|
||||||
const size = signal('m');
|
const size = signal('m');
|
||||||
@@ -445,10 +446,21 @@ const content = h(
|
|||||||
section(
|
section(
|
||||||
'sec-tabs-modal',
|
'sec-tabs-modal',
|
||||||
'标签页与弹窗',
|
'标签页与弹窗',
|
||||||
'tabs 滑动指示条 + 方向键切换(←→),禁用页签置灰;modal 支持 Esc / 遮罩 / × 关闭,弹窗内的下拉展开时 Esc 先收下拉、再按才关弹窗(逐层关闭)。',
|
'tabs 滑动指示条 + 方向键切换(←→),禁用页签置灰;modal 支持 Esc / 遮罩 / × 关闭(closeOnOverlay: false 时点遮罩不关、防填一半误触),弹窗内的下拉展开时 Esc 先收下拉、再按才关弹窗(逐层关闭)。',
|
||||||
tabs({ tabs: [{ value: 'a', label: '概览' }, { value: 'b', label: '明细' }, { value: 'c', label: '设置' }, { value: 'd', label: '已停用', disabled: true }], active: activeTab }),
|
tabs({ tabs: [{ value: 'a', label: '概览' }, { value: 'b', label: '明细' }, { value: 'c', label: '设置' }, { value: 'd', label: '已停用', disabled: true }], active: activeTab }),
|
||||||
h('span', { class: 'out' }, () => `当前页签:${activeTab()}`),
|
h('span', { class: 'out' }, () => `当前页签:${activeTab()}`),
|
||||||
button({ label: '打开弹窗', onClick: () => modalOpen(true) }),
|
button({ label: '打开弹窗', onClick: () => modalOpen(true) }),
|
||||||
|
button({ label: '打开防误关弹窗', variant: 'ghost', onClick: () => stickyOpen(true) }),
|
||||||
|
modal(
|
||||||
|
{
|
||||||
|
title: '填写中,点遮罩不关闭',
|
||||||
|
open: stickyOpen,
|
||||||
|
closeOnOverlay: false,
|
||||||
|
onClose: () => stickyOpen(false),
|
||||||
|
footer: h('div', { class: 'row' }, button({ label: '关闭', variant: 'ghost', onClick: () => stickyOpen(false) })),
|
||||||
|
},
|
||||||
|
h('p', null, 'closeOnOverlay: false —— 点遮罩不会关闭,防止填到一半误触丢失内容;× 与 Esc 仍然有效。'),
|
||||||
|
),
|
||||||
modal(
|
modal(
|
||||||
{
|
{
|
||||||
title: '确认操作',
|
title: '确认操作',
|
||||||
|
|||||||
+3
-1
@@ -1,6 +1,6 @@
|
|||||||
# @ui-arch 组件库 Agent 文档(无图形版)
|
# @ui-arch 组件库 Agent 文档(无图形版)
|
||||||
|
|
||||||
> 自动生成于 2026-10-26T05:14:42.470Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。
|
> 自动生成于 2026-10-26T05:15:56.401Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。
|
||||||
> 组件 = 普通函数,传 props 返回 DOM;状态用 signal 双向绑定:读 signal() 写 signal(v)。
|
> 组件 = 普通函数,传 props 返回 DOM;状态用 signal 双向绑定:读 signal() 写 signal(v)。
|
||||||
|
|
||||||
## 快速上手
|
## 快速上手
|
||||||
@@ -842,6 +842,7 @@ const page = signal(1); pagination({ page, pageSize: 3, total: 24, onChange: (p)
|
|||||||
- title(必填):string —— 标题
|
- title(必填):string —— 标题
|
||||||
- size(默认 md):'sm' | 'md' | 'lg' —— 宽度档位:sm 340px / md 420px / lg 640px;缺省 md
|
- size(默认 md):'sm' | 'md' | 'lg' —— 宽度档位:sm 340px / md 420px / lg 640px;缺省 md
|
||||||
- footer:unknown —— 底部操作区内容(常见为按钮组,右对齐);缺省不渲染
|
- footer:unknown —— 底部操作区内容(常见为按钮组,右对齐);缺省不渲染
|
||||||
|
- closeOnOverlay:boolean —— 点遮罩是否关闭弹窗;缺省 true,表单类可传 false 防误关(× 与 Esc 仍可用)
|
||||||
- onClose(回调):() => void —— 关闭回调(点遮罩、× 或 Esc 触发)
|
- onClose(回调):() => void —— 关闭回调(点遮罩、× 或 Esc 触发)
|
||||||
- ...children:unknown[] —— 弹窗内容子节点
|
- ...children:unknown[] —— 弹窗内容子节点
|
||||||
|
|
||||||
@@ -871,6 +872,7 @@ const open = signal(false); modal({ title: '确认操作', open, onClose: () =>
|
|||||||
- placement(默认 right):'left' | 'right' | 'top' | 'bottom' —— 滑出方向;缺省 right
|
- placement(默认 right):'left' | 'right' | 'top' | 'bottom' —— 滑出方向;缺省 right
|
||||||
- width(默认 320):number —— 面板尺寸(像素):左右滑出为宽度,上下滑出为高度;缺省 320
|
- width(默认 320):number —— 面板尺寸(像素):左右滑出为宽度,上下滑出为高度;缺省 320
|
||||||
- footer:unknown —— 底部操作区内容;缺省不渲染
|
- footer:unknown —— 底部操作区内容;缺省不渲染
|
||||||
|
- closeOnOverlay:boolean —— 点遮罩是否关闭抽屉;缺省 true(× 与 Esc 始终可用)
|
||||||
- onClose(回调):() => void —— 关闭回调(点遮罩 / × / Esc 触发)
|
- onClose(回调):() => void —— 关闭回调(点遮罩 / × / Esc 触发)
|
||||||
- ...children:unknown[] —— 面板内容子节点
|
- ...children:unknown[] —— 面板内容子节点
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ export function drawer(props: DrawerProps, ...children: unknown[]): HTMLElement
|
|||||||
const overlay = h('div', {
|
const overlay = h('div', {
|
||||||
class: () => `ua-drawer-overlay${props.open() ? ' ua-open' : ''}`,
|
class: () => `ua-drawer-overlay${props.open() ? ' ua-open' : ''}`,
|
||||||
onClick: (e: Event) => {
|
onClick: (e: Event) => {
|
||||||
if (e.target === overlay) close(); // 卫语句:仅点遮罩本身关闭
|
if (e.target !== overlay) return; // 卫语句:只处理点在遮罩本身的
|
||||||
|
if (props.closeOnOverlay === false) return; // 显式禁止时防误关,× 与 Esc 仍可用
|
||||||
|
close();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const panel = h(
|
const panel = h(
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ export function modal(props: ModalProps, ...children: unknown[]): HTMLElement {
|
|||||||
const overlay = h('div', {
|
const overlay = h('div', {
|
||||||
class: 'ua-modal-overlay',
|
class: 'ua-modal-overlay',
|
||||||
onClick: (e: Event) => {
|
onClick: (e: Event) => {
|
||||||
if (e.target === overlay) close(); // 卫语句:仅点遮罩本身关闭
|
if (e.target !== overlay) return; // 卫语句:只处理点在遮罩本身的
|
||||||
|
if (props.closeOnOverlay === false) return; // 显式禁止时防误关,× 与 Esc 仍可用
|
||||||
|
close();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const box = h(
|
const box = h(
|
||||||
|
|||||||
@@ -336,6 +336,7 @@ export interface ModalProps {
|
|||||||
open: Signal<boolean>; // 开关信号:true 显示 / false 隐藏
|
open: Signal<boolean>; // 开关信号:true 显示 / false 隐藏
|
||||||
size?: 'sm' | 'md' | 'lg'; // 宽度档位;缺省 md(420px),sm 340px / lg 640px
|
size?: 'sm' | 'md' | 'lg'; // 宽度档位;缺省 md(420px),sm 340px / lg 640px
|
||||||
footer?: unknown; // 底部操作区内容(常见为按钮组);缺省不渲染
|
footer?: unknown; // 底部操作区内容(常见为按钮组);缺省不渲染
|
||||||
|
closeOnOverlay?: boolean; // 点遮罩是否关闭;缺省 true(表单类弹窗可传 false 防误关,× 与 Esc 仍可用)
|
||||||
onClose?: () => void; // 关闭回调(点遮罩、× 或 Esc 触发)
|
onClose?: () => void; // 关闭回调(点遮罩、× 或 Esc 触发)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,6 +347,7 @@ export interface DrawerProps {
|
|||||||
placement?: 'left' | 'right' | 'top' | 'bottom'; // 滑出方向;缺省 right
|
placement?: 'left' | 'right' | 'top' | 'bottom'; // 滑出方向;缺省 right
|
||||||
width?: number; // 面板尺寸像素:左右滑出为宽度,上下滑出为高度;缺省 320
|
width?: number; // 面板尺寸像素:左右滑出为宽度,上下滑出为高度;缺省 320
|
||||||
footer?: unknown; // 底部操作区内容;缺省不渲染
|
footer?: unknown; // 底部操作区内容;缺省不渲染
|
||||||
|
closeOnOverlay?: boolean; // 点遮罩是否关闭;缺省 true(× 与 Esc 始终可用)
|
||||||
onClose?: () => void; // 关闭回调(遮罩 / × / Esc 触发)
|
onClose?: () => void; // 关闭回调(遮罩 / × / Esc 触发)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1449,6 +1449,11 @@
|
|||||||
"t": "unknown",
|
"t": "unknown",
|
||||||
"d": "底部操作区内容(常见为按钮组,右对齐);缺省不渲染"
|
"d": "底部操作区内容(常见为按钮组,右对齐);缺省不渲染"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"n": "closeOnOverlay",
|
||||||
|
"t": "boolean",
|
||||||
|
"d": "点遮罩是否关闭弹窗;缺省 true,表单类可传 false 防误关(× 与 Esc 仍可用)"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"n": "onClose",
|
"n": "onClose",
|
||||||
"t": "() => void",
|
"t": "() => void",
|
||||||
@@ -1505,6 +1510,11 @@
|
|||||||
"t": "unknown",
|
"t": "unknown",
|
||||||
"d": "底部操作区内容;缺省不渲染"
|
"d": "底部操作区内容;缺省不渲染"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"n": "closeOnOverlay",
|
||||||
|
"t": "boolean",
|
||||||
|
"d": "点遮罩是否关闭抽屉;缺省 true(× 与 Esc 始终可用)"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"n": "onClose",
|
"n": "onClose",
|
||||||
"t": "() => void",
|
"t": "() => void",
|
||||||
|
|||||||
Reference in New Issue
Block a user