diff --git a/.ua/index.json b/.ua/index.json index 196974a..9d7d4e8 100644 --- a/.ua/index.json +++ b/.ua/index.json @@ -1,6 +1,6 @@ { "$schema": "ui-arch-registry-index/0.1", - "generatedAt": "2026-10-26T09:07:20.198Z", + "generatedAt": "2026-10-26T09:17:08.488Z", "repoRoot": ".", "packages": [ { @@ -265,7 +265,7 @@ "无障碍基线:装饰性占位(skeleton)aria-hidden、加载指示(spinner)role=status、关闭按钮必须 aria-label、弹层弹窗 aria-haspopup/expanded、读屏可见的状态一律同步 aria-*" ], "docs": { - "intro": "28 个 DOM 组件,统一用法:组件是普通函数,传入 props 返回 DOM 节点;需要状态时先创建 signal 再双向绑定。引入 CSS:import '@ui-arch/ui/ui.css'(内部已消费 tokens)。", + "intro": "28 个 DOM 组件,统一用法:组件是普通函数,传入 props 返回 DOM 节点;需要状态时先创建 signal 再双向绑定。引入 CSS:import '@ui-arch/ui/ui.css'(内部已消费 tokens)。\n\n阴影对照表:下拉弹层=shadow-2 / 浮层与悬浮按钮=shadow-3 / 模态弹窗与抽屉及通知=shadow-4 / 卡片与输入组轻浮起=shadow-1;主按钮与强调件的主题色投影=shadow-accent / shadow-accent-strong,组件内不得再手写 box-shadow 字面值。", "steps": [ "安装依赖:pnpm add @ui-arch/ui @ui-arch/frame(workspace 内自动链接)", "引入样式:在应用入口 import '@ui-arch/ui/ui.css',暗色主题在根元素设 data-theme='dark'", diff --git a/.ua/visual-baseline.json b/.ua/visual-baseline.json index 6e009e9..615a992 100644 --- a/.ua/visual-baseline.json +++ b/.ua/visual-baseline.json @@ -1,14 +1,14 @@ { "$schema": "视觉漂移基线:五类硬编码视觉字面量的允许上限,任一类超出即 ua audit:visual 退出码 1;迁移后用 --baseline 重写", "file": "packages/skin/ui/ui.css", - "commit": "f125369", - "generatedAt": "2026-10-26T08:49:44.301Z", - "lines": 4726, - "total": 35, + "commit": "a9a084c", + "generatedAt": "2026-10-26T09:17:07.493Z", + "lines": 4758, + "total": 27, "counts": { "font-size-literal": 5, "duration-literal": 9, - "shadow-literal": 17, + "shadow-literal": 9, "radius-literal": 0, "focus-ring-variant": 4 } diff --git a/llms-full.txt b/llms-full.txt index 7c1fa35..c80c196 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -1,6 +1,6 @@ # @ui-arch 组件库 Agent 文档(无图形版) -> 自动生成于 2026-10-26T09:07:20.198Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。 +> 自动生成于 2026-10-26T09:17:08.488Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。 > 组件 = 普通函数,传 props 返回 DOM;状态用 signal 双向绑定:读 signal() 写 signal(v)。 ## 快速上手 @@ -52,6 +52,8 @@ 28 个 DOM 组件,统一用法:组件是普通函数,传入 props 返回 DOM 节点;需要状态时先创建 signal 再双向绑定。引入 CSS:import '@ui-arch/ui/ui.css'(内部已消费 tokens)。 +阴影对照表:下拉弹层=shadow-2 / 浮层与悬浮按钮=shadow-3 / 模态弹窗与抽屉及通知=shadow-4 / 卡片与输入组轻浮起=shadow-1;主按钮与强调件的主题色投影=shadow-accent / shadow-accent-strong,组件内不得再手写 box-shadow 字面值。 + ### image — 图片 Image 参数: @@ -2169,6 +2171,8 @@ node packages/tools/cli/bin/ua.js |docs|tokens - --ua-shadow-2: 0 4px 12px rgba(0, 0, 0, 0.1)(暗色 0 4px 12px rgba(0, 0, 0, 0.4)) - --ua-shadow-3: 0 10px 28px rgba(0, 0, 0, 0.12)(暗色 0 10px 28px rgba(0, 0, 0, 0.45)) - --ua-shadow-4: 0 18px 44px rgba(0, 0, 0, 0.14)(暗色 0 18px 44px rgba(0, 0, 0, 0.5)) +- --ua-shadow-accent: 0 3px 10px color-mix(in srgb, var(--ua-color-accent) 25%, transparent)(暗色 0 3px 10px color-mix(in srgb, var(--ua-color-accent) 30%, transparent)) +- --ua-shadow-accent-strong: 0 8px 20px color-mix(in srgb, var(--ua-color-accent) 35%, transparent)(暗色 0 8px 20px color-mix(in srgb, var(--ua-color-accent) 40%, transparent)) - --ua-duration-fast: 0.15s - --ua-duration-base: 0.2s - --ua-duration-slow: 0.25s diff --git a/packages/design/tokens/tokens.css b/packages/design/tokens/tokens.css index 5aef9e4..41e8f40 100644 --- a/packages/design/tokens/tokens.css +++ b/packages/design/tokens/tokens.css @@ -50,6 +50,8 @@ --ua-shadow-2: 0 4px 12px rgba(0, 0, 0, 0.1); /* 2 档:下拉菜单 / 选择面板 / 气泡提示 */ --ua-shadow-3: 0 10px 28px rgba(0, 0, 0, 0.12); /* 3 档:浮层 / 悬浮面板 / 拖拽中的卡片 */ --ua-shadow-4: 0 18px 44px rgba(0, 0, 0, 0.14); /* 4 档:模态弹窗 / 抽屉 / 通知中心等最高层 */ + --ua-shadow-accent: 0 3px 10px color-mix(in srgb, var(--ua-color-accent) 25%, transparent); /* 主题色投影:主按钮 / 强调控件悬停浮起 */ + --ua-shadow-accent-strong: 0 8px 20px color-mix(in srgb, var(--ua-color-accent) 35%, transparent); /* 主题色强投影:返回顶部等悬浮强调件 */ /* ---- 动效:三档时长 + 两条主缓动曲线 ---- */ --ua-duration-fast: 0.15s; /* 快:hover / 聚焦 / 颜色与边框变化(既有样式的主流时长) */ @@ -92,4 +94,6 @@ --ua-shadow-2: 0 4px 12px rgba(0, 0, 0, 0.4); /* 暗色 2 档:下拉 / 气泡 */ --ua-shadow-3: 0 10px 28px rgba(0, 0, 0, 0.45); /* 暗色 3 档:浮层 / 悬浮面板 */ --ua-shadow-4: 0 18px 44px rgba(0, 0, 0, 0.5); /* 暗色 4 档:模态 / 抽屉 / 通知 */ + --ua-shadow-accent: 0 3px 10px color-mix(in srgb, var(--ua-color-accent) 30%, transparent); /* 暗色主题色投影:透明度略升补可见性 */ + --ua-shadow-accent-strong: 0 8px 20px color-mix(in srgb, var(--ua-color-accent) 40%, transparent); /* 暗色主题色强投影 */ } diff --git a/packages/design/tokens/tokens.json b/packages/design/tokens/tokens.json index c3e20b8..e11b1ba 100644 --- a/packages/design/tokens/tokens.json +++ b/packages/design/tokens/tokens.json @@ -1,33 +1,110 @@ { "$schema": "https://design-tokens.github.io/community-group/format/", "color": { - "bg": { "light": "#ffffff", "dark": "#101216" }, - "surface": { "light": "#f6f7f9", "dark": "#1a1c22" }, - "text": { "light": "#1c1e21", "dark": "#e7e9ec" }, - "textMuted": { "light": "#6b7280", "dark": "#888780" }, - "border": { "light": "rgba(0, 0, 0, 0.15)", "dark": "rgba(255, 255, 255, 0.15)" }, - "accent": { "light": "#185fa5", "dark": "#378add" }, - "accentContrast": { "light": "#ffffff", "dark": "#042c53" }, - "danger": { "light": "#a32d2d", "dark": "#d96a6a" }, - "success": { "light": "#0f6e56", "dark": "#4fc39e" }, - "warning": { "light": "#9a6b1f", "dark": "#d9a94f" } + "bg": { + "light": "#ffffff", + "dark": "#101216" + }, + "surface": { + "light": "#f6f7f9", + "dark": "#1a1c22" + }, + "text": { + "light": "#1c1e21", + "dark": "#e7e9ec" + }, + "textMuted": { + "light": "#6b7280", + "dark": "#888780" + }, + "border": { + "light": "rgba(0, 0, 0, 0.15)", + "dark": "rgba(255, 255, 255, 0.15)" + }, + "accent": { + "light": "#185fa5", + "dark": "#378add" + }, + "accentContrast": { + "light": "#ffffff", + "dark": "#042c53" + }, + "danger": { + "light": "#a32d2d", + "dark": "#d96a6a" + }, + "success": { + "light": "#0f6e56", + "dark": "#4fc39e" + }, + "warning": { + "light": "#9a6b1f", + "dark": "#d9a94f" + } + }, + "radius": { + "sm": "4px", + "md": "8px", + "lg": "12px" + }, + "space": { + "1": "4px", + "2": "8px", + "3": "12px", + "4": "16px" + }, + "fontSize": { + "xs": "11px", + "sm": "12px", + "md": "13px", + "lg": "14px", + "xl": "16px", + "2xl": "18px" + }, + "weight": { + "normal": 400, + "medium": 500, + "semibold": 600 + }, + "leading": { + "tight": 1.35, + "normal": 1.55 }, - "radius": { "sm": "4px", "md": "8px", "lg": "12px" }, - "space": { "1": "4px", "2": "8px", "3": "12px", "4": "16px" }, - "fontSize": { "xs": "11px", "sm": "12px", "md": "13px", "lg": "14px", "xl": "16px", "2xl": "18px" }, - "weight": { "normal": 400, "medium": 500, "semibold": 600 }, - "leading": { "tight": 1.35, "normal": 1.55 }, "border": { "subtle": "color-mix(in srgb, var(--ua-color-border) 60%, transparent)" }, "shadow": { - "1": { "light": "0 1px 2px rgba(0, 0, 0, 0.06)", "dark": "0 1px 2px rgba(0, 0, 0, 0.3)" }, - "2": { "light": "0 4px 12px rgba(0, 0, 0, 0.1)", "dark": "0 4px 12px rgba(0, 0, 0, 0.4)" }, - "3": { "light": "0 10px 28px rgba(0, 0, 0, 0.12)", "dark": "0 10px 28px rgba(0, 0, 0, 0.45)" }, - "4": { "light": "0 18px 44px rgba(0, 0, 0, 0.14)", "dark": "0 18px 44px rgba(0, 0, 0, 0.5)" } + "1": { + "light": "0 1px 2px rgba(0, 0, 0, 0.06)", + "dark": "0 1px 2px rgba(0, 0, 0, 0.3)" + }, + "2": { + "light": "0 4px 12px rgba(0, 0, 0, 0.1)", + "dark": "0 4px 12px rgba(0, 0, 0, 0.4)" + }, + "3": { + "light": "0 10px 28px rgba(0, 0, 0, 0.12)", + "dark": "0 10px 28px rgba(0, 0, 0, 0.45)" + }, + "4": { + "light": "0 18px 44px rgba(0, 0, 0, 0.14)", + "dark": "0 18px 44px rgba(0, 0, 0, 0.5)" + }, + "accent": { + "light": "0 3px 10px color-mix(in srgb, var(--ua-color-accent) 25%, transparent)", + "dark": "0 3px 10px color-mix(in srgb, var(--ua-color-accent) 30%, transparent)" + }, + "accentStrong": { + "light": "0 8px 20px color-mix(in srgb, var(--ua-color-accent) 35%, transparent)", + "dark": "0 8px 20px color-mix(in srgb, var(--ua-color-accent) 40%, transparent)" + } }, "motion": { - "duration": { "fast": "0.15s", "base": "0.2s", "slow": "0.25s" }, + "duration": { + "fast": "0.15s", + "base": "0.2s", + "slow": "0.25s" + }, "ease": "cubic-bezier(0.2, 0.8, 0.2, 1)", "easeOut": "cubic-bezier(0.16, 1, 0.3, 1)" }, @@ -36,7 +113,17 @@ "ringInset": "inset 0 0 0 2px color-mix(in srgb, var(--ua-color-accent) 40%, transparent)" }, "control": { - "height": { "sm": "28px", "md": "34px", "lg": "40px" } + "height": { + "sm": "28px", + "md": "34px", + "lg": "40px" + } }, - "layer": { "dropdown": 100, "sticky": 200, "overlay": 300, "modal": 400, "toast": 500 } + "layer": { + "dropdown": 100, + "sticky": 200, + "overlay": 300, + "modal": 400, + "toast": 500 + } } diff --git a/packages/skin/ui/ua.manifest.json b/packages/skin/ui/ua.manifest.json index fa3fee5..d784c2c 100644 --- a/packages/skin/ui/ua.manifest.json +++ b/packages/skin/ui/ua.manifest.json @@ -136,7 +136,7 @@ "无障碍基线:装饰性占位(skeleton)aria-hidden、加载指示(spinner)role=status、关闭按钮必须 aria-label、弹层弹窗 aria-haspopup/expanded、读屏可见的状态一律同步 aria-*" ], "docs": { - "intro": "28 个 DOM 组件,统一用法:组件是普通函数,传入 props 返回 DOM 节点;需要状态时先创建 signal 再双向绑定。引入 CSS:import '@ui-arch/ui/ui.css'(内部已消费 tokens)。", + "intro": "28 个 DOM 组件,统一用法:组件是普通函数,传入 props 返回 DOM 节点;需要状态时先创建 signal 再双向绑定。引入 CSS:import '@ui-arch/ui/ui.css'(内部已消费 tokens)。\n\n阴影对照表:下拉弹层=shadow-2 / 浮层与悬浮按钮=shadow-3 / 模态弹窗与抽屉及通知=shadow-4 / 卡片与输入组轻浮起=shadow-1;主按钮与强调件的主题色投影=shadow-accent / shadow-accent-strong,组件内不得再手写 box-shadow 字面值。", "steps": [ "安装依赖:pnpm add @ui-arch/ui @ui-arch/frame(workspace 内自动链接)", "引入样式:在应用入口 import '@ui-arch/ui/ui.css',暗色主题在根元素设 data-theme='dark'", diff --git a/packages/skin/ui/ui.css b/packages/skin/ui/ui.css index c375b73..437d5d3 100644 --- a/packages/skin/ui/ui.css +++ b/packages/skin/ui/ui.css @@ -19,7 +19,7 @@ .ua-btn:hover { filter: brightness(1.08); transform: translateY(-1px); - box-shadow: 0 3px 10px color-mix(in srgb, var(--ua-color-accent) 25%, transparent); + box-shadow: var(--ua-shadow-accent); /* 主题色投影:主按钮悬停浮起 */ } .ua-btn:active { transform: translateY(0) scale(0.97); @@ -91,7 +91,7 @@ } .ua-card-hoverable:hover { transform: translateY(-2px); - box-shadow: 0 10px 24px color-mix(in srgb, var(--ua-color-text) 14%, transparent); + box-shadow: var(--ua-shadow-2); /* 卡片悬停浮起 = 下拉档 */ } .ua-table table { width: 100%; @@ -2279,7 +2279,7 @@ button.ua-step-dot:hover { height: 100%; border-radius: 999px; background: var(--ua-color-bg); - box-shadow: 0 1px 4px color-mix(in srgb, var(--ua-color-text) 12%, transparent); + box-shadow: var(--ua-shadow-1); /* 滑块拇指轻浮起 = 贴地档 */ transition: transform var(--ua-duration-base) ease, width var(--ua-duration-base) ease; pointer-events: none; } @@ -3462,7 +3462,7 @@ button.ua-step-dot:hover { transform: translateY(8px) scale(0.9); pointer-events: none; transition: opacity var(--ua-duration-base) ease, transform var(--ua-duration-base) ease; - box-shadow: 0 8px 20px color-mix(in srgb, var(--ua-color-accent) 35%, transparent); + box-shadow: var(--ua-shadow-accent-strong); /* 悬浮强调件主题色投影 */ } .ua-backtop.is-visible { opacity: 1; @@ -4327,7 +4327,7 @@ h5.ua-type-title { font-size: var(--ua-font-size-md); } font: inherit; font-size: var(--ua-font-size-md); cursor: pointer; - box-shadow: 0 6px 20px color-mix(in srgb, var(--ua-color-text) 16%, transparent); + box-shadow: var(--ua-shadow-3); /* 悬浮按钮 = 浮层档 */ transition: transform var(--ua-duration-fast) ease, box-shadow var(--ua-duration-fast) ease, color var(--ua-duration-fast) ease, border-color var(--ua-duration-fast) ease; } .ua-fab.has-label { @@ -4338,7 +4338,7 @@ h5.ua-type-title { font-size: var(--ua-font-size-md); } color: var(--ua-color-accent); border-color: var(--ua-color-accent); transform: translateY(-2px); - box-shadow: 0 10px 26px color-mix(in srgb, var(--ua-color-text) 22%, transparent); + box-shadow: var(--ua-shadow-4); /* 悬停抬升 = 最高层档 */ } .ua-fab:active { transform: translateY(0) scale(0.97); @@ -4419,7 +4419,7 @@ h5.ua-type-title { font-size: var(--ua-font-size-md); } border: 1px solid var(--ua-color-border); border-radius: var(--ua-radius-md); background: var(--ua-color-surface); - box-shadow: 0 12px 28px color-mix(in srgb, var(--ua-color-text) 16%, transparent); + box-shadow: var(--ua-shadow-2); /* 下拉弹层 = 下拉档 */ } .ua-mentions.is-open .ua-mentions-pop { display: block; @@ -4518,7 +4518,7 @@ h5.ua-type-title { font-size: var(--ua-font-size-md); } border: 1px solid var(--ua-color-border); border-radius: var(--ua-radius-md); background: var(--ua-color-surface); - box-shadow: 0 14px 30px color-mix(in srgb, var(--ua-color-text) 16%, transparent); + box-shadow: var(--ua-shadow-2); /* 下拉弹层 = 下拉档 */ } .ua-treeselect.is-open .ua-treeselect-pop { display: block;