Style-dictionary: reference token groups

Created on 8 Mar 2021  路  4Comments  路  Source: amzn/style-dictionary

Imagine the dictionary below, with a group (font.heading.body) of tokens:

font.json:

{
   font: {
      heading: {
          body: {
             size: { value: 16 },
             type: { value: 'Arial' },
             weight: { value: 'bold' }
      }
   }
}

Let's say we want to reference this group of tokens inside a component:

{
   hero: {
      bar: {
          // here I want to apply {font.heading.body}, so that I get hero.bar.size, hero.bar.type, hero.bar.weight
      }
   }
}

What is the best way to achieve this?

question

Most helpful comment

There is one way to do this now, just not in JSON. Token source files can be JS modules as long as they export a plain object. I made a quick gist for you based on your example: https://gist.github.com/dbanksdesign/0fdd18e27b54d892fbd0df467f48ea91

There is unfortunately no way to do this in JSON (or JSON5) source files. Hopefully this helps!

All 4 comments

There is one way to do this now, just not in JSON. Token source files can be JS modules as long as they export a plain object. I made a quick gist for you based on your example: https://gist.github.com/dbanksdesign/0fdd18e27b54d892fbd0df467f48ea91

There is unfortunately no way to do this in JSON (or JSON5) source files. Hopefully this helps!

Hi,

Thanks for taking the effort to create the gist! This would be a great way to do this indeed 馃憤

Currently we maintain our dictionary in JSON though, for the following reasons:

  • declarative format, allows for better collaboration between different disciplines (devs and UXers)
  • could more easily be supported by tools like Sketch in the future
  • allows for more meta info that can be consumed in documentation

To achieve this, I created a small preprocessor in my personal fork last week that allows for a declaritive syntax via an @apply decorator.

          /**
           * Override if '@apply' decorator is added before the key
           * In the example below, key1 would be overridden, key2 would be preserved
           * @example
           * {
           *   "external": {
           *     "ref": {
           *       "key1": { "value": "x" },
           *       "key2": { "value": "y" },
           *     }
           *   }
           * }
           * // application
           * {
           *   "myComponent": {
           *     "key1": { "value": "q" }, // => overridden
           *     "@apply": { "value" : "{external.ref}" },
           *     "key2": { "value": "z" }, // => not overridden
           *   }
           * }
           */

It also allows us to interpret this as meta data, so we can create documentation about interdependent relations, like:

| Component token | Referenced token |
--- | ---
| SwitchThumbFocused | FocusRing, ... |

So we want to keep our current solution for the reasons mentioned above, but I could see others using your solution in different cases 馃憤

@dbanksdesign since we want be up to date with latest style-dictionary (and don't want to maintain our own fork): would it be possible to provide a hook inside exportPlatform.js?

We would basically need to preprocess the complete dictionary, right before regular transforms run (a function that gives the dictionary as a parameter would be enough).

@dbanksdesign what would be the process of adding a hook? would you like a proposal for how the hook would work what API it would have and even create a PR?

or what would be best?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

blackfalcon picture blackfalcon  路  4Comments

dbanksdesign picture dbanksdesign  路  5Comments

clepore picture clepore  路  5Comments

chazzmoney picture chazzmoney  路  5Comments

tonyjwalt picture tonyjwalt  路  5Comments