feat(client): tablet 外壳 + 视觉 diff 工作流文档

- tablet_shell: 侧栏 232·4 项触控(minHeight 48, 字号 15) + 顶栏无主题切换 + 连接页双栏
  对照 ui_kits/tablet/tabapp.jsx;home_shell 分发 tablet→TabletShell
- nav_sidebar 加 dense 参数(desktop 紧凑 / tablet 触控)
- content_top_bar 加 showThemeToggle + titleSize 参数
- tool/visual-diff.md: 截图 diff 工作流(design-distill 工具)+ 实现侧三路径
  现状(golden 被 google_fonts 阻塞 / screencapture 受 macOS chrome 限制)+ 推荐

注: tablet 形态在 macOS 桌面平台不触发(只 desktop/mobile),运行验证需 iPad。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-06-16 09:38:18 +08:00
parent 4dc4127252
commit 281a6261fb
5 changed files with 159 additions and 31 deletions
+44
View File
@@ -0,0 +1,44 @@
# 视觉 diff 工作流(pangolin 客户端 ↔ design/ui_kits 原型)
`design-distill` skill 的截图 diff 工具,把 Flutter 实现与 `design/ui_kits/{desktop,tablet,mobile}` React 原型对照。
## 工具
- 原型截图:`~/.claude/skills/design-distill/tools/shoot-prototype.mjs`
- 像素 diff`~/.claude/skills/design-distill/tools/diff.mjs`
## 原型基准(已验证可用)
从项目根运行(脚本自动起临时 http server,让 Babel 原型能 fetch jsx):
```bash
SHOOT=~/.claude/skills/design-distill/tools/shoot-prototype.mjs
# desktop 连接页 明/暗(920×600 内容,截外层 sand 画布给点余量)
node $SHOOT design/ui_kits/desktop/index.html shots/desktop_connect_light.png \
--width 1000 --height 720 --theme light --lang zh --wait-for "#root > *"
node $SHOOT design/ui_kits/desktop/index.html shots/desktop_connect_dark.png \
--width 1000 --height 720 --theme dark --lang zh --wait-for "#root > *"
```
> 原型是 SPA,默认显示连接页。截其它页需给 shoot-prototype 加 `--click <navSelector>`(待补)。
## diff
```bash
node ~/.claude/skills/design-distill/tools/diff.mjs <baseline.png> <impl.png> <diff.png> --threshold 0.05
```
## 实现侧截图:两条路径与现状
### A. Flutter golden(推荐,CI 友好)— 当前被 google_fonts 阻塞
`flutter test --update-goldens``RepaintBoundary`,无 chrome/窗口问题,可入 CI。
**阻塞**:组件用 `GoogleFonts.*()`,测试环境 `allowRuntimeFetching=false` 会抛异常(`test/golden/components_golden_test.dart` 因此 `@Skip`)。
**解法**:让字体可注入——把 `pangolin_theme.dart``PangolinText` / `GoogleFonts.*TextTheme` 改为可由测试用 `FontLoader` 注册的 family 覆盖(test/fonts/ 已备 Manrope/Sora/JetBrainsMono ttf),或测试态走 bundled 字体。改完即可启用 golden 做严格回归闸。
### B. screencapture 真实 app(已可截,但受限)
真实渲染、字体真实,但:macOS 原生标题栏(红绿灯) vs 原型自绘 chrome 结构不同;窗口精确定位需「辅助功能」权限。
**用途**:作为**人工视觉对照**(生成 diff 图定位结构偏差),非严格像素闸。
### C. iOS 模拟器(最干净的全屏,未接)
`xcrun simctl io booted screenshot` 截模拟器无桌面 chrome、字体真实,适合 mobile/tablet。导航多页仍需 integration_test 驱动。
## 建议
- **严格回归闸** → 走 A,先做 `PangolinText` 字体可注入(一次性小重构),启用 golden。
- **对照设计原型** → 原型基准(本文档)+ A 的 golden 截图,用 diff.mjs 比对。
- desktop 因 chrome 差异,像素级 100% 对齐不是目标;以**布局/间距/颜色结构一致**为验收口径。