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

Support aliasing both current value, and overridden value #1001

Open stephan-noel opened 1 year ago

stephan-noel commented 1 year ago

Hi, thanks for the great library. I'll try to explain my use cases well as I'm trying to figure out ways to reduce the amount of duplication with aliasing without resorting to javascript.

Motivation

Use Case 1: Be able to keep using JSON aliasing without repeating myself.

{
  "font": {
    "family": {
      "main": {
        "shared": "{font.family.main.value}",
        "value": "var(--jost), {font.family.main.shared}"
      }
    }
  }
}

This results in mutual recursion, but I want the font.family.main.value in "override" to refer to the one I define in ../../../node_modules/shared-tokens/index.json. This way I can augment values.

Config.json

{
  "include": ["../../../node_modules/shared-tokens/index.json"],
  "source": ["./tokens/**/*.json"],}
}

One approach inspired by lage/turborepo is to use ^,

{
  "font": {
    "family": {
      "main": {
        "value": "var(--jost), {^font.family.main.value}"
      }
    }
  }
}

Now it refers to the font.family of the outcome of "include" in the config.json. There may be a lot of complications and dynamicity here, but I'd like to reduce repetition without maually merging myself.

Use Case 2: Live Aliasing

I want the typography.body.font.value to be composed of the same thing, yet have the new font.family.main.value that I am overriding. Currently, I have to repeat:

{ "typography": { "body": { "font": { "value": "{font.weight.regular} {font.size.16} {font.family.main.value}" } }, }

But I'd like font.family.main.value to be overridden with whatever value I set now instead of having the old value, I want the aliases to be live.

Without these, I either have to do a lot of duplication when overriding tokens, or I have to switch to JS and do deep merging manually.