iter(g96): 抽屉支持上下滑出方位

This commit is contained in:
HIsheR
2026-10-26 13:15:00 +08:00
parent 6e6860abab
commit 306fd90ab7
8 changed files with 52 additions and 14 deletions
+8
View File
@@ -1124,6 +1124,14 @@
"acceptance": "StatisticProps 新增 countdown(目标时间戳毫秒),传了即每秒显示 DD 天 HH:MM:SS(不足一天省天数),value 转为可选;到点或组件被移除后自动 clearInterval,不留常驻定时器;倒计时不走滚动动画;文档与演示同步;npm run check 全绿",
"notes": "自补:功能补齐;停表条件放在 tick 内自检 isConnected,无需额外卸载钩子",
"status": "done"
},
{
"id": "g96",
"title": "抽屉支持上下滑出方位",
"motivation": "drawer 的 placement 只有 left/right,移动端最常见的「底部弹层」只能拿 modal 或者自己写 fixed 容器凑,既丢了焦点陷阱与 Esc 栈,样式也不统一",
"acceptance": "placement 扩到 'left' | 'right' | 'top' | 'bottom';上下滑出时 width 语义变为高度、横向自动铺满(max-width 放开),入场位移走 translateY,四条方位共用同一套遮罩/焦点陷阱/Esc 栈;文档与演示(底部抽屉实例)同步;npm run check 全绿",
"notes": "自补:组件能力补齐;只加 CSS 分支与一个三元表达尺寸,逻辑零改动",
"status": "open"
}
]
}
+3 -3
View File
@@ -1,6 +1,6 @@
{
"$schema": "ui-arch-registry-index/0.1",
"generatedAt": "2026-10-26T05:13:47.565Z",
"generatedAt": "2026-10-26T05:14:42.470Z",
"repoRoot": ".",
"packages": [
{
@@ -1619,14 +1619,14 @@
},
{
"n": "placement",
"t": "'left' | 'right'",
"t": "'left' | 'right' | 'top' | 'bottom'",
"d": "滑出方向;缺省 right",
"df": "right"
},
{
"n": "width",
"t": "number",
"d": "面板宽度像素(窄屏最多 92vw);缺省 320",
"d": "面板尺寸(像素):左右滑出为宽度,上下滑出为高度;缺省 320",
"df": "320"
},
{
+10 -2
View File
@@ -139,6 +139,7 @@ const name = signal('');
// —— 表单控件状态集中声明 ——
const agreed = signal(false);
const nightMode = signal(true);
const sheetOpen = signal(false); // 底部抽屉开合
const sound = signal(true); // 无可见文案的开关演示
const city = signal('');
const size = signal('m');
@@ -279,8 +280,11 @@ const content = h(
section(
'sec-drawer',
'抽屉',
'drawer:open 信号驱动侧滑面板,保留主视图上下文;遮罩 / × / Esc 关闭。',
button({ label: '打开抽屉', onClick: () => drawerOpen(true) }),
'drawer:open 信号驱动侧滑面板,保留主视图上下文;四向滑出(左右按宽度、上下按高度),遮罩 / × / Esc 关闭。',
h('div', { class: 'row' },
button({ label: '从右侧打开', onClick: () => drawerOpen(true) }),
button({ label: '从底部打开', variant: 'ghost', onClick: () => sheetOpen(true) }),
),
drawer(
{
title: '订单详情',
@@ -292,6 +296,10 @@ const content = h(
h('p', null, '这里是抽屉内容,可放任意 DOM。'),
h('div', { class: 'row' }, tag({ label: '#A1024', variant: 'info' }), badge({ label: '已发货', variant: 'success' })),
),
drawer(
{ title: '快捷操作', open: sheetOpen, placement: 'bottom', width: 220, onClose: () => sheetOpen(false) },
h('p', null, '从底部滑出的操作面板:适合移动端底部弹层,宽度自动铺满、高度由 width 指定。'),
),
),
section(
'sec-tag',
+3 -3
View File
@@ -1,6 +1,6 @@
# @ui-arch 组件库 Agent 文档(无图形版)
> 自动生成于 2026-10-26T05:13:47.565Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。
> 自动生成于 2026-10-26T05:14:42.470Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。
> 组件 = 普通函数,传 props 返回 DOM;状态用 signal 双向绑定:读 signal() 写 signal(v)。
## 快速上手
@@ -868,8 +868,8 @@ const open = signal(false); modal({ title: '确认操作', open, onClose: () =>
- title(必填):string —— 标题
- open(必填):Signal<boolean> —— 开关信号:true 滑出 / false 收起
- placement(默认 right):'left' | 'right' —— 滑出方向;缺省 right
- width(默认 320):number —— 面板宽度像素(窄屏最多 92vw);缺省 320
- placement(默认 right):'left' | 'right' | 'top' | 'bottom' —— 滑出方向;缺省 right
- width(默认 320):number —— 面板尺寸(像素):左右滑出为宽度,上下滑出为高度;缺省 320
- footer:unknown —— 底部操作区内容;缺省不渲染
- onClose(回调):() => void —— 关闭回调(点遮罩 / × / Esc 触发)
- ...children:unknown[] —— 面板内容子节点
+1 -1
View File
@@ -22,7 +22,7 @@ export function drawer(props: DrawerProps, ...children: unknown[]): HTMLElement
'aside',
{
class: `ua-drawer ua-drawer-${props.placement ?? 'right'}`,
style: `width:${props.width ?? 320}px`,
style: `${props.placement === 'top' || props.placement === 'bottom' ? 'height' : 'width'}:${props.width ?? 320}px`, // 上下滑出改高度
role: 'dialog',
'aria-labelledby': titleId,
'aria-hidden': () => String(!props.open()),
+2 -2
View File
@@ -343,8 +343,8 @@ export interface ModalProps {
export interface DrawerProps {
title: string; // 标题
open: Signal<boolean>; // 开关信号:true 滑出 / false 收起
placement?: 'left' | 'right'; // 滑出方向;缺省 right
width?: number; // 面板宽度像素;缺省 320
placement?: 'left' | 'right' | 'top' | 'bottom'; // 滑出方向;缺省 right
width?: number; // 面板尺寸像素:左右滑出为宽度,上下滑出为高度;缺省 320
footer?: unknown; // 底部操作区内容;缺省不渲染
onClose?: () => void; // 关闭回调(遮罩 / × / Esc 触发)
}
+2 -2
View File
@@ -1490,14 +1490,14 @@
},
{
"n": "placement",
"t": "'left' | 'right'",
"t": "'left' | 'right' | 'top' | 'bottom'",
"d": "滑出方向;缺省 right",
"df": "right"
},
{
"n": "width",
"t": "number",
"d": "面板宽度像素(窄屏最多 92vw);缺省 320",
"d": "面板尺寸(像素):左右滑出为宽度,上下滑出为高度;缺省 320",
"df": "320"
},
{
+23 -1
View File
@@ -1576,8 +1576,30 @@ button.ua-step-dot:hover {
border-right: 1px solid var(--ua-color-border);
transform: translateX(-100%);
}
.ua-drawer-top,
.ua-drawer-bottom {
left: 0;
right: 0;
bottom: auto;
max-width: none;
border-left: none;
border-bottom: 1px solid var(--ua-color-border);
}
.ua-drawer-top {
top: 0;
transform: translateY(-100%);
}
.ua-drawer-bottom {
top: auto;
bottom: 0;
border-bottom: none;
border-top: 1px solid var(--ua-color-border);
transform: translateY(100%);
}
.ua-drawer-overlay.ua-open .ua-drawer-right,
.ua-drawer-overlay.ua-open .ua-drawer-left {
.ua-drawer-overlay.ua-open .ua-drawer-left,
.ua-drawer-overlay.ua-open .ua-drawer-top,
.ua-drawer-overlay.ua-open .ua-drawer-bottom {
transform: none;
}
.ua-drawer-head {