diff --git a/.ua/index.json b/.ua/index.json index 4d0ed29..0c21f44 100644 --- a/.ua/index.json +++ b/.ua/index.json @@ -1,6 +1,6 @@ { "$schema": "ui-arch-registry-index/0.1", - "generatedAt": "2026-10-26T15:15:56.703Z", + "generatedAt": "2026-10-26T15:17:13.022Z", "repoRoot": ".", "packages": [ { @@ -4625,7 +4625,8 @@ "文案比容器宽就传 scroll: true:正文从右向左匀速走,悬停自动暂停,读得完不用追", "只想播报不需要关闭就传 closable: false:右侧不再留 × 位,横条更紧凑", "颜色只是第二线索:左侧符号按 variant 自动配(ℹ / ✓ / ! / ×),色弱或灰度打印也能分辨", - "跑马灯在减少动效偏好下自动停成静态首屏——完整原文始终在 title 里,不必为可访问性另写一份" + "跑马灯在减少动效偏好下自动停成静态首屏——完整原文始终在 title 里,不必为可访问性另写一份", + "点 × 是先淡出再隐藏(200ms,和 alert 同一档),回调 onClose 立刻触发:想同步清理外部状态就在回调里做,别等隐藏" ] } ] diff --git a/apps/demo/main.ts b/apps/demo/main.ts index 68a0862..8f26afe 100644 --- a/apps/demo/main.ts +++ b/apps/demo/main.ts @@ -1908,7 +1908,7 @@ content.append( 'div', { class: 'col' }, noticeBar({ text: '系统将于今晚 23:00 维护约 10 分钟,期间提交会排队重试。', onClose: () => toast.info('已关闭维护公告') }), - noticeBar({ text: '长公告示例:新版表格已支持列宽记忆与筛选快照,若发现列宽异常可在设置里一键重置;滚动模式下悬停会自动暂停。', variant: 'warning', scroll: true }), + noticeBar({ text: '长公告示例:本季度将完成表单校验规则的可视化配置,期间旧配置继续有效;滚动模式下悬停会自动暂停。', variant: 'warning', scroll: true }), noticeBar({ text: '构建成功:12 项门禁全部通过。', variant: 'success', closable: false }), noticeBar({ text: '连接已断开,正在重试第 3 次…', variant: 'danger', icon: '⚠' }), ), diff --git a/llms-full.txt b/llms-full.txt index 99204c4..1538e8f 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -1,6 +1,6 @@ # @ui-arch 组件库 Agent 文档(无图形版) -> 自动生成于 2026-10-26T15:15:56.703Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。 +> 自动生成于 2026-10-26T15:17:13.022Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。 > 组件 = 普通函数,传 props 返回 DOM;状态用 signal 双向绑定:读 signal() 写 signal(v)。 ## 快速上手 @@ -2478,6 +2478,7 @@ noticeBar({ text: '系统将于今晚 23:00 维护 10 分钟', scroll: true }) 3. 只想播报不需要关闭就传 closable: false:右侧不再留 × 位,横条更紧凑 4. 颜色只是第二线索:左侧符号按 variant 自动配(ℹ / ✓ / ! / ×),色弱或灰度打印也能分辨 5. 跑马灯在减少动效偏好下自动停成静态首屏——完整原文始终在 title 里,不必为可访问性另写一份 +6. 点 × 是先淡出再隐藏(200ms,和 alert 同一档),回调 onClose 立刻触发:想同步清理外部状态就在回调里做,别等隐藏 现场演示:apps/docs/demo.html#sec-notice diff --git a/packages/skin/ui/src/noticeBar.ts b/packages/skin/ui/src/noticeBar.ts index 0bc990e..79010b9 100644 --- a/packages/skin/ui/src/noticeBar.ts +++ b/packages/skin/ui/src/noticeBar.ts @@ -3,12 +3,18 @@ import type { NoticeBarProps } from './types.js'; // 语义色配符号:只靠颜色区分在灰度/色弱下会失效,符号是第二条线索 const ICONS: Record = { info: 'ℹ', success: '✓', warning: '!', danger: '×' }; +const EXIT_MS = 200; // 退场时长:与 alert 的关闭过渡同档,两条播报件消失手感一致 -/*** 通知条:单行横条,语义色 + 可选跑马灯与关闭;关闭即整条隐藏并回调 ***/ +/*** 通知条:单行横条,语义色 + 可选跑马灯与关闭;关闭先淡出再隐藏并回调 ***/ export function noticeBar(props: NoticeBarProps): HTMLElement { const variant = props.variant ?? 'info'; - const open = signal(true); // 关闭状态:隐藏而非摘节点,调用方仍可拿到元素句柄 - return h( + const open = signal(true); // 关闭状态:退场结束后置 false(隐藏而非摘节点,调用方仍持有句柄) + const close = (): void => { + el.classList.add('is-out'); // 挂退场类:淡出 + 轻微上移,先给观感再隐藏 + props.onClose?.(); + window.setTimeout(() => open(false), EXIT_MS); // 与 CSS 过渡时长同源,避免节点在半路消失 + }; + const el = h( 'div', { class: `ua-notice ua-notice-${variant}${props.scroll ? ' is-roll' : ''}`, @@ -20,18 +26,7 @@ export function noticeBar(props: NoticeBarProps): HTMLElement { h('div', { class: 'ua-notice-body' }, h('span', { class: 'ua-notice-text' }, props.text)), props.closable === false ? null - : h( - 'button', - { - type: 'button', - class: 'ua-notice-close', - 'aria-label': '关闭通知', - onClick: () => { - open(false); - props.onClose?.(); - }, - }, - '×', - ), + : h('button', { type: 'button', class: 'ua-notice-close', 'aria-label': '关闭通知', onClick: close }, '×'), ); + return el; } diff --git a/packages/skin/ui/ua.manifest.json b/packages/skin/ui/ua.manifest.json index 5573c48..a6ef27d 100644 --- a/packages/skin/ui/ua.manifest.json +++ b/packages/skin/ui/ua.manifest.json @@ -4496,7 +4496,8 @@ "文案比容器宽就传 scroll: true:正文从右向左匀速走,悬停自动暂停,读得完不用追", "只想播报不需要关闭就传 closable: false:右侧不再留 × 位,横条更紧凑", "颜色只是第二线索:左侧符号按 variant 自动配(ℹ / ✓ / ! / ×),色弱或灰度打印也能分辨", - "跑马灯在减少动效偏好下自动停成静态首屏——完整原文始终在 title 里,不必为可访问性另写一份" + "跑马灯在减少动效偏好下自动停成静态首屏——完整原文始终在 title 里,不必为可访问性另写一份", + "点 × 是先淡出再隐藏(200ms,和 alert 同一档),回调 onClose 立刻触发:想同步清理外部状态就在回调里做,别等隐藏" ] } ] diff --git a/packages/skin/ui/ui.css b/packages/skin/ui/ui.css index ed17dd1..5546a8b 100644 --- a/packages/skin/ui/ui.css +++ b/packages/skin/ui/ui.css @@ -5911,6 +5911,13 @@ h5.ua-type-title { font-size: var(--ua-font-size-md); } border: 1px solid transparent; border-radius: var(--ua-radius-md); color: var(--ua-color-text); + transition: opacity var(--ua-duration-base) var(--ua-ease), transform var(--ua-duration-base) var(--ua-ease); +} + +/* 关闭退场:淡出 + 轻微上移,与 alert 的 ua-alert-out 同一套观感(200ms 后由脚本隐藏) */ +.ua-notice.is-out { + opacity: 0; + transform: translateY(calc(-1 * var(--ua-translate-4))); } .ua-notice-icon { @@ -5989,6 +5996,18 @@ h5.ua-type-title { font-size: var(--ua-font-size-md); } .ua-notice.is-roll .ua-notice-text { animation: none; /* 减少动效:跑马灯停成静态首屏,完整原文靠 title */ } + + .ua-notice.is-out { + transform: none; /* 减少动效:退场只淡出,不做位移 */ + } +} + +/* 窄屏:一行装不下就允许换行,跑马灯同时停掉——手机上调宽的滚动条比换行更难读 */ +@media (max-width: 640px) { + .ua-notice.is-roll .ua-notice-text { + animation: none; + white-space: normal; + } } /* ---- 减少动效:旋转 / 缩放一律退化为瞬时 ----