terrazzoapp / terrazzo

Use DTCG tokens in CI and code

Home Page:https://terrazzo.app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Make token private

snicol21 opened this issue · comments

How do i label some tokens as being private? I have some tokens that i want to exist soley to be referenced by aliases, but not be included with the final output?

You may be interested in following this issue on the official specification repo. Though there’s nothing in the specification that currently permits this, it does seem like the authors are open to the idea.

If we get to the point there’s loose consensus on how private tokens should be handled, I’m open to adding to this library. But I don’t want to jump the gun and add the wrong thing here and have the spec follow a different path.

Thanks @drwpow this makes a long of sense and I appreciate the quick response. I'm really excited to give these tools a shot, I've recently been deep in the weeds with style-dictionary, but after stumbling upon this library I feel like it makes way more sense and it will significantly cut out the need for me to manage all of these transformers, formatters, etc, so i'm hoping your library becomes the silver bullet.

Yeah I’m a big fan of Style Dictionary. And the W3C Design Tokens spec wouldn’t be what it is without all the awesome research and exploration Style Dictionary did. But the new spec is an improvement over SD in my opinion. And hopefully it becomes a more universal standard for design tokens in general.

Hopefully the spec eventually lands on naming.

If it's cool, I'd like to submit an idea for a temporary workaround. The basic idea is chaining plugins.

/**
 * Filters out $private tokens, and then pass the remaining tokens to the
 * passed plugin.
 *
 *  Token:
 * { "$value": "rebeccapurple", $type: "color", "$private": true }
 *
 * Config:
 * plugins: [
 *   pluginOmitPrivate({
 *     plugin: pluginCSS({ ...options... })
 *   })
 * ]
 */
export default function pluginOmitPrivate(options = {}) {
  return {
    name: 'plugin-omit-private',
    async build({ tokens, metadata }) {
      // TODO keep an eye on https://github.com/design-tokens/community-group/issues/110
      const filteredTokens = tokens.filter((token) => token?.$private !== true)

      return await options.plugin.build({ tokens: filteredTokens, metadata })
    },
  }
}

FWIW, I had the same requirement in my work and ended up making a custom plugin similar to @jbarreiros one above.

However, I had the additional challenge that most of my public tokens were aliases for private ones which had modes. And my intent was to get CSS output where there various per-mode resolutions of the public tokens were available. An example probably makes this clearer:

{
  "private-token": {
    "$type": "color",
    "$value": "#000000",
    "$extensions": {
      "mode": {
        "light": "#000000",
        "dark": "#FFFFFF"
      }
    } 
  },
  
  "public-token": {
    "$type": "color"
    "$value": "{private-token}"
  }
}

...and my desired CSS output was something like this:

:root {
  --public-token: #000000;
}

.dark-mode {
  --public-token: #FFFFFF;
}

However, just filtering the tokens means you only end up with something like:

:root {
  --public-token: #000000;
}

Because the "public-token" does not itself have modes, so only its (default) $value gets resolved.

(In actual fact, my use case was a tad more complex as I had 2 different sets of modes (one for light/dark and one for different sub-brands), so there was a chain of aliases to provide all the possible permutations of those modes.)

Long story short, I ended up making a plugin that can follow those alias chains for tokens and resolve them for specified combinations of mode names and then add the result as new modes to those tokens. Then I can filter out the private ones and pass the result to the CSS plugin. It's a bit clunky, but it works!

Unfortunately, the design system I'm working on is not (yet) open-source, so I can't share my plugin's code. Hopefully outlining the approach here might at least help others facing the same issue.