设计令牌解析器模块 2025.10

最终社区组报告

本版本:
https://www.w3.org/community/reports/design-tokens/2025.10/
最新发布版本:
https://www.designtokens.org/TR/2025.10/resolver/
编辑:
Joren Broekema
Esther Cheran
Mike Kamminga
Andrew L’Homme
Drew Powers
Matthew Ström-Awn
Lilith Wittmann
作者:
Louis Chenais
James Nash
反馈:
GitHub design-tokens/community-group (拉取请求, 新建议, 未解决问题)

摘要

本规范扩展了格式,并描述了一种在多种情境(如“明亮模式”和“暗黑模式”配色主题)下使用设计令牌的方法。

本文档状态

本规范由Design Tokens 社区组发布。它不是 W3C 标准,也不在 W3C 标准制定轨道上。 请注意,根据 W3C 社区最终规范协议(FSA) 还适用其他条件。 了解更多关于 W3C 社区与业务组的信息。

本节描述了本文档在发布时的状态。其他文档可能会取代本文件。当前 W3C 社区组报告列表和本报告的最新修订版可在 W3C 社区组报告索引中找到, https://www.w3.org/community/reports/

本文档由 DTCG 作为 候选推荐 发布,遵循 W3C 流程所给定义。对本草案的贡献受 社区贡献者许可协议(CLA)的约束,具体见 W3C 社区组流程

尽管不是 W3C 推荐标准,此分类旨在澄清:经过广泛共识建立后,本规范旨在被实现。

本规范被认为是稳定的。后续更新将在后续规范中发布。

建议优先通过GitHub Issues讨论本规范。

1. 简介

本节为非规范性内容。

设计令牌的使用者常需要在不同上下文中表达可替换的值。例如(但不限于):

然而,这些可替换的上下文容易遭遇组合爆炸,使得存储与管理变得笨重。

本格式描述了一种机制,用于在所有上下文中对令牌的重复值进行去重,并且枚举所有上下文的排列组合。

2. 术语

2.1 正交性

本节为非规范性内容。

一种特征,描述两个或多个上下文分别仅作用于互斥的令牌,即不发生重叠。修饰符可以(MAY)是正交的,但并非必须。

尽可能使修饰符正交化可降低认知负担并减少用户错误。

2.2 排列

排列是解析器文档的某一个可能的最终排列。一个排列与一个输入一一对应,但“输入”强调所使用的修饰符 上下文,而“排列”强调最终的令牌集合。

3. 文件类型

3.1 格式

解析器文档必须(MUST)使用标准 JSON 语法([RFC8259])。

工具可以(MAY)支持诸如JSONCJSON5等扩展,只要文档能够转换为正常 JSON 且不影响令牌值。

3.2 文件扩展名

用户应该(SHOULD)使用.resolver.json作为解析器文档的文件扩展名。

3.3 MIME 类型

当通过 HTTP 传输解析器文档时,用户应该(SHOULD)Content-Type 头([RFC1341]) 中使用预期的application/json MIME 类型([RFC6838])。 用户不应该(SHOULD NOT)使用自定义或非预期的 MIME 类型。

4. 语法

4.1 根级属性

一个解析器文档在根级包含以下属性:

名称 类型 必需 描述
name string 文档的简短、可读名称。
version YYYY.MM Y 版本。必须为2025.10
description string 本文件的人类可读描述。
sets Map[string, Set] 集合的定义。
modifiers Map[`string, Modifier] 修饰符的定义。
resolutionOrder (ReferenceObject | Set | Modifier)[] Y 集合与修饰符的解析顺序。

4.1.1 名称

文档可以(MAY)在根级提供一个可读的name。这有助于在文件名不足以区分时区分不同的解析器文档。

4.1.2 版本

文档必须(MUST)在根级提供版本,并且必须(MUST)2025.10。这为未来可能引入的破坏性变更保留空间。

4.1.3 描述

文档可以(MAY)在根级提供description。它可用于补充name中未包含的说明或上下文。

4.1.4 集合(Sets)

集合是以DTCG 格式组织的一组设计令牌。集合必须(MUST)包含一个sources数组,其中直接声明令牌,或一个指向包含设计令牌的 JSON 文件的引用对象,或两者的任意组合。

集合可以(MAY)包含description,用于描述集合的目的。

如果数组声明了多个来源,它们将按照数组顺序合并,这意味着如果一个令牌被多次声明,则数组中的最后一次出现将成为最终值。工具必须(MUST)遵循数组顺序。

4.1.5 修饰符(Modifiers)

修饰符与集合相似,但允许通过contexts映射进行条件包含。

4.1.5.1 上下文(Contexts)

修饰符必须(MUST)声明一个contexts映射,将string值映射到一个令牌来源数组。令牌来源的数组必须(MUST)ReferenceObject,内联令牌,或两者的任意组合。

修饰符应该(SHOULD)至少有两个contexts,因为只有一个时等效于一个集合。修饰符不得(MUST NOT)有空的contexts映射。工具应该(SHOULD)对仅有1个上下文的修饰符抛出错误。工具必须(MUST)对0个上下文的修饰符抛出错误。

集合一致,数组顺序必须(MUST)得到遵循,以便在冲突情况下,数组中令牌的最后一次出现产生最终值。

修饰符可以(MAY)在某个上下文值中引用一个集合。但修饰符不得(MUST NOT)引用任何其他修饰符,即使是同一修饰符中的另一个上下文也不行。

4.1.5.2 描述

修饰符可以(MAY)声明一个可读的description

4.1.5.3 默认值

修饰符可以(MAY)声明一个default值,该值必须(MUST)contexts中的某个键匹配。若该值不在contexts中,工具必须(MUST)抛出错误。

4.1.5.4 解析数量

文档可能生成的解析数量可通过所有修饰符的contexts数量的乘积来预测。

4.1.6 解析顺序(Resolution Order)

resolutionOrder键是一个集合修饰符的数组,按顺序生成令牌的最终结果。顺序具有重要意义,若产生冲突,数组中靠后的令牌会覆盖之前的令牌。

4.1.6.1 内联集合与修饰符

resolutionOrder中,集合修饰符可以(MAY)以内联方式声明,只要对象中添加nametype键:

属性 类型 必需 描述
name string Y 一个唯一名称,不得(MUST NOT)resolutionOrder中的其他name冲突。
type "set" | "modifier" Y 必须(MUST)根据类型为"set""modifier"

若内联对象缺少nametype,或name在任意对象中重复,工具必须(MUST)抛出错误。

编者注:Name

内联集合与修饰符不得(MUST NOT)以任何方式被引用。工具应该(SHOULD)引用对象指向解析顺序项时抛出错误。

4.1.6.2 集合与修饰符的排序

本节为非规范性内容。

resolutionOrder数组允许用户按任意顺序排列集合与修饰符。然而,如果存在许多集合必须出现在修饰符之后以解决冲突,这很可能是一种代码异味,表明令牌组织的不可预测与脆弱。理想情况下,修饰符对条件值的处理足够完善,以至于需要很少或不需要覆盖(参见正交性)。在实践中,这意味着

4.2 引用对象

当引用另一个 JSON 文档或同一文档中的结构时,必须(MUST)使用引用对象。JSON Schema 2020-12 中对此的描述为一个以$ref为键的对象,其字符串为符合 [RFC6901] 的 JSON 指针。

工具必须(MUST)解析解析器文档中的所有引用对象。

引用对象不得(MUST NOT)是循环的,既不能引用自身的指针,也不能引用该引用对象的任何父节点。

工具必须(MUST)支持同文档引用对象,这是支持此解析器模块的最低要求。除此之外,工具可以做个别决定不支持某些 URI 类型,如本地文件系统导入或通过 TCP/IP 的远程 URI。

4.2.1 无效指针

指针可以(MAY)指向同一文档中的任意位置,但以下情况除外:

  1. 只有resolutionOrder可以引用修饰符(#/modifiers/…)。集合与修饰符不得(MUST NOT)引用另一个修饰符。
    • 从集合引用修饰符可能导致输入将条件逻辑应用到一个不支持该逻辑的结构,因此不允许。
    • 从修饰符引用另一个修饰符意味着单个输入会应用到意料之外的修饰符,因此不允许。
  2. 引用对象不得(MUST NOT)指向resolutionOrder数组中的任何内容(#/resolutionOrder/…)。解析顺序的本质是引用文档的许多其他部分。复制其中任何部分都会产生复杂、难以预测的链条。

工具必须(MUST)在遇到任何无效指针时抛出错误。

4.2.2 扩展

JSON Schema 2020-12所允许,引用对象可在$ref旁边存在其他键。在这些场景中,与$ref并列的本地键必须(MUST)被视为覆盖。

如果与$ref并列的键声明了对象或数组,工具必须(MUST)进行浅层扁平化,即对象与数组不合并。

4.3 $extensions

可以在任意集合修饰符内联集合/修饰符上添加$extensions对象,以声明任意的元数据,由各工具自行决定使用或忽略。

若提供,$extensions必须(MUST)为一个对象,其键为供应商特定的命名空间。这允许多个工具无冲突地使用这些元数据。

4.4 $defs

工具可以(MAY)允许在 JSON Schema 的$defs中定义结构,但这不是必需的。然而,工具不得(MUST NOT)在遇到$defs时抛出错误,且必须(MUST)在不支持时忽略该键。

编者注:$defs

5. 输入

解析器文档仅描述条件令牌值可以(MAY)如何生成。但这些条件仍需在某处提供。“输入”一词指传递给工具的任意上下文值选择。

工具必须(MUST)接受可序列化为 JSON 的对象,例如JavaScript 中的对象Python 中的字典

加载声明了修饰符的解析器的工具,若未提供相应输入,应该(SHOULD)抛出错误。

5.1 大小写敏感性

输入应该(SHOULD)不区分大小写。例如,{ "theme": "dark" }{ "Theme": "Dark" }{ "THEME": "DARK" }应该(SHOULD)等价。然而,工具可以(MAY)对大小写敏感性做出个别决定。

5.2 强制使用字符串

输入的值必须(MUST)为字符串。若输入包含非字符串值(如{ "beta": true }{ "size": 100 }),工具必须(MUST)抛出错误。

6. 解析逻辑

工具必须(MUST)处理解析阶段以产生正确的输出。

  1. 输入验证:验证给定解析器文档的输入是否有效。
  2. 排序:遍历resolutionOrder数组以生成最终令牌结构。
  3. 别名:解析最终令牌结构中的令牌别名。
  4. 解析:最终的结果。

6.1 输入验证

工具必须(MUST)要求所有输入与所提供的修饰符上下文匹配。

如果解析器未声明任何修饰符,跳过此步骤并继续排序

  1. 对于输入对象中的每个键:
    1. 验证其对应一个有效修饰符。若不对应,抛出错误。
    2. 验证该键的值与该修饰符的允许值相匹配。若不匹配,抛出错误。
  2. 对于解析器中的每个修饰符:
    1. 若该解析器未声明默认值,验证输入中提供了该键。若未提供,抛出错误。

6.2 排序

工具必须(MUST)按顺序迭代resolutionOrder数组。

  1. 对于数组中的每一项,确定其是集合还是修饰符,并按数组顺序扁平化为单一令牌结构。

    1. 如果该项是集合,按数组顺序组合sources以生成单一令牌结构。
    2. 否则,如果该项是修饰符,仅选择与输入匹配的context,并按数组顺序组合以生成单一令牌结构。
    3. 若发生冲突,取数组中最近一次出现的值。
  2. 重复,直到到达resolutionOrder数组末尾。

最终结果将是一个令牌结构,其行为与最初来自一个来源相同。

6.3 别名

在此步骤之前不得(MUST NOT)解析别名。

在将排序扁平化为单一令牌结构之后,唯一剩余的步骤是解析别名。别名的解析与format中概述的方法完全相同:

6.4 解析

7. 打包

本节为非规范性内容。

解析器文档允许为组织目的在多个 JSON 文件中使用令牌。但出于可移植性的考虑,只处理单个 JSON 文档可能更有利。

“打包”指将解析器文档简化为单个文件的过程。实现这一点有多种策略,超过本文档的范围。但为便于说明,这里概述众多可能方法中的两种:

7.1 内联文件

内联涉及获取所有指向远程文件的引用对象,并将其替换为其内容。这是一种简单的策略,能实现最终目标,但在同一文件被多次引用时会产生重复。工具可能不会因令牌重复而有任何问题,但阅读本文件的人很可能会因产生的代码行数过多而难以阅读。

7.2 为文件使用 $defs

$defs所述,$defs在解析器文档中未定义行为。仅当某工具决定支持 JSON Schema 的此特性时才可使用。

该策略涉及创建一个顶层$defs键,每个顶层键包含对应文件的内容。

使用$defs的唯一缺点是某些工具可能选择忽略它,因为它不是解析器文档的最低要求。

8. 一致性

除了标注为非规范性的章节外,本规范中的所有编写指南、图示、示例与注释均为非规范性内容。除此以外的所有内容均为规范性内容。

本文件中的关键词MAYMUSTMUST NOTSHOULDSHOULD NOT应按 BCP 14 [RFC2119] [RFC8174] 的描述进行解读,且仅当它们以本文所示的全大写形式出现时才适用。

实现解析器规范的工具必须(MUST)

A. 致谢

本节为非规范性内容。

若无 Hyma 团队的支持,本解析器规范将无法完成, 包括但不限于 Mike Kamminga、Andrew L’Homme 与 Lilith。 Joren Broekema、Louis Chenais 亦作出了重要贡献。 我们感谢设计令牌社区工作组成员的贡献与反馈。

B. 参考文献

B.1 规范性参考

[html]
HTML 标准。 Anne van Kesteren; Domenic Denicola;Dominic Farolino;Ian Hickson;Philip Jägenstedt;Simon Pieters。WHATWG。活标准。 URL:https://html.spec.whatwg.org/multipage/
[RFC1341]
MIME(多用途互联网邮件扩展):指定与描述互联网邮件正文格式的机制。 N. Borenstein;N. Freed。IETF。1992 年 6 月。建议标准。URL:https://www.rfc-editor.org/rfc/rfc1341
[RFC2119]
在 RFC 中用于指示需求级别的关键词。S. Bradner。IETF。1997 年 3 月。当前最佳实践。URL:https://www.rfc-editor.org/rfc/rfc2119
[RFC6838]
媒体类型规范与注册流程。N. Freed;J. Klensin;T. Hansen。IETF。2013 年 1 月。当前最佳实践。URL:https://www.rfc-editor.org/rfc/rfc6838
[RFC6901]
JavaScript 对象表示法(JSON)指针。P. Bryan, Ed.;K. Zyp;M. Nottingham, Ed. IETF。2013 年 4 月。建议标准。URL:https://www.rfc-editor.org/rfc/rfc6901
[RFC8174]
RFC 2119 关键词大小写歧义。B. Leiba。IETF。2017 年 5 月。当前最佳实践。URL:https://www.rfc-editor.org/rfc/rfc8174
[RFC8259]
JavaScript 对象表示法(JSON)数据交换格式。T. Bray, Ed. IETF。2017 年 12 月。互联网标准。URL:https://www.rfc-editor.org/rfc/rfc8259
[w3c-process]
W3C 流程文档。Elika J. Etemad(fantasai);Florian Rivoal。W3C。2025 年 8 月 18 日。URL:https://www.w3.org/policies/process/