amzn / style-dictionary

A build system for creating cross-platform styles.
https://styledictionary.com
Apache License 2.0
3.87k stars 543 forks source link

How to avoid Collisions on Figma variables with multiple columns? #1246

Closed bruno-lucas141 closed 3 months ago

bruno-lucas141 commented 3 months ago

I've recently discovered that it is possible to use style-dictionary to transform Figma information into css/scss variables.

The issue is that i have some variables that have multiple columns and style-dictionary is overriding the variables.

is it possible to use a callback so i could decide what to do with the collisions? Or are there any custom function that i can send to customize the way the variables are created?

PSB an example of variable with multiple columns from Figma

{
  "style.Dark.json": {
    "Primary": {
      "$type": "color",
      "$value": "#000000",
      "$description": "",
      "$extensions": { "com.figma": { "hiddenFromPublishing": false, "scopes": ["ALL_SCOPES"], "codeSyntax": {} } }
    },
    "Secondary": {
      "$type": "color",
      "$value": "#000000",
      "$description": "",
      "$extensions": { "com.figma": { "hiddenFromPublishing": false, "scopes": ["ALL_SCOPES"], "codeSyntax": {} } }
    }
  },
  "style.Light.json": {
    "Primary": {
      "$type": "color",
      "$value": "#ffffff",
      "$description": "",
      "$extensions": { "com.figma": { "hiddenFromPublishing": false, "scopes": ["ALL_SCOPES"], "codeSyntax": {} } }
    },
    "Secondary": {
      "$type": "color",
      "$value": "#ffffff",
      "$description": "",
      "$extensions": { "com.figma": { "hiddenFromPublishing": false, "scopes": ["ALL_SCOPES"], "codeSyntax": {} } }
    }
  }
}
jorenbroekema commented 3 months ago

Right now there isn't a way to customize how token collisions are handled, our deep-merge utility will handle it using the array order, so if you specify the source like so:

{
  "source": [
    "tokens/foo.json",
    "tokens/bar.json"
  ]
}

Then any collisions between foo and bar will mean that the duplicate definitions in foo will be overridden by those in bar.

So even though there isn't something like an onTokenCollision callback that allows you to customize the behavior, you can somewhat control it through ordering the "source" array values. Note that if you use globs, they will always resolve alphabetically, so "source": ["tokens/*.json"], assuming still that we have foo.json and bar.json, should mean that the foo definitions will override the bar definitions, the opposite of the previous example.

jorenbroekema commented 3 months ago

Btw, I am open to creating a callback, but I'd have to know a bit more about use cases where the ordering of "source" array isn't sufficient as a means to control how collisions are handled

bruno-lucas141 commented 3 months ago

I've managed to solve my issue but that required a Figma token refactoring. Instead if adding the values as new columns under the same variable i've grouped them.

Before: image

After: image

By using the refactored structure style-dictionary created a single scss/css variable for each parameter with no collisions. image

To create Figma groups just use / in the name when creating a variable like so: brands/Brand3/Primary