amzn / style-dictionary

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

Token partially transformed #1090

Open lewispeel opened 9 months ago

lewispeel commented 9 months ago

Hello!

I'm having an issue transforming a color token and wondered if anyone else has seen this or have any tips on how to solve it. I'll simplify and remove unnecessary parts of my setup for brevity but hopefully it's detailed enough for you to understand what's going on.

FYI - I'm not responsible for the token structure, only transforming them via Style Dictionary so please let me know if the structure is the problem. Also, if it's relevant.. we're using Tokens Studio via Figma to generate these.

// Palette.json
{
  "Palette": {
    "Black": {
      "Black 100": {
        "value": "#000000",
        "type": "color"
      }
    }
  }
}
// Tokens.json
{
  "Brand": {
    "Navigation": {
      "nav-gradient": {
        "value": "linear-gradient(0deg, {Palette.Black.Black 100} 0%, {Palette.Black.Black 100} 100%)",
        "type": "color"
      }
    }
  }
}

I have setup a custom color transform as our target platform requires ARGB values.

const customColor = {
  name: "custom/color",
  type: "value",
  matcher: (token) => token.type === "color",
  transformer: (token) => toArgb(token.value),
};

Looking at the logs, I can see that Black 100 gets converted fine and other tokens that reference this work as expected. However, when nav-gradient is put through customColor, the matcher is returning true as expected but it's not being passed to the transformer. I suspect this is because the value being passed in malformed e.g. linear-gradient(0deg, 0xff000000 0%, 0xff000000 100%) and doesn't know what to do with it. I have other linear-gradients in my token files that work fine, but those don't use references.

Is there anything I can do to solve this?

jorenbroekema commented 9 months ago

The reason wwhy your nav-gradient token is not being transformed is because it contains a token reference/alias ({Palette.Black.Black 100}. By default, transforms do not transform tokens with references in its value.

What you could do if you absolutely must transform it after the references have been resolved, is use a transitive transform (setting transitive: true). See docs: https://amzn.github.io/style-dictionary/#/transforms?id=transitive-transforms

However, in your example I don't really think a transitive transform is gonna work, because I'm going to assume that your toArgb function is not going to be able to understand CSS linear-gradient syntax?

Maybe for me to understand your use case better, can you show me what your output CSS is and what your expected or desired output is versus that?