Design System
交互模式与行为规范
交互模式与行为规范
版本 1.0 - 从 v3 原型提炼的可复用模式。
1. 数据可视化注释
所有内嵌 viz 必须携带上下文锚,否则它只是装饰而非信息。
1.1 规则
- 每个 viz 下方必须有
.viz-note行(9px mono 字体,tertiary 色)。 - Sparkline 注释说明 X 轴含义和节点语义。例:
周一 → 周五 · 每个节点 = 1 条新机会。 - 进度环注释说明目标和预计完成条件。例:
目标 100% · 预计 2 次阅读块完成。 - 条形图注释使用图例格式:
- 计划线 - 超支 - 正常,每个图例项含色块 swatch。 - 注释不参与 hover 交互,纯信息展示。
1.2 Token
--component-viz-note-font-size: 9px;
--component-viz-note-color: var(--color-text-tertiary);
--component-viz-legend-swatch-width: 8px;
--component-viz-legend-swatch-height: 2px;2. Lazy View 注入
非首屏视图使用 <template> 标签存储 HTML,首次切换时 clone 注入。
2.1 流程
- 用户点击导航 →
switchView(view)调用。 - 检查
injectedViewsSet:若未注入,先渲染 skeleton。 - 280ms 后从
#tpl-{view}clone content 注入到#view-{view}。 - 绑定事件(
bindViewEvents):data-detail 点击/键盘、data-view-jump、reveal observer。 - 添加
.in类触发 reveal 动画。
2.2 Skeleton 规格
- 2 行
.sk-line(w40 + w80)模拟标题。 - 1 行
.sk-line.w60模拟副标题。 - 2 个
.sk-block模拟卡片。 - Shimmer 动画 1.4s infinite。
2.3 性能考量
- Today 视图 inline 渲染(首屏关键路径)。
- 其他 7 个视图 template 存储,减少首屏 DOM 解析量。
- 注入后 template 内容不再需要,但保留在 DOM 中(clone 不影响原 template)。
3. 键盘导航
3.1 Focus Stack(优先事项列表)
role="listbox"+ 每个 itemrole="option"+aria-selected。- ArrowDown / ArrowRight:选中下一项并触发 click(更新 inspector)。
- ArrowUp / ArrowLeft:选中上一项。
- Enter / Space:同 click。
- 循环:到末尾后回到首项。
3.2 Detail Drawer Focus Trap
- 打开时记录
previousFocus = document.activeElement。 - 打开后 50ms 将焦点移到关闭按钮。
- Tab 循环:最后一个 focusable → 第一个 focusable。
- Shift+Tab 循环:第一个 focusable → 最后一个 focusable。
- 关闭时
previousFocus.focus()恢复焦点。
3.3 全局快捷键
| 快捷键 | 行为 |
|---|---|
⌘K / Ctrl+K |
打开 Command Palette。 |
Escape |
关闭所有 overlay + detail drawer。 |
4. Inspector 同步
4.1 视图级默认上下文
每个视图在 viewInspectorMap 中定义默认 inspector 数据:
- 可以是
inspectorData中已有 key 的字符串引用(如today → "renewal")。 - 可以是内联对象(如
knowledge → {title, body, links, level, reason})。
4.2 切换行为
switchView()末尾查询viewInspectorMap[view]。- 若为字符串:直接用该 key 的数据。
- 若为对象:注册到
inspectorData["__view_"+view]并使用。 - 触发 140ms cross-fade swap 动画。
- 更新
currentInspectorKey以支持"打开详情"按钮映射。
4.3 Debounce
快速连续切换视图或 focus-item 时:
- 若上一次 swap timer 未结束,清除 timer 直接更新内容(不重播动画)。
- 避免 cross-fade 互相打断产生闪烁。
5. 决策流反馈链
用户在 DetailDrawer 中做出决策后,以下 6 个位置必须同步更新:
- Detail state badge - 状态文字 + 注释更新。
- Detail timeline - 新条目 unshift 到顶部。
- Decision result panel - spring 弹入显示决策摘要。
- Today 卡片 - 标题 + 描述 + meta 更新 +
.flash动画。 - Inspector - 标题 + 描述更新(通过
applyInspector)。 - Audit events - 新审计条目插入 Governance 审计列表顶部。
- Toast - 底部弹出确认通知,3.4s 自动消失。
5.1 Card Flash 动画
@keyframes cardflash {
0% { background: var(--color-accent-subtle); }
100% { background: var(--color-bg-raised); }
}触发方式:移除 class → void offsetWidth(强制 reflow)→ 添加 class。
5.2 取消操作门控
取消属于外部写操作,必须经过 ConfirmDialog:
- 显示动作、影响对象、执行状态、自动化等级。
- 用户确认后才执行
recordSubscriptionDecision("cancel")。 - 原型中只记录决定,不调用外部服务。
6. 主题切换
6.1 实现
- 点击 toggle 按钮 → 检测当前主题 → 设置
data-theme属性。 - 添加
.theming类 420ms,让所有颜色属性平滑过渡。 - 过渡属性:
background-color, border-color, color, box-shadow, background。
6.2 暗色模式特殊处理
- Grain 纹理从 noise SVG 换为 dot pattern(更干净)。
- Wash 饱和度提高(accent glow 型渐变而非白色 wash)。
- 阴影换为纯黑基底(更深的 depth 感)。
- Accent 色提亮到 #7db89d 保持可读性。
7. Scroll Reveal
7.1 规则
.reveal类元素默认opacity: 0; transform: translateY(16px)。- IntersectionObserver(threshold 0.12)检测到可见时添加
.in。 .in触发 600ms smooth easing 过渡到opacity: 1; transform: none。- 一旦 reveal 完成,unobserve 不再重复触发。
- 视图切换时手动为当前视图所有
.reveal添加.in(因为已在视口内)。
7.2 与 Stagger 的关系
- Stagger 用于视图内首屏元素的入场编排(animation-delay 递增)。
- Reveal 用于滚动后才进入视口的 section。
- 两者不冲突:stagger 是 CSS animation,reveal 是 CSS transition。
8. 脉冲点(Live Indicator)
用于表示"系统运行中"或"当前进行中"。
- 8px 圆点 +
::after伪元素做扩散环。 @keyframes pulse:scale(.5) opacity(.8) → scale(1.25) opacity(0),2.4s infinite。- 使用场景:sidebar footer 同步状态、hero chip、agenda 当前项、timeline 节点。
9. 响应式降级
| 组件 | 桌面 | 平板 | 移动 |
|---|---|---|---|
| Inspector | 固定右栏 | 隐藏 | 点击 focus-item 时打开 detail drawer。 |
| Sidebar | 固定左栏 | 缩窄 | Fixed drawer + hamburger。 |
| Signal grid | 3 列 | 2 列(末项跨列) | 1 列。 |
| Coverage | 6 列 | 3 列 | 2 列。 |
| Focus item | 3 列 grid | 同 | 2 列(meta 移到第二行)。 |
| Detail drawer | 768px | 同 | 100vw。 |