主题
主题与样式
颜色不是直接写在形状里的。它先以 token 的形式进入主题,再通过文档里的样式声明, 最后变成形状能直接使用的具体涂法。
正在渲染图表…
三层分别负责什么
| 层 | 写什么 | 给谁用 |
|---|---|---|
| 主题 tokens | surface、text、accent 这类名字和值 | build 解析样式 |
theme.typeStyles | 某类 shape / edge 的默认外观 | build 在文档样式之前解析 |
| 文档 styles | 一类元素怎么填、怎么描边、是否投影 | 节点 / 边通过 style 引用 |
| overlay | selected / hover / muted 等运行时状态 | build 最后覆盖 |
ctx.style | 已经解析成具体值的 Style | 形状直接交给场景零件 |
形状看不到 surface、accent 这些 token 名,也拿不到整份主题。它只知道自己拿到的 是一套可以直接输出的样式。这样换主题不需要改形状代码,换形状也不需要重新定义主题。
文档里怎么引用样式
ts
const document = {
version: 2,
styles: {
card: {
fill: { token: "surface" },
stroke: { token: "border" },
color: { token: "text" },
},
},
nodes: [
{ id: "a", type: "rect", style: "card", label: "订单服务" },
],
edges: [],
};style: "card" 是引用名字,不是直接塞一份样式。同一个名字可以被多个节点或边复用。
主题为什么切成两半
主题产出两份东西:
tokens给 build 上色;typography给 layout 量文字。
theme.typeStyles 也属于主题:它让“所有 component 默认是什么颜色”集中在主题里,而不是 每个文档复制一份。overlay 则只存在于调用方状态,不写进文档,也不触发重新布局。
字号和行高会改变节点尺寸,所以它们必须在布局开始前确定。颜色不参与几何,所以可以等到 构建场景时再解析。
找不到 token 时
样式解析按“内置底座 → typeStyles → 排版量 → 文档样式 → overlay”的顺序逐字段覆盖。 某个字段引用了不存在的 token 时, 会退回更早一层的值,并产生 UNKNOWN_TOKEN 诊断。画面不会直接掉到 SVG 的隐式黑色填充。
常见误解
node.style不是 token 名,它引用的是document.styles里的条目。- 主题只负责值,不负责判断某个形状应该长什么样。
typeStyles负责类型默认值,overlay负责瞬时状态,两者不要混用。- 只换颜色 token 时几何不变;如果连
typography一起换,文字尺寸变化会继续影响布局。 - 形状里写死颜色不是“更简单”,而是绕过了主题,之后无法统一换肤。