Copyright © 2025 the Contributors to the Design Tokens Resolver Module 2025.10 Specification, published by the Design Tokens Community Group under the W3C Community Final Specification Agreement (FSA). A human-readable summary is available.
本规范由Design Tokens 社区组发布。它不是 W3C 标准,也不在 W3C 标准制定轨道上。 请注意,根据 W3C 社区最终规范协议(FSA) 还适用其他条件。 了解更多关于 W3C 社区与业务组的信息。
本节描述了本文档在发布时的状态。其他文档可能会取代本文件。当前 W3C 社区组报告列表和本报告的最新修订版可在 W3C 社区组报告索引中找到, https://www.w3.org/community/reports/。
本文档由 DTCG 作为 候选推荐 发布,遵循 W3C 流程所给定义。对本草案的贡献受 社区贡献者许可协议(CLA)的约束,具体见 W3C 社区组流程。
尽管不是 W3C 推荐标准,此分类旨在澄清:经过广泛共识建立后,本规范旨在被实现。
本规范被认为是稳定的。后续更新将在后续规范中发布。
建议优先通过GitHub Issues讨论本规范。
本节为非规范性内容。
设计令牌的使用者常需要在不同上下文中表达可替换的值。例如(但不限于):
然而,这些可替换的上下文容易遭遇组合爆炸,使得存储与管理变得笨重。
本格式描述了一种机制,用于在所有上下文中对令牌的重复值进行去重,并且枚举所有上下文的排列组合。
本节为非规范性内容。
一种特征,描述两个或多个上下文分别仅作用于互斥的令牌,即不发生重叠。修饰符可以(MAY)是正交的,但并非必须。
尽可能使修饰符正交化可降低认知负担并减少用户错误。
排列是解析器文档的某一个可能的最终排列。一个排列与一个输入一一对应,但“输入”强调所使用的修饰符 上下文,而“排列”强调最终的令牌集合。
解析器文档必须(MUST)使用标准 JSON 语法([RFC8259])。
用户应该(SHOULD)使用.resolver.json作为解析器文档的文件扩展名。
当通过 HTTP 传输解析器文档时,用户应该(SHOULD)在
Content-Type 头([RFC1341])
中使用预期的application/json MIME 类型([RFC6838])。
用户不应该(SHOULD NOT)使用自定义或非预期的 MIME 类型。
一个解析器文档在根级包含以下属性:
| 名称 | 类型 | 必需 | 描述 |
|---|---|---|---|
| name | string |
文档的简短、可读名称。 | |
| version | YYYY.MM |
Y | 版本。必须为2025.10。 |
| description | string |
本文件的人类可读描述。 | |
| sets | Map[string, Set] |
集合的定义。 | |
| modifiers | Map[`string, Modifier] | 修饰符的定义。 | |
| resolutionOrder | (ReferenceObject | Set | Modifier)[] |
Y | 集合与修饰符的解析顺序。 |
文档可以(MAY)在根级提供一个可读的name。这有助于在文件名不足以区分时区分不同的解析器文档。
文档必须(MUST)在根级提供版本,并且必须(MUST)为2025.10。这为未来可能引入的破坏性变更保留空间。
文档可以(MAY)在根级提供description。它可用于补充name中未包含的说明或上下文。
集合是以DTCG 格式组织的一组设计令牌。集合必须(MUST)包含一个sources数组,其中直接声明令牌,或一个指向包含设计令牌的 JSON 文件的引用对象,或两者的任意组合。
集合可以(MAY)包含description,用于描述集合的目的。
如果数组声明了多个来源,它们将按照数组顺序合并,这意味着如果一个令牌被多次声明,则数组中的最后一次出现将成为最终值。工具必须(MUST)遵循数组顺序。
修饰符与集合相似,但允许通过contexts映射进行条件包含。
修饰符必须(MUST)声明一个contexts映射,将string值映射到一个令牌来源数组。令牌来源的数组必须(MUST)是ReferenceObject,内联令牌,或两者的任意组合。
修饰符应该(SHOULD)至少有两个contexts,因为只有一个时等效于一个集合。修饰符不得(MUST NOT)有空的contexts映射。工具应该(SHOULD)对仅有1个上下文的修饰符抛出错误。工具必须(MUST)对0个上下文的修饰符抛出错误。
与集合一致,数组顺序必须(MUST)得到遵循,以便在冲突情况下,数组中令牌的最后一次出现产生最终值。
修饰符可以(MAY)在某个上下文值中引用一个集合。但修饰符不得(MUST NOT)引用任何其他修饰符,即使是同一修饰符中的另一个上下文也不行。
修饰符可以(MAY)声明一个可读的description。
修饰符可以(MAY)声明一个default值,该值必须(MUST)与contexts中的某个键匹配。若该值不在contexts中,工具必须(MUST)抛出错误。
文档可能生成的解析数量可通过所有修饰符的contexts数量的乘积来预测。
resolutionOrder键是一个集合与修饰符的数组,按顺序生成令牌的最终结果。顺序具有重要意义,若产生冲突,数组中靠后的令牌会覆盖之前的令牌。
在resolutionOrder中,集合或修饰符可以(MAY)以内联方式声明,只要对象中添加name与type键:
| 属性 | 类型 | 必需 | 描述 |
|---|---|---|---|
| name | string |
Y | 一个唯一名称,不得(MUST
NOT)与resolutionOrder中的其他name冲突。 |
| type | "set" | "modifier" |
Y | 必须(MUST)根据类型为"set"或"modifier"。
|
若内联对象缺少name或type,或name在任意对象中重复,工具必须(MUST)抛出错误。
内联集合与修饰符不得(MUST NOT)以任何方式被引用。工具应该(SHOULD)在引用对象指向解析顺序项时抛出错误。
本节为非规范性内容。
resolutionOrder数组允许用户按任意顺序排列集合与修饰符。然而,如果存在许多集合必须出现在修饰符之后以解决冲突,这很可能是一种代码异味,表明令牌组织的不可预测与脆弱。理想情况下,修饰符对条件值的处理足够完善,以至于需要很少或不需要覆盖(参见正交性)。在实践中,这意味着
当引用另一个 JSON 文档或同一文档中的结构时,必须(MUST)使用引用对象。JSON Schema 2020-12
中对此的描述为一个以$ref为键的对象,其字符串为符合 [RFC6901] 的 JSON
指针。
工具必须(MUST)解析解析器文档中的所有引用对象。
引用对象不得(MUST NOT)是循环的,既不能引用自身的指针,也不能引用该引用对象的任何父节点。
工具必须(MUST)支持同文档引用对象,这是支持此解析器模块的最低要求。除此之外,工具可以做个别决定不支持某些 URI 类型,如本地文件系统导入或通过 TCP/IP 的远程 URI。
指针可以(MAY)指向同一文档中的任意位置,但以下情况除外:
#/modifiers/…)。集合与修饰符不得(MUST NOT)引用另一个修饰符。#/resolutionOrder/…)。解析顺序的本质是引用文档的许多其他部分。复制其中任何部分都会产生复杂、难以预测的链条。
工具必须(MUST)在遇到任何无效指针时抛出错误。
如JSON Schema
2020-12所允许,引用对象可在$ref旁边存在其他键。在这些场景中,与$ref并列的本地键必须(MUST)被视为覆盖。
如果与$ref并列的键声明了对象或数组,工具必须(MUST)进行浅层扁平化,即对象与数组不合并。
可以在任意集合、修饰符或内联集合/修饰符上添加$extensions对象,以声明任意的元数据,由各工具自行决定使用或忽略。
若提供,$extensions必须(MUST)为一个对象,其键为供应商特定的命名空间。这允许多个工具无冲突地使用这些元数据。
工具可以(MAY)允许在 JSON Schema 的$defs中定义结构,但这不是必需的。然而,工具不得(MUST NOT)在遇到$defs时抛出错误,且必须(MUST)在不支持时忽略该键。
解析器文档仅描述条件令牌值可以(MAY)如何生成。但这些条件仍需在某处提供。“输入”一词指传递给工具的任意上下文值选择。
工具必须(MUST)接受可序列化为 JSON 的对象,例如JavaScript 中的对象或Python 中的字典。
加载声明了修饰符的解析器的工具,若未提供相应输入,应该(SHOULD)抛出错误。
输入应该(SHOULD)不区分大小写。例如,{ "theme": "dark" }、{ "Theme": "Dark" }与{ "THEME": "DARK" }应该(SHOULD)等价。然而,工具可以(MAY)对大小写敏感性做出个别决定。
输入的值必须(MUST)为字符串。若输入包含非字符串值(如{ "beta": true }或
{ "size": 100 }),工具必须(MUST)抛出错误。
工具必须(MUST)处理解析阶段以产生正确的输出。
工具必须(MUST)要求所有输入与所提供的修饰符上下文匹配。
如果解析器未声明任何修饰符,跳过此步骤并继续排序。
工具必须(MUST)按顺序迭代resolutionOrder数组。
对于数组中的每一项,确定其是集合还是修饰符,并按数组顺序扁平化为单一令牌结构。
sources以生成单一令牌结构。context,并按数组顺序组合以生成单一令牌结构。
重复,直到到达resolutionOrder数组末尾。
最终结果将是一个令牌结构,其行为与最初来自一个来源相同。
在此步骤之前不得(MUST NOT)解析别名。
在将排序扁平化为单一令牌结构之后,唯一剩余的步骤是解析别名。别名的解析与format中概述的方法完全相同:
$type。本节为非规范性内容。
解析器文档允许为组织目的在多个 JSON 文件中使用令牌。但出于可移植性的考虑,只处理单个 JSON 文档可能更有利。
“打包”指将解析器文档简化为单个文件的过程。实现这一点有多种策略,超过本文档的范围。但为便于说明,这里概述众多可能方法中的两种:
内联涉及获取所有指向远程文件的引用对象,并将其替换为其内容。这是一种简单的策略,能实现最终目标,但在同一文件被多次引用时会产生重复。工具可能不会因令牌重复而有任何问题,但阅读本文件的人很可能会因产生的代码行数过多而难以阅读。
如$defs所述,$defs在解析器文档中未定义行为。仅当某工具决定支持 JSON Schema 的此特性时才可使用。
该策略涉及创建一个顶层$defs键,每个顶层键包含对应文件的内容。
使用$defs的唯一缺点是某些工具可能选择忽略它,因为它不是解析器文档的最低要求。
除了标注为非规范性的章节外,本规范中的所有编写指南、图示、示例与注释均为非规范性内容。除此以外的所有内容均为规范性内容。
本文件中的关键词MAY、MUST、MUST NOT、SHOULD与SHOULD NOT应按 BCP 14 [RFC2119] [RFC8174] 的描述进行解读,且仅当它们以本文所示的全大写形式出现时才适用。
实现解析器规范的工具必须(MUST):
本节为非规范性内容。
若无 Hyma 团队的支持,本解析器规范将无法完成, 包括但不限于 Mike Kamminga、Andrew L’Homme 与 Lilith。 Joren Broekema、Louis Chenais 亦作出了重要贡献。 我们感谢设计令牌社区工作组成员的贡献与反馈。