Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom value transforms skip values with aliases #451

Closed
avkvirtru opened this issue Aug 7, 2020 · 10 comments
Closed

Custom value transforms skip values with aliases #451

avkvirtru opened this issue Aug 7, 2020 · 10 comments

Comments

@avkvirtru
Copy link

Existing related issues

Maybe #208, although that seems like a larger architectural discussion.

Environment

style-dictionary --version
2.10.1

node -v
v12.16.1

npm -v
6.13.4

Test case

Given the following config.js:

// configure Style Dictionary with default & custom configs 
// https://github.com/amzn/style-dictionary/issues/344#issuecomment-543285393
const StyleDictionary = require('style-dictionary');

// defines a custom transform for CSS variables
// to translate aliases `{vds.custom.value}` into CSS vars `var(--vds-custom)`
// https://amzn.github.io/style-dictionary/#/api?id=registertransform
const alias_syntax = /\{([^\}]+)\}/gm;
StyleDictionary.registerTransform({
  name: 'css/custom_vars',
  type: 'value',
  matcher: function(prop) {
    if (alias_syntax.test(prop.original.value)) {
      console.log(`:) MATCHING ${prop.original.value}`);
      return true;
    } else {
      return false;
    }
  },
  transformer: function(prop) {
    console.log(`~ TRANSFORMING ${prop.original.value}`);
    return prop.original.value;
  }
});

StyleDictionary.registerTransformGroup({
  name: 'css-vds',
  transforms: [
    // custom transforms registered above
    "css/custom_vars",

    /* css default transform group = 
     * attribute/cti name/cti/kebab time/seconds content/icon size/rem color/css 
     * https://amzn.github.io/style-dictionary/#/transform_groups?id=css
     **/
    "attribute/cti",
    "name/cti/kebab",
    "time/seconds",
    "content/icon",
    "size/rem",
    "color/css",
  ]
});

module.exports = {
  "source": ["lib/styles/style_dict/tokens/**/*.json"],
  "platforms": {
    "css": {
      "transformGroup": "css-vds", 
      "buildPath": "lib/styles/build/css/",
      "files": [{
        "destination": "design_tokens.css",
        "format": "css/variables"
      }]
    }
  }
}

And the following tokens.json:

{
  "vds": {
    "font": {
      "scale": {
        "base": { 
          "value": "1.6rem"
        },
        "multiplier": {
          "value": "1.25"
        }
      },

      "size": {
        "md": {
          "value": "{vds.font.scale.base.value}"
        },
        "sm": {
          "value": "calc({vds.font.size.md.value} / {vds.font.scale.multiplier.value})"
        }
      }
    }
  }
}

Actual behavior

I see the following output:

style-dictionary build --config=./lib/styles/style_dict/config.js


css
:) MATCHING {vds.font.scale.base.value}
:) MATCHING calc({vds.font.size.md.value} / {vds.font.scale.multiplier.value})
✔︎  lib/styles/build/css/design_tokens.css

Note how only the MATCHING lines are logged…

Expected behavior

I expect to see the following:

style-dictionary build --config=./lib/styles/style_dict/config.js


css
:) MATCHING {vds.font.scale.base.value}
~ TRANSFORMING {vds.font.scale.base.value}
:) MATCHING calc({vds.font.size.md.value} / {vds.font.scale.multiplier.value})
~ TRANSFORMING calc({vds.font.size.md.value} / {vds.font.scale.multiplier.value})
✔︎  lib/styles/build/css/design_tokens.css

Note how both MATCHING and TRANSFORMING lines are logged…

Changing the registerTransform option from type: 'value' to type: 'name' or type: 'attribute' gives the expected behavior.

Is this intended?

@avkvirtru avkvirtru changed the title Custom value transforms, skip values with aliases Custom value transforms skip values with aliases Aug 7, 2020
@nategreen
Copy link

I came here to report this too—I was trying to do the same as #452 (piece together a token from an opaque color and an alpha value), but found that if I pulled the rgb from the opaque token via aliases, the color transforms weren't being applied. After logging all the transforms and scratching my head, it seems that aliased values just aren't transformed, even though they match the matcher given.

@dbanksdesign
Copy link
Member

This is "working as expected" right now, but something we plan to fix in the next major version. Right now the "build" happens in a few distinct steps. The relevant steps to this are: transforming the tokens and then resolving aliases/references which are done in 2 passes of the entire style dictionary object as seen in this build diagram. Notably the transform step skips doing any value transforms on values that reference other values. Here is the line of code that does that: https://github.com/amzn/style-dictionary/blob/main/lib/transform/property.js#L36 The original intent was that the aliased token should already be properly transformed for the given format.

Doing it this way does make it impossible to do certain things like output a variable reference in an output file, --color-a: var(--color-b); for example or modify a value like darken a referenced color. It also doesn't fit the mental model people have about how the build process works. So we are fixing that in the next major version. We have a proposed solution already, we just need to do some more testing and branch clean up and other work for the next major release.

@nategreen
Copy link

Cool. For now since we're just doing web, I can use my workaround and I'll eagerly await v3 😎 Thanks @dbanksdesign !

@avkvirtru
Copy link
Author

I'm still using type: 'name' in my local transform to get what I need.

@pryaniq
Copy link

pryaniq commented Oct 5, 2020

+1.

@dbanksdesign thanks for explanation.

It would be really handy to transform resolved value. So I'm looking forward to this feature.

@chazzmoney
Copy link
Collaborator

This should work with the coming release of Style Dictionary 3.0. I will leave the issue open until the release occurs, but wanted to give you all a heads up that a solution was merged into the codebase with #371

@dbanksdesign
Copy link
Member

For those curious and want to get access to this right now, you can install the upcoming release of style dictionary with the next tag: npm install style-dictionary@next.

Here is an example using transitive transforms in the next version of Style Dictionary: https://github.com/amzn/style-dictionary/tree/3.0/examples/advanced/transitive-transforms

And this documentation page has a more detailed explanation of upcoming changes in 3.0: https://amzn.github.io/style-dictionary/#/version_3

@chazzmoney
Copy link
Collaborator

This is now released as part of 3.0 via #636

@ghost
Copy link

ghost commented Jan 23, 2022

Is it possible to improve the conversion of json tokens using primitive math?
For example, I have a set of brightness values, and I simply add it depending on the state of the button.
Снимок экрана 2022-01-23 в 05 30 06

thus I take this code and use it in Figma Token and it works
Снимок экрана 2022-01-23 в 05 31 49
Снимок экрана 2022-01-23 в 05 32 04

Figma Token uses its own script to transform the value into a valid number.

So, is it possible to do this?

@Jasperrr91
Copy link

Jasperrr91 commented Feb 16, 2023

This should work with the coming release of Style Dictionary 3.0. I will leave the issue open until the release occurs, but wanted to give you all a heads up that a solution was merged into the codebase with #371

@chazzmoney this is (still?) broken in 3.7.2 with type: 'value'

Edit: I was mistaken, it is working with transitive: true but the examples seem to be lacking and the property is hidden away deep inside of the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants