1a8089a96d
- doc/frontend-overview.html:一次 UI 改动的标准路径 / 真相源结构 / 五端消费对照 / 各道闸全景 / L1-L2-L3 分治 / 已知滞后(jiu frontend-overview 思想的 dudu 版) - design/SKILL.md 增补「单源与闸」章节(agent 改 UI 前必读) - doc/index.html 登记全景文档 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
169 lines
11 KiB
HTML
169 lines
11 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>dudu 前端全景:设计真相源与防漂移体系</title>
|
||
<style>
|
||
:root {
|
||
--accent: #4F6EF7;
|
||
--accent-text: #3D58DB;
|
||
--accent-soft: #EEF1FE;
|
||
--bg: #F6F7FA;
|
||
--card: #FFFFFF;
|
||
--text-1: #1B1E26;
|
||
--text-2: #5A6072;
|
||
--text-3: #A6ABB8;
|
||
--border-1: #E4E6EB;
|
||
--positive: #16A34A;
|
||
--warning: #E8890C;
|
||
--danger: #DC2626;
|
||
--code-bg: #1B1E26;
|
||
--code-text: #D6DCEA;
|
||
}
|
||
* { box-sizing: border-box; }
|
||
body {
|
||
margin: 0;
|
||
font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", "Segoe UI", sans-serif;
|
||
background: var(--bg); color: var(--text-1); line-height: 1.75;
|
||
}
|
||
.container { max-width: 980px; margin: 0 auto; padding: 0 24px 80px; }
|
||
header.hero { background: var(--accent); color: #fff; padding: 48px 24px 40px; text-align: center; }
|
||
header.hero h1 { margin: 0 0 6px; font-size: 30px; }
|
||
header.hero p { margin: 0; opacity: .85; font-size: 15px; }
|
||
.chips { margin-top: 16px; }
|
||
.chip { display: inline-block; padding: 3px 14px; margin: 3px; background: rgba(255,255,255,.16); border-radius: 999px; font-size: 13px; }
|
||
section.card {
|
||
background: var(--card); border: 1px solid var(--border-1); border-radius: 14px;
|
||
padding: 28px 32px; margin-top: 24px; box-shadow: 0 1px 3px rgba(17,19,26,.05);
|
||
}
|
||
h2 { font-size: 21px; margin: 0 0 14px; padding-bottom: 8px; border-bottom: 2px solid var(--accent); display: inline-block; }
|
||
h3 { font-size: 16px; margin: 22px 0 8px; color: var(--accent-text); }
|
||
table { width: 100%; border-collapse: collapse; margin: 10px 0; font-size: 13.5px; }
|
||
th, td { border: 1px solid var(--border-1); padding: 7px 11px; text-align: left; vertical-align: top; }
|
||
th { background: #F0F1F4; font-weight: 600; }
|
||
tr:nth-child(even) td { background: #FCFCFD; }
|
||
pre.code, pre.diagram {
|
||
background: var(--code-bg); color: var(--code-text); padding: 16px 18px; border-radius: 10px;
|
||
overflow-x: auto; font-family: "SF Mono", Menlo, Consolas, monospace; font-size: 12.5px; line-height: 1.55;
|
||
}
|
||
code.inline { background: var(--accent-soft); color: var(--accent-text); padding: 1px 6px; border-radius: 4px; font-family: "SF Mono", Menlo, monospace; font-size: 12.5px; }
|
||
.callout { border-left: 4px solid var(--accent); background: var(--accent-soft); padding: 11px 16px; border-radius: 0 8px 8px 0; margin: 12px 0; font-size: 13.5px; }
|
||
.callout.warn { border-color: var(--warning); background: #FCEFD7; }
|
||
.tag { display: inline-block; font-size: 12px; padding: 1px 10px; border-radius: 999px; margin-right: 6px; font-weight: 600; }
|
||
.tag.green { background: #DCFCE7; color: var(--positive); }
|
||
.tag.orange { background: #FCEFD7; color: var(--warning); }
|
||
.tag.blue { background: var(--accent-soft); color: var(--accent-text); }
|
||
ul, ol { padding-left: 22px; }
|
||
li { margin: 3px 0; }
|
||
footer { text-align: center; color: var(--text-3); font-size: 13px; margin-top: 44px; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<header class="hero">
|
||
<h1>dudu 前端全景</h1>
|
||
<p>设计真相源(design/)· 五端消费 · 防漂移闸体系 —— 参考 jiu ds-flow 思想的非 Flutter 落地</p>
|
||
<div class="chips">
|
||
<span class="chip">2026-07-11</span>
|
||
<span class="chip">登记簿:design/index.html</span>
|
||
<span class="chip">闸:design-pipeline/check-ds · check-code · export-tokens --check</span>
|
||
</div>
|
||
</header>
|
||
|
||
<div class="container">
|
||
|
||
<section class="card">
|
||
<h2>一、一次 UI 改动的标准路径</h2>
|
||
<pre class="diagram">改颜色/字号/间距 design/tokens/*.css 登记
|
||
│
|
||
▼
|
||
node design-pipeline/export-tokens.mjs
|
||
│(直写四端消费位置)
|
||
┌──────────┬──────┴──────┬──────────────┐
|
||
▼ ▼ ▼ ▼
|
||
desktop iOS Swift Android Kotlin 官网 web/
|
||
CSS 变量 DuduTheme DuduTheme tokens.css
|
||
(直引源) (生成) (生成) (生成,含字体内嵌)
|
||
|
||
改组件 / 图标 先在 design/ 登记(components/ + index.html 卡;
|
||
icons.js + icon-map.json)→ 再到各端实现
|
||
提交 pre-commit 自动跑对应闸;CI 三道闸复验</pre>
|
||
<div class="callout"><b>核心原则(ds-flow):</b>设计决策只有一个出生地(design/),代码永远是镜像;绕过单源的行为由闸在提交/CI 时拦截。<b>规则写了没上闸 = 没有规则。</b></div>
|
||
</section>
|
||
|
||
<section class="card">
|
||
<h2>二、真相源结构(design/)</h2>
|
||
<table>
|
||
<tr><th>路径</th><th>角色</th></tr>
|
||
<tr><td><code class="inline">index.html</code></td><td><b>登记簿</b>(活文档主页):token 色板 / 组件卡 / 图标映射 / guidelines / ui_kits 单一入口。新元素必须在此登记(check-ds ④ 强制)。评审:<code class="inline">node design/serve.mjs</code></td></tr>
|
||
<tr><td><code class="inline">tokens/*.css</code></td><td>令牌单源:colors(含 --brand-wechat / --overlay-wave)/ typography / spacing / effects / fonts(Outfit 自托管,禁 CDN)</td></tr>
|
||
<tr><td><code class="inline">icons.js + icon-map.json</code></td><td>图标单源(Lucide 线条 24 网格)+ 语义名→三端实现映射表;业务代码禁内联 <path></td></tr>
|
||
<tr><td><code class="inline">components/</code>(core/forms/voice)</td><td>参考组件(React),桌面端直接运行时消费;Icon.jsx 渲染 icons.js</td></tr>
|
||
<tr><td><code class="inline">ui_kits/</code>(desktop/mobile)</td><td>屏级交互原型(新屏 design-first 的出生地)</td></tr>
|
||
<tr><td><code class="inline">guidelines/*.card.html</code></td><td>规范卡(品牌/色板/字体/间距/动效)</td></tr>
|
||
<tr><td><code class="inline">readme.md / SKILL.md</code></td><td>设计基调、文案基调、视觉硬规则;agent 使用入口</td></tr>
|
||
<tr><td><code class="inline">_ds_manifest.json</code></td><td>Claude 设计导出的机读清单——<b>非权威、可能滞后</b>,真相以 tokens/ 与登记簿为准</td></tr>
|
||
</table>
|
||
</section>
|
||
|
||
<section class="card">
|
||
<h2>三、五端消费方式对照</h2>
|
||
<table>
|
||
<tr><th>端</th><th>技术栈</th><th>令牌</th><th>组件/图标</th></tr>
|
||
<tr><td>桌面 Mac/Win</td><td>Tauri 2 + React</td><td>vite alias <code class="inline">@dudu/design</code> 直引 tokens CSS(无生成层)</td><td>直接 import design/components;Icon 组件渲染 icons.js</td></tr>
|
||
<tr><td>iOS</td><td>SwiftUI</td><td><code class="inline">ios/dudu/Shared/DuduTheme.swift</code>(codegen 直写)</td><td>SF Symbols,须 ∈ icon-map ios 列(check-code 同集闸)</td></tr>
|
||
<tr><td>Android</td><td>Compose</td><td><code class="inline">DuduTheme.kt</code>(codegen 直写)→ <code class="inline">DuduPalette</code> CompositionLocal</td><td>暂无图标使用;启用后同集闸生效</td></tr>
|
||
<tr><td>官网</td><td>静态单页</td><td><code class="inline">web/tokens.css</code>(codegen:custom props + Outfit data URI)</td><td>页面只允许 var(--*);深色板块挂 <code class="inline">data-theme="dark"</code> 复用 dark 令牌</td></tr>
|
||
<tr><td>原型自身</td><td>React(浏览器内 Babel)</td><td>styles.css @import tokens</td><td>与桌面同一套组件源码</td></tr>
|
||
</table>
|
||
<div class="callout"><b>codegen 直写消费位置</b>(2026-07-11 改):此前生成到 design-pipeline/generated/ 再手工拷贝进 app,<code class="inline">--check</code> 守不到真实文件、拷贝已漂移。现直写 + CI 校验真实消费文件,漂移类型整个消除。</div>
|
||
</section>
|
||
|
||
<section class="card">
|
||
<h2>四、各道闸全景</h2>
|
||
<table>
|
||
<tr><th>闸</th><th>拦什么</th><th>何时跑</th></tr>
|
||
<tr><td><code class="inline">check-ds.mjs</code><br>真相源自检(7 道)</td><td>① dark 孤儿 token ② var() 断链/@import 缺失 ③ design/ 内裸色 ∉ tokens 值集 ④ 组件未登记登记簿 ⑤ icons.js 重复 key/填充色 ⑥ icon-map ↔ icons.js 双向不同集 ⑦ 界面文案 emoji</td><td>pre-commit(动 design/)+ CI</td></tr>
|
||
<tr><td><code class="inline">export-tokens.mjs --check</code></td><td>四端令牌产物与源不一致(改了 tokens 忘 regen / 手改生成文件)</td><td>pre-commit(动 design/)+ CI</td></tr>
|
||
<tr><td><code class="inline">check-code.mjs</code><br>代码侧单源(四端)</td><td>desktop 字面色/内联 <path>;iOS 字面色/未登记 SF Symbol;Android Color(0x;web 字面色</td><td>pre-commit(动端代码)+ CI</td></tr>
|
||
</table>
|
||
<h3>豁免机制</h3>
|
||
<ul>
|
||
<li>行级 <code class="inline">ds-ignore: 理由</code> 注释——必须写理由(mac 红绿灯窗饰、手机外壳装饰、alpha 派生色等)</li>
|
||
<li>codegen 产物(DuduTheme.*、web/tokens.css)自动豁免</li>
|
||
</ul>
|
||
<h3>启用</h3>
|
||
<pre class="code"># 一次性(每个 clone)
|
||
git config core.hooksPath .githooks
|
||
|
||
# 手动全量
|
||
node design-pipeline/check-ds.mjs && node design-pipeline/export-tokens.mjs --check && node design-pipeline/check-code.mjs</pre>
|
||
</section>
|
||
|
||
<section class="card">
|
||
<h2>五、三层分治规则(L1 / L2 / L3)</h2>
|
||
<table>
|
||
<tr><th>层</th><th>规则</th></tr>
|
||
<tr><td><b>L1 设计系统元素</b><br>颜色/字号/间距/组件/图标</td><td>先登记 design/(tokens / components+登记簿 / icons+map)再写端代码,<b>无例外</b>。闸强制。</td></tr>
|
||
<tr><td><b>L2 屏级</b></td><td>屏以 ui_kits 原型为基准;小迭代直改代码但不得引入 L1 违规(闸兜底);整屏改版原型先行。</td></tr>
|
||
<tr><td><b>L3 新屏</b></td><td>design-first:ui_kits 加屏(serve.mjs 起服务给 URL 评审,不截图)→ 各端实现 → 登记。</td></tr>
|
||
</table>
|
||
</section>
|
||
|
||
<section class="card">
|
||
<h2>六、已知滞后与后续项</h2>
|
||
<ul>
|
||
<li><span class="tag orange">todo #26</span>桌面 fidelity 像素闸(Playwright 截 ui_kits 原型 vs Tauri 页面 pixelmatch)——静态闸先行,像素级验收后续补</li>
|
||
<li><span class="tag orange">待治理</span>ui_kits 预览页经 unpkg CDN 加载 React/Babel,离线/无代理网络不可用(评审时需网络;可选改为 vendor 本地化)</li>
|
||
<li><span class="tag blue">说明</span>_ds_manifest.json 为 Claude 设计导出产物,未纳入闸;以 tokens/ 与登记簿为权威</li>
|
||
<li><span class="tag blue">说明</span>移动端不做跨渲染器像素比对(字体度量漂移大,jiu 教训);iOS/Android 一致性由 token codegen + 同集闸保障</li>
|
||
</ul>
|
||
</section>
|
||
|
||
<footer>dudu · 前端全景 · 2026-07-11 · 变更走 feat/design-truth-source</footer>
|
||
|
||
</div>
|
||
</body>
|
||
</html>
|