From 80e63ca7f76a99360b3c2e64020fa40fc8a0a0c1 Mon Sep 17 00:00:00 2001 From: wangjia <809946525@qq.com> Date: Thu, 25 Jun 2026 06:51:52 +0800 Subject: [PATCH] =?UTF-8?q?feat(client):=20token=20=E5=9C=B0=E5=9F=BA?= =?UTF-8?q?=E8=A1=A5=E5=AD=97=E9=98=B6/=E5=9C=86=E8=A7=92/=E9=97=B4?= =?UTF-8?q?=E8=B7=9D=E6=A0=87=E9=87=8F=E5=B1=82=20AppDims=EF=BC=88codegen?= =?UTF-8?q?=20=E5=8D=95=E6=BA=90=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gen_tokens.mjs 扩展解析 :root 共享块 → 生成 app_dims.g.dart: 间距 sp1-10 / 圆角 rSm-rPill / 字号 fsDisplay-fsXs,主题无关 const 标量。 为屏幕重建提供「禁硬编码 px」的单一真源;app_tokens.g.dart 保持字节一致。 Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01TSKEiHsvauyxYUW2itzUXX --- client/lib/core/theme/app_dims.g.dart | 30 +++++++++++++++++ client/tool/gen_tokens.mjs | 47 +++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 client/lib/core/theme/app_dims.g.dart diff --git a/client/lib/core/theme/app_dims.g.dart b/client/lib/core/theme/app_dims.g.dart new file mode 100644 index 0000000..8071655 --- /dev/null +++ b/client/lib/core/theme/app_dims.g.dart @@ -0,0 +1,30 @@ +// GENERATED by tool/gen_tokens.mjs — DO NOT EDIT. +// 源:lib/core/theme/token_source/tokens.css(:root 共享块,主题无关)。改尺寸请改源后重跑脚本。 +// 间距/圆角/字号三套主题统一,故为 const 标量,不进 per-theme AppTokens。 + +class AppDims { + AppDims._(); + // 间距 + static const double sp1 = 4; + static const double sp2 = 8; + static const double sp3 = 12; + static const double sp4 = 16; + static const double sp5 = 20; + static const double sp6 = 24; + static const double sp8 = 32; + static const double sp10 = 40; + // 圆角 + static const double rSm = 4; + static const double rMd = 6; + static const double rLg = 10; + static const double rXl = 14; + static const double rPill = 999; + // 字号 + static const double fsDisplay = 28; + static const double fsH1 = 21; + static const double fsH2 = 17; + static const double fsTitle = 15; + static const double fsBody = 13; + static const double fsSm = 12; + static const double fsXs = 11; +} diff --git a/client/tool/gen_tokens.mjs b/client/tool/gen_tokens.mjs index ea319ac..9cfa637 100644 --- a/client/tool/gen_tokens.mjs +++ b/client/tool/gen_tokens.mjs @@ -72,3 +72,50 @@ AppTokens appTokensOf(String key) { `; fs.writeFileSync(path.join(ROOT, 'lib/core/theme/app_tokens.g.dart'), body); console.log('generated app_tokens.g.dart'); + +// ── 主题无关标量(间距/圆角/字号):解析 :root{} 共享块 → AppDims ── +function rootBlock(){ + // 匹配 ":root{" 而非 ":root[data-theme=...]"(前者 { 紧跟) + const m = css.match(/:root\s*\{([^}]*)\}/); + if(!m) throw new Error('missing :root shared block'); + const out = {}; + for(const mm of m[1].matchAll(/--([a-z0-9-]+)\s*:\s*([^;]+);/g)) out[mm[1]] = mm[2].trim(); + return out; +} +// kebab → camel:sp-1→sp1 · r-sm→rSm · fs-h1→fsH1 · fs-display→fsDisplay +function camel(name){ + const [h, ...rest] = name.split('-'); + return h + rest.map(s => s.charAt(0).toUpperCase() + s.slice(1)).join(''); +} +function px(raw){ + const m = raw.trim().match(/^([\d.]+)px$/); + if(!m) throw new Error('unsupported dim value: ' + raw); + return m[1]; +} +function emitDims(){ + const r = rootBlock(); + const groups = [ + ['间距', k => k.startsWith('sp-')], + ['圆角', k => k.startsWith('r-')], + ['字号', k => k.startsWith('fs-')], + ]; + const lines = []; + for(const [label, pick] of groups){ + const keys = Object.keys(r).filter(pick); + if(!keys.length) continue; + lines.push(` // ${label}`); + for(const k of keys) lines.push(` static const double ${camel(k)} = ${px(r[k])};`); + } + return lines.join('\n'); +} +const dimsBody = `// GENERATED by tool/gen_tokens.mjs — DO NOT EDIT. +// 源:lib/core/theme/token_source/tokens.css(:root 共享块,主题无关)。改尺寸请改源后重跑脚本。 +// 间距/圆角/字号三套主题统一,故为 const 标量,不进 per-theme AppTokens。 + +class AppDims { + AppDims._(); +${emitDims()} +} +`; +fs.writeFileSync(path.join(ROOT, 'lib/core/theme/app_dims.g.dart'), dimsBody); +console.log('generated app_dims.g.dart');