-
Notifications
You must be signed in to change notification settings - Fork 71
Adding technical report: Resolver #289
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
mikekamminga
wants to merge
8
commits into
main
Choose a base branch
from
resolver-spec
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
30de46c
Adding technical report: Resolver
mikekamminga 15b0f3d
Add resolver build and validation steps
kaelig 632c5ae
chore: Format resolver spec into individual markdown files (#290)
drwpow e4aeb68
Improve language of introduction (#291)
drwpow 767c0ad
2. Terminology and 3. Syntax (#292)
drwpow 49d2450
Merge remote-tracking branch 'origin/main' into resolver-spec
drwpow 6a8672f
Merge remote-tracking branch 'origin/main' into resolver-spec
drwpow a51e049
Remaining edits to the resolver specification (#297)
drwpow File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,12 +11,12 @@ | |
"license": "SEE LICENSE.md", | ||
"packageManager": "[email protected]", | ||
"scripts": { | ||
"build": "pnpm --filter @dtcg/www run build", | ||
"build": "pnpm --filter @dtcg/tr run build && pnpm --filter @dtcg/www run build", | ||
"dev": "pnpm run build && pnpm --parallel --recursive --if-present run dev", | ||
"lint": "pnpm --recursive --parallel --stream --if-present run lint", | ||
"format": "pnpm --recursive --parallel --stream --if-present run format", | ||
"prepare": "husky", | ||
"install-browsers": "puppeteer browsers install chrome@137" | ||
"install-browsers": "puppeteer browsers install chrome" | ||
}, | ||
"lint-staged": { | ||
"*.{md,yml,json,html}": "prettier --write" | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# Changelog | ||
|
||
All notable changes to this project will be documented in this file. | ||
|
||
## [2.1.0] - 2025-07-23 | ||
|
||
This release incorporates editorial improvements and community feedback summarized from the [Design Tokens Resolvers Specification Working Copy](https://docs.google.com/document/d/1LOtdiS8R903R7RwDd22JiDxljh51l7Xfy9M1D-p-9mU/edit?tab=t.0#heading=h.svkctwfaregs), identifying key areas for future specification development. | ||
|
||
### Added | ||
|
||
- **Resolution Aliasing Section:** Added a complete new section explaining aliasing/namespacing concepts with detailed examples and JSON Schema definition (from Working Copy) | ||
- **Community Feedback Integration:** Incorporated editorial comments and issues from the working copy document throughout the specification, highlighting ambiguities, inconsistencies, and areas needing clarification. | ||
|
||
### Issues Identified (from Working Copy) | ||
|
||
- **Terminology Clarifications:** Highlighted need for better definitions of "process", "inputs", "dimensions" vs "contexts", and disambiguation between different types of aliasing. | ||
- **File Extension Recommendations:** Suggested using `.tokens.json` extension to align with Design Tokens Format Specification conventions. | ||
- **Schema Structure Improvements:** Identified need to move functional properties out of generic `meta` property into formal schema definitions. | ||
- **Modifier Structure Concerns:** Raised questions about using arrays vs objects for modifiers to ensure uniqueness and prevent conflicts. | ||
- **Merging Logic Specification:** Highlighted need for detailed DTCG-compliant merging algorithms and conflict resolution rules. | ||
- **Precedence and Order:** Identified need for explicit precedence rules when multiple modifiers affect the same tokens. | ||
- **Orthogonality Declaration:** Suggested need for explicit orthogonality declarations to support lazy resolution. | ||
|
||
### Notes | ||
|
||
- This version focuses on integrating community feedback and issue identification from the working copy rather than normative specification changes. | ||
- Issues summarized from the working copy will inform future specification development and clarifications. | ||
|
||
## [2.0.0] - 2023-10-27 | ||
|
||
This is the first major revision of the specification based on a detailed technical review. The goal of this release is to add clarity, address ambiguities, and provide a more robust foundation for implementers. | ||
|
||
### Added | ||
|
||
- **"Include" Modifier Type:** Added a new `include` type for modifiers, which is used to conditionally include a set of tokens. An example has been added to the "Modifiers" section. | ||
- **Order of Precedence:** A new subsection, "Order of Precedence," has been added to the "Resolution Logic" section to explicitly define the merge order for base sets and modifiers. | ||
- **Error Handling Guidance:** A new informative section, "Error Handling," has been added to recommend specific error types for common failure scenarios (e.g., `FileNotFoundError`, `CircularReferenceError`). | ||
|
||
### Changed | ||
|
||
- **Modifier Type:** The `type` property on modifiers now defaults to `"enumerated"`. | ||
- **Inline Token Definitions:** Clarified that an "inline token definition" must be a complete JSON object representing a valid token structure. An example has been added to the "Token Sets" section. | ||
- **Final Output Format:** The specification now explicitly states that the final resolved output should be a nested JSON object that mirrors the token paths, as shown in the examples. | ||
- **Path Resolution:** It is now explicitly stated that file paths in a resolver file must be resolved relative to the location of the resolver file itself. | ||
- **Alias Resolution Scope:** The spec now clarifies that alias resolution is performed on the fully merged set of tokens, allowing aliases to reference tokens across any loaded file. | ||
- **`meta.alias` Behavior:** The behavior of `meta.alias` is now more clearly defined, explaining that it namespaces the tokens from the modifier's files and that external references must use this namespace. | ||
|
||
### Fixed | ||
|
||
- **Inconsistent `\$value` Key:** Corrected all instances of an inconsistent `value` key in JSON examples to use `\$value`, aligning with the Design Tokens Format Specification. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
Tools implementing the Resolver Specification MUST: | ||
|
||
- **Support the Resolution Process**: Implement the [resolution logic](#resolution-logic) as defined, including input validation, base set flattening, modifier application, aliasing, and conflict resolution. | ||
- **Validate Inputs**: Ensure that provided modifier inputs match the defined modifiers and acceptable values. | ||
- **Resolve Aliases Correctly**: Handle [token references](../format/#aliases-references) accurately, including recursive references and detection of circular dependencies. | ||
- **Preserve Token Properties**: Maintain additional token properties (e.g., [$extensions](#extensions)) throughout the resolution process. | ||
- **Handle Errors Gracefully**: Provide meaningful error messages for issues like invalid inputs or circular references. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<title>Design Tokens Resolver Module</title> | ||
<script | ||
src="https://www.w3.org/Tools/respec/respec-w3c" | ||
class="remove" | ||
></script> | ||
<script class="remove"> | ||
var respecConfig = { | ||
specStatus: 'CG-DRAFT', | ||
group: 'design-tokens', | ||
// In PR preview apps, shows an annoying red box to the document, | ||
// warning unsuspecting readers that they should not cite or | ||
// reference this version of the specification. | ||
isPreview: document.location.host.includes('preview'), | ||
editors: [ | ||
{ name: "Andrew L'Homme", email: '[email protected]' }, | ||
{ name: 'Drew Powers' }, | ||
{ name: 'Esther Cheran', email: '[email protected]' }, | ||
{ name: 'James Nash' }, | ||
{ name: 'Joren Broekema', email: '[email protected]' }, | ||
{ name: 'Louis Chenais' }, | ||
{ name: 'Mike Kamminga', email: '[email protected]' }, | ||
], | ||
shortName: 'design-tokens-resolvers', | ||
cg: 'Design Tokens W3C Community Group', | ||
cgURI: 'https://github.com/design-tokens/community-group', | ||
github: { | ||
repoURL: 'https://github.com/design-tokens/community-group', | ||
branch: 'main', | ||
}, | ||
tocIntroductory: true, | ||
logos: [ | ||
{ | ||
src: '/_includes/assets/images/logo_128_2x.png', | ||
url: 'https://www.designtokens.org', | ||
alt: 'Design Tokens Community Group', | ||
width: 128, | ||
height: 128, | ||
id: 'dtcg-logo', | ||
}, | ||
], | ||
}; | ||
</script> | ||
</head> | ||
<body> | ||
<section id="abstract"> | ||
<p> | ||
This specification extends the [format](../format/) and describes a | ||
method to work with alternate values for [design tokens](../), such as | ||
“light mode” and “dark mode” color themes for supporting devices. | ||
</p> | ||
</section> | ||
|
||
<section id="sotd"> | ||
<p> | ||
This is a snapshot of the editors’ draft. It is provided for discussion | ||
only and may change at any moment. Its publication here does not imply | ||
endorsement of its contents by W3C or the Design Tokens W3C Community | ||
Group Membership. Don’t cite this document other than as work in | ||
progress. | ||
</p> | ||
<p>This document has been published to facilitate Wide Review.</p> | ||
<p> | ||
This document was produced by the Design Tokens W3C Community Group, and | ||
contributions to this draft are governed by | ||
<a href="https://www.w3.org/community/about/process/cla" | ||
>Community Contributor License Agreement (CLA)</a | ||
>, as specified by the | ||
<a href="https://www.w3.org/community/about/process/#cgroups" | ||
>W3C Community Group Process</a | ||
>. | ||
</p> | ||
</section> | ||
|
||
<section | ||
class="informative" | ||
data-include="./introduction.md" | ||
data-include-format="markdown" | ||
></section> | ||
|
||
<section | ||
data-include="./terminology.md" | ||
data-include-format="markdown" | ||
></section> | ||
|
||
<section | ||
data-include="./syntax.md" | ||
data-include-format="markdown" | ||
></section> | ||
|
||
<section | ||
data-include="./resolution-logic.md" | ||
data-include-format="markdown" | ||
></section> | ||
|
||
<section | ||
id="conformance" | ||
data-include="./conformance.md" | ||
data-include-format="markdown" | ||
></section> | ||
|
||
<section id="acknowledgements" class="appendix informative"> | ||
<h2>Acknowledgments</h2> | ||
<p> | ||
This resolver spec wouldn’t have happened without the Hyma Team, | ||
including but not limited to Mike Kamminga, Andrew L'Homme, and Lilith. | ||
Significant contributions were also made by Joren Broekema, Louis | ||
Chenais. We thank the members of the Design Tokens Community Group for | ||
their contributions and feedback. | ||
</p> | ||
</section> | ||
</body> | ||
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
# Introduction | ||
|
||
Expressing alternate values for design tokens multiples the number of values to manage for every layer. This specification describes an efficient way to work with [=alternate values=]while producing the fewest minimal end number. We’ll compare a [naïve approach](#naive-approach) to the [resolver approach](#resolver-approach) outlined in this document. | ||
|
||
## Naïve approach | ||
|
||
The naïve approach multiplies the number of final values flatly with the number of alternate value layers. Mathematically, this can be expresed as the original starting number of tokens 𝑇, multiplied by layers of alternate values 𝐴𝑉, produces a final number of tokens 𝑇<sub>𝛥</sub>: | ||
|
||
<math display="block"> | ||
<mrow> | ||
<mi>T</mi> | ||
<mo>×</mo> | ||
<mi>AV</mi> | ||
<mo>=</mo> | ||
<msub><mi>T</mi><mi>Δ</mi></msub> | ||
</mrow> | ||
</math> | ||
|
||
<aside class="example" title="Naïve token increase"> | ||
|
||
Starting with 100 [color tokens](../format/#color): | ||
|
||
- Adding a 2nd “dark mode” layer of alternate values results in 200 values, or 100 × 2. | ||
- Adding a 2nd (“dark mode”), 3rd (“light mode - high contrast”), and 4th (“dark mode - high contrast”) layer results in 400 values, or 100 × 4. | ||
|
||
</aside> | ||
|
||
## Resolver approach | ||
|
||
The resolver approach involves breaking apart all tokens 𝑇 into subsets 𝑡<sub>1</sub>, 𝑡<sub>2</sub>, … 𝑡<sub>𝑛</sub>, and applying alternate value layers separately to produce a subtotal. The subtotals are added together to produce a final 𝑇<sub>𝛥</sub> value. The key difference is avoiding flat multiplication across the entire superset by breaking into subsets. Mathematically this may be expressed like so: | ||
|
||
<math display="block"> | ||
<mtable> | ||
<mtr> | ||
<mtd> | ||
<msub><mi>𝑡</mi><mn>1</mn></msub> | ||
<mo>×</mo> | ||
<msub><mi>AV</mi><mn>1</mn></msub> | ||
</mtd> | ||
<mtd> | ||
<mo>=</mo> | ||
</mtd> | ||
<mtd> | ||
<msub><mi>T</mi><mn>Δ1</mn></msub> | ||
</mtd> | ||
</mtr> | ||
<mtr> | ||
<mtd> | ||
<msub><mi>𝑡</mi><mn>2</mn></msub> | ||
<mo>×</mo> | ||
<msub><mi>AV</mi><mn>2</mn></msub> | ||
</mtd> | ||
<mtd> | ||
<mo>=</mo> | ||
</mtd> | ||
<mtd> | ||
<msub><mi>T</mi><mn>Δ2</mn></msub> | ||
</mtd> | ||
</mtr> | ||
<mtr> | ||
<mtd></mtd><mtd>...</mtd><mtd></mtd> | ||
</mtr> | ||
<mtr> | ||
<mtd> | ||
<msub><mi>𝑡</mi><mi>n</mi></msub> | ||
<mo>×</mo> | ||
<msub><mi>AV</mi><mi>n</mi></msub> | ||
</mtd> | ||
<mtd> | ||
<mo>=</mo> | ||
</mtd> | ||
<mtd> | ||
<msub> | ||
<mi>T</mi> | ||
<mi>Δn</mi> | ||
</msub> | ||
</mtd> | ||
</mtr> | ||
<mtr> | ||
<mtd> | ||
<msub><mi>T</mi><mn>Δ1</mn></msub> | ||
<mo>+</mo> | ||
<msub><mi>T</mi><mn>Δ2</mn></msub> | ||
<mo>+</mo> | ||
<mi>…</mi> | ||
<msub><mi>T</mi><mi>Δn</mi></msub> | ||
</mtd> | ||
<mtd><mo>=</mo></mtd> | ||
<mtd><msub><mi>T</mi><mi>Δ</mi></msub></mtd> | ||
</mtr> | ||
</mtable> | ||
</math> | ||
|
||
<aside class="example" title="Resolver approach"> | ||
|
||
1. Subset 𝑎, consisting of 100 color tokens, applies 4 alternate value layers (100 × 4). | ||
2. Subset 𝑏, consisting of 50 dimension tokens, applies 4 alternate value layers (50 × 4). | ||
3. Subset 𝑐, consisting of 50 typography tokens, applies 2 alternate value layers (50 × 2). | ||
4. Adding all subtotals together (400 + 200 + 100) produces 700 final values. | ||
|
||
700 is much fewer than the 2,000 tokens you’d get from the naïve method (100 × (4 + 4 + 2))! | ||
|
||
</aside> | ||
|
||
This illustrates the concept in abstract. See [syntax](#syntax) to see how it’s expressed in JSON. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔 I have no idea what happens to animations but in the future I’d love to resume this exploration (I’m no Val Head but I’m interested and have some knowledge here)