Maybe #208, although that seems like a larger architectural discussion.
style-dictionary --version
2.10.1
node -v
v12.16.1
npm -v
6.13.4
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})"
}
}
}
}
}
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…
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?
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.
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.
Cool. For now since we're just doing web, I can use my workaround and I'll eagerly await v3 😎 Thanks @dbanksdesign !
I'm still using type: 'name' in my local transform to get what I need.
+1.
@dbanksdesign thanks for explanation.
It would be really handy to transform resolved value. So I'm looking forward to this feature.
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
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
This is now released as part of 3.0 via #636
Most helpful comment
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.