Skip to content

DTCG extension: $ref and $defs #405

@drwpow

Description

@drwpow

Proposal

Thinking through upcoming changes to the DTCG specification, there have been not only requests to alias tokens in other files, but some future proposals depend on use of multiple files.

I introduced a proposal to add this to DTCG, but as I’m thinking through it more, this may conflict with some other thinking in the specification, and it may not pass, and that’s fine. But the idea of supporting it in Terrazzo has been growing, either way, because ultimately it is a backwards-compatible extension to DTCG so adopting it wouldn’t be a “fork” in any sense.

Pros / Cons

I listed out several pros and cons in the original proposal, but in a nutshell this solves all the following problems:

  • Aliasing tokens in other files
  • More complex uses of modes/theming
    • In fact, this may even replace modes/theming but that’ll be a separate RFC
  • Ultimate token reuses (think beyond $value—this lets you reuse descriptions, groups—everything!)

All while being backwards-compatible to the spec

⚠️ Future mode changes

This is NOT part of this issue, however, I wanted to share a possibility of how $refs and $defs could replace modes.

Pretend you have a color system that has light and dark color modes, as well as protanopia/deuteranopia modes. Using $extensions.modes you’d declare overrides like so:

{
  "color": {
    "$type": "color",
    "red": {
      "1": {
        "$value": "Red1",
        "$extensions": {
          "mode": {
            "dark": "Red2",
            "lightProtanopia": "Red3",
            "darkProtanopia": "Red4"
          }
        }
      }
    }
  }
}

But the longstanding problem with modes has been when does each mode kick in? and you have been left to resolve that yourself. With $refs, instead, you’d start by declaring your end themes in separate files, like so: light.json, dark.json, light-protanopia.json, dark-protanopia.json. But that would be way too much duplication, wouldn’t it? you’d say. It would have been… before $refs. Now consider how simple dark-protanopia.json is:

{
  "$ref": "dark.json", // import all of `dark.json`, but keep the local overrides
  "color": {
    "red": {
      "1": "Red4"
    },
    "green": {
      "$ref": "light.json#/color/green" // reuse light.json’s green palette
    }
  }
}

Every end-file can pull from any other tokens set it wants to, while only minimally declaring its overrides. This lets you use modes, just in a more holistic sense—you don’t have to go through all the trouble of declaring all the mechanisms and code to make certain modes kick in, or not. You simply start with your final adjustments, which could even be a single token override.

Now the thing we lose is exactly the thing that perhaps attracted people to modes in the first place—this does encourage multiple token files over one. However, in general, most people managing tokens do request to split the tokens into bite-sized, readable files.


Again, this proposal DOES NOT introduce any changes to modes on its own; we may keep both. But just outlining all the possibilities this unlocks, and all the freedom it gives people to manage their tokens, which is why I’m interesting in “just supporting it” in Terrazzo, come what may.

Metadata

Metadata

Assignees

No one assigned

    Labels

    2.0Needed for 2.0cli@terrazzo/clip1High priorityparser@terrazzo/parser

    Type

    No type

    Projects

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions