style-dictionary-utils
style-dictionary-utils copied to clipboard
Generate additive tokens with rgb value outputs
HI Lukas. I have a question on how we might go about doing something and think it could be of value to your repo.
So (sadly) we are supporting a Bootstrap theme and need some of our tokens to line-up with Bootstrap CSS Vars. One of the things they do is create CSS vars like this:
--bs-primary: #0d6efd;
--bs-secondary: #6c757d;
--bs-success: #198754;
--bs-info: #0dcaf0;
--bs-warning: #ffc107;
--bs-danger: #dc3545;
But because the hex values don't handle opacity, they also generate RGB values from these hex values, like so:
--bs-primary-rgb: 13, 110, 253;
--bs-secondary-rgb: 108, 117, 125;
--bs-success-rgb: 25, 135, 84;
--bs-info-rgb: 13, 202, 240;
--bs-warning-rgb: 255, 193, 7;
--bs-danger-rgb: 220, 53, 69;
So how do we go about handling this with Style Dictionary? My colleague Doug has worked out a custom transformer, but we still have some questions.
-
We only need this for a handful of the color tokens. We don't want to generate these RGB values for 100's of tokens. More like a dozen or so, but it would be nice to automate to reduce maintenance and errors.
-
Is there a way to 'handpick' or label specific tokens to be processed so that we retain the hex token but also output the RGB values for it as well?
-
Given that the W3C spec wants colors defined in Hex and they suggest conversion to other color spaces, how do you think is the best way to approach this?
Hey @jkinley,
firstly, hex values do work with opacity, the format is called hex8 and the last 2 digits are the opacity in hex.
-
You need to create a filter that can detect which colors need this. This could be as simple as adding a config file or an array with the token names in the filter or you could add a property like
usesOpacity. -
You can't output two tokens from one using a transformer. For this you need to create a custom format which can handle this.
-
I think the optimal way is to use
hex8. If bootstrap needs the rgb values and hex values I would just create a format (this can be the filter and format in one, if this is the only place where you need to filter).
Hope that helps.
firstly, hex values do work with opacity, the format is called
hex8and the last 2 digits are the opacity in hex.
Yes. I am aware of hex8, but that does not help us get the RGB values that we need for Bootstrap. We will look into your other suggestions. Thanks!
Great use-case! This brings us to the potential need for a token object model (aka TOM), which isn't easy to codify, but I'll post this here so I can both plant the seed and subscribe to this thread.
i have done this with some custom functions (transformers etc) my use case was allowing variable consumers to change alpha for a variable i feel this will be temporary requirement as modern browser support relative color
Can you share more about how you did this? Maybe a PR if we feel it would solve the issue?
Can you share more about how you did this? Maybe a PR if we feel it would solve the issue?
i will put a minimal example here soon
@lukasoppermann here is a minimal gist to showcase this use case
Nice approach @anoopsinghbayes.
I think this is a great solution in general.
Do you not add a type: color and this is why it is not processed by style dictionary afterwards?
Do you not add a
type: colorand this is why it is not processed by style dictionary afterwards?
Can you explain what does this mean? i see type:color on all the token definitions in my example
blue: {value: "#0d6efd", type: "color"},
grey: {value: "#6c757d", type: "color"},
green: {value: "#198754", type: "color"},
azure: {value: "#0dcaf0", type: "color"},
orange: {value: "#ffc107", type: "color"},
red: {value: "#dc3545", type: "color"},
primary: {value: "{color.blue}", type: "color"},
secondary: {value: "{color.grey}", type: "color"},
success: {value: "{color.green}", type: "color"},
info: {value: "{color.azure}", type: "color"},
warning: {value: "{color.orange}", type: "color"},
danger: {value: "{color.red}", type: "color"},
refered: {
value: "rgb({color.primary-rgb} / .2)",
type: "color",
},
I have just put this example to showcase what can be done
Can you explain what does this mean? i see type:color on all the token definitions in my example
Yes, but not on the rgb tokens. It seems like the preprocess: https://gist.github.com/anoopsinghbayes/c1b9003dc0700cd119f345fb997d23ed#file-index-mjs-L5-L68 does not add a type and thus the tokens are ignored in any transformation, correct?