iter(g243): 文档站与演示页外壳配色改为从令牌派生,消除暗色强调色漂移

This commit is contained in:
HIsheR
2026-10-26 21:55:27 +08:00
parent aa27a16912
commit f396a5545c
4 changed files with 43 additions and 7 deletions
+6 -2
View File
@@ -6,6 +6,7 @@ import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { createRequire } from 'node:module';
import { shellPalette } from '../../packages/tools/cli/lib/shell-palette.mjs'; // 外壳配色与文档站同源:从 tokens.json 派生
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const root = path.resolve(__dirname, '..', '..'); // apps/demo 上两级 = 仓库根
@@ -34,6 +35,9 @@ const result = await esbuild.build({
const js = result.outputFiles[0].text.replace(/<\/script>/gi, '<\\/script>'); // 防提前闭合
const css = [read('packages/design/tokens/tokens.css'), read('packages/skin/ui/ui.css')].join('\n');
// 外壳 chrome 配色从 tokens.json 派生:手写值时改暗色 accent 会让页面外壳与组件各显示一种蓝
const tokensPath = path.join(root, 'packages/design/tokens/tokens.json');
const shell = shellPalette(fs.existsSync(tokensPath) ? JSON.parse(fs.readFileSync(tokensPath, 'utf8')) : null);
const html = `<!DOCTYPE html>
<html lang="zh-CN">
@@ -43,8 +47,8 @@ const html = `<!DOCTYPE html>
<title>@ui-arch 组件库 · 现场演示</title>
<style>
${css}
:root{--page-bg:#ffffff;--page-text:#1c1e21;--page-muted:#6b7280;--page-border:rgba(0,0,0,.14)}
:root[data-theme=dark]{--page-bg:#101216;--page-text:#e7e9ec;--page-muted:#888780;--page-border:rgba(255,255,255,.15)}@media (prefers-color-scheme:dark){:root:not([data-theme]){--page-bg:#101216;--page-text:#e7e9ec;--page-muted:#888780;--page-border:rgba(255,255,255,.15)}}
:root{--page-bg:${shell.bg};--page-text:${shell.text};--page-muted:${shell.muted};--page-border:${shell.border}}
:root[data-theme=dark]{--page-bg:${shell.darkBg};--page-text:${shell.darkText};--page-muted:${shell.darkMuted};--page-border:${shell.darkBorder}}@media (prefers-color-scheme:dark){:root:not([data-theme]){--page-bg:${shell.darkBg};--page-text:${shell.darkText};--page-muted:${shell.darkMuted};--page-border:${shell.darkBorder}}}
*{box-sizing:border-box}
body{margin:0;background:var(--page-bg);color:var(--page-text);font:14px/1.7 -apple-system,"Segoe UI","Microsoft YaHei",sans-serif}
.shell{max-width:1160px;margin:0 auto;padding:36px 20px 80px;display:grid;grid-template-columns:190px minmax(0,1fr);gap:36px}
+2 -2
View File
@@ -10,7 +10,7 @@
--ua-color-surface-3: color-mix(in srgb, var(--ua-color-text) 8%, var(--ua-color-bg)); /* 表面三阶:按下底、最深容器 */
--ua-color-surface-inset: color-mix(in srgb, var(--ua-color-text) 5%, var(--ua-color-bg)); /* 凹陷区:输入框 / 代码块底 */
--ua-color-text: #1c1e21; /* 主文本色:正文与标题共用 */
--ua-color-text-muted: #676d78; /* 辅助文本色:说明、占位、次要信息(比 #6b7280 略深:凹陷底上原值仅 4.39,过不了 AA 4.5) */
--ua-color-text-muted: #676d78; /* 辅助文本色:说明、占位、次要信息(比原值略深:凹陷底上原值仅 4.39,过不了 AA 4.5) */
--ua-color-text-secondary: #4b5158; /* 次级文本色:介于主文本与辅助文本之间 */
--ua-color-text-faint: #9aa0a8; /* 三级文本色:禁用、极弱说明 */
--ua-color-overlay: rgba(0, 0, 0, 0.45); /* 遮罩:抽屉 / 弹窗 / 命令面板等半透明底 */
@@ -158,7 +158,7 @@
--ua-color-scrollbar: rgba(255, 255, 255, 0.24); /* 暗色滚动条拇指:暗底上黑拇指完全看不见,改白色低透明度 */
--ua-color-scrollbar-hover: rgba(255, 255, 255, 0.42); /* 暗色滚动条拇指悬停:亮度再升一档表示可拖拽 */
--ua-color-highlight: rgba(255, 255, 255, 0.08); /* 暗色内高光:暗底上白高光刺眼,降到 8% 只留一道细光 */
--ua-color-accent: #4a9aeb; /* 暗色强调色:提亮以保证暗底可读(原 #378add 压在白字/淡底上只有 3.92/4.44,过不了 AA) */
--ua-color-accent: #4a9aeb; /* 暗色强调色:提亮以保证暗底可读(原值压在白字/淡底上只有 3.92/4.44,过不了 AA,详见 ua audit:contrast) */
--ua-color-accent-contrast: #042c53; /* 暗色强调色上的文字色:深色反白,维持对比 */
--ua-color-accent-soft: color-mix(in srgb, var(--ua-color-accent) 82%, var(--ua-color-bg)); /* 暗色柔和强调色:与亮色同结构,混入暗底即自然降饱和 */
--ua-color-tint-accent: color-mix(in srgb, var(--ua-color-accent) 14%, transparent); /* 暗色淡底标准档:暗底上淡底不可见,透明度升一档 */
+7 -3
View File
@@ -6,6 +6,7 @@ import { fileURLToPath } from 'node:url';
import { spawnSync } from 'node:child_process';
import { visualAudit } from '../lib/visual-audit.mjs';
import { auditContrast, formatReport, PAIRS } from '../lib/contrast-audit.mjs';
import { shellPalette } from '../lib/shell-palette.mjs';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
@@ -328,6 +329,9 @@ function renderDocs(index, tokens) {
const data = JSON.stringify(index.packages).replace(/</g, '\\u003c');
const tokData = JSON.stringify(tokens).replace(/</g, '\\u003c');
const generatedAt = esc(index.generatedAt);
// 文档站外壳配色从 tokens.json 派生:手写十六进制会跟令牌脱节(改暗色 accent 后这里还留着旧值,
// 页面与演示 iframe 两个蓝各显示一种),派生后单一来源,改令牌即全站跟随。
const shell = shellPalette(tokens);
return `<!DOCTYPE html>
<html lang="zh-CN">
<head>
@@ -335,9 +339,9 @@ function renderDocs(index, tokens) {
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>@ui-arch 组件库文档</title>
<style>
:root{--bg:#ffffff;--surface:#f6f7f9;--text:#1c1e21;--muted:#6b7280;--border:rgba(0,0,0,.14);--accent:#185fa5;--code-bg:#101216;--code-text:#e7e9ec}
@media (prefers-color-scheme:dark){:root:not([data-theme=light]){--bg:#101216;--surface:#1a1c22;--text:#e7e9ec;--muted:#888780;--border:rgba(255,255,255,.15);--accent:#378add}}
:root[data-theme=dark]{--bg:#101216;--surface:#1a1c22;--text:#e7e9ec;--muted:#888780;--border:rgba(255,255,255,.15);--accent:#378add}
:root{--bg:${shell.bg};--surface:${shell.surface};--text:${shell.text};--muted:${shell.muted};--border:${shell.border};--accent:${shell.accent};--code-bg:${shell.codeBg};--code-text:${shell.codeText}}
@media (prefers-color-scheme:dark){:root:not([data-theme=light]){--bg:${shell.darkBg};--surface:${shell.darkSurface};--text:${shell.darkText};--muted:${shell.darkMuted};--border:${shell.darkBorder};--accent:${shell.darkAccent}}}
:root[data-theme=dark]{--bg:${shell.darkBg};--surface:${shell.darkSurface};--text:${shell.darkText};--muted:${shell.darkMuted};--border:${shell.darkBorder};--accent:${shell.darkAccent}}
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--text);font:14px/1.65 -apple-system,"Segoe UI","Microsoft YaHei",sans-serif}
header{position:sticky;top:0;z-index:2;display:flex;gap:16px;align-items:center;flex-wrap:wrap;padding:14px 24px;background:var(--bg);border-bottom:1px solid var(--border)}
+28
View File
@@ -0,0 +1,28 @@
/*** @ui-arch 外壳配色:文档站与演示页的外层 chrome 用色,统一从 tokens.json 派生
*
* 为什么单独成文件:这两处都曾手写十六进制,改暗色 accent 后页面里还留着旧蓝、与演示 iframe 各显示一种色。
* 放在 lib 里给 bin/ua.js(生成文档站)与 apps/demo/build.mjs(生成演示页)共用,才是真正的单一来源;
* 缺键时退回内置默认,保证 tokens.json 缺失时构建不炸(宁可配色旧一点也不中断发布)。
*/
/*** 作用:取出亮暗两套外壳配色;tokens 为解析后的 tokens.json,可为 null ***/
export function shellPalette(tokens) {
const color = (tokens && tokens.color) || {};
const pick = (key, theme, fallback) => (color[key] && color[key][theme]) || fallback;
return {
bg: pick('bg', 'light', '#ffffff'),
surface: pick('surface', 'light', '#f6f7f9'),
text: pick('text', 'light', '#1c1e21'),
muted: pick('textMuted', 'light', '#676d78'),
border: pick('border', 'light', 'rgba(0, 0, 0, 0.15)'),
accent: pick('accent', 'light', '#185fa5'),
codeBg: pick('bg', 'dark', '#101216'),
codeText: pick('text', 'dark', '#e7e9ec'),
darkBg: pick('bg', 'dark', '#101216'),
darkSurface: pick('surface', 'dark', '#1a1c22'),
darkText: pick('text', 'dark', '#e7e9ec'),
darkMuted: pick('textMuted', 'dark', '#888780'),
darkBorder: pick('border', 'dark', 'rgba(255, 255, 255, 0.15)'),
darkAccent: pick('accent', 'dark', '#4a9aeb'),
};
}