style-dictionary
style-dictionary copied to clipboard
RFC: What would you like to see in Style Dictionary 4.0?π©π½βπ»π‘
Hey SD community... we need your help!
We would really love to hear what YOU would like to see in SD 4.0. Answers to this might include answers to these questions:
- What do I wish I could do with SD that I just can't right now?
- What do I want from a next generation Design Token Management tool?
- Whats next after Style Dictionary?
- (Your idea here)
We would love to hear all your thoughts - we might* even send you some SD swag***...
- There is no guarantee, I don't even know how to send something physically to someone on github... *** Right now this ONLY consists of stickers of our mascot, Pascal. But I really want a Pascal stuffie/plushie... and maybe a tote bag, or a water bottle, or coffee cup, or phone case, hoodie, throw pillow, pajamas, or... really, anything Pascal. Danny made him way too cute to be relegated to an existence consisting only of stickers.
I'd love to see a few things to better support strongly typed languages such as Kotlin/Java:
-
Support passing context between a transform and a format. Kotlin, Java, Swift, etc. require imports, but when a transform such as
color/composeColor
uses a type that needs to be imported, there's no way to tell the format that it needs to add that import statement at the top of the file- we just have to import all the things a transform could want. -
References across output files. For example, I'd like to be able to have Style Dictionary support generating these two objects in separate files in a safe manner:
object Palette { val gray: Color = Color(0xcccccc) } object LightColors { val background: Color = Palette.gray }
Right now I'm doing this by passing
Palette
as aclassName
option to the format that generates theLightColors
, but that feel hacky- I'd love if references could keep some of that context for me.
I'd love to be able to create different formats and transforms based off different sources (if we can't do already)
@lewishealey could you elaborate a bit on this?
@didoo @nhoizey @EvanLovely @kharrop @Tenga @jbarreiros @tonyjwalt @7studio @lukasoppermann
Would love your thoughts!
I am not sure how easy it is now, but splitting output by theme would be interesting.
E.g. you have dark / colors / background
and light / colors / background
and want to get two css files or better be able to define if two files or maybe one file but nested within two parents: body {...} and body.dark-mode { ... }
Still very rough, but this is something we work on currently. (Not just for the web of course)
Some initial thoughts.
I think a possible focus could be on making SD do things better, not necessarily do more. For example, I think one inevitable thing (and I am not saying it lightly, I understand the complexity of it) would be to convert the entire codebase to TypeScript. I know it's a huge, massive work. But this would make the refactoring of code (for its evolution) so much better! For those who have to touch the codebase, the knowledge that there is something in place that allows code refactoring without worrying that you forgot to change one prop or variable name somewhere in a file, is a game changer. This will not impact the final user, I know, but I think is a very important "safety feature" to add to the project.
Another thing I was thinking was the website and the documentation: I know also this one is huge and requires a massive effort, but I think is long past overdue :) (I suspect there is also a GH issue, somewhere, where this discussion already happened). There are so many things we could do in this area, and so many good websites of open-source projects where we could get inspiration from (in terms of exposing to the users the documentation/information in a smart way)
One last thing, possibly controversial: what if instead of "adding something" we "remove something"? The risk I see for many open-source projects is feature bloat, and I would be extremely sad to see this happen to SD. Quoting Antoine de Saint-Exupery βPerfection is Achieved Not When There Is Nothing More to Add, But When There Is Nothing Left to Take Awayβ π
Support for naming structures with nested/default values.
Given end result token names of:
$color-white
$color-white-alpha
It's not currently possible to achieve this with a token structure like:
color: {
white: {
value: '#fff',
alpha: {
value: 'rgba(1,1,1,0.8)',
},
},
}
The alpha token is treated as an attribute of the white token.
We're currently solving this with a default
value, which is then renamed in the formatter to remove the suffix. Not an ideal solution as we should only be mutating tokens during the transform step.
color: {
white: {
default: {
value: "#fff",
},
alpha: {
value: 'rgba(1,1,1,0.8)',
},
},
}
Possible solutions
- A new type of transformer for modifying paths. This could allow us to rearrange the structure dependent on platform/token matcher.
- Provide a configuration to limit the keys of attributes, in order for the parser to understand when to continue traversing the object for values.
- this could also be achieved by enabling users to provide a custom traverser
I would like the ability to create multi-file formats. For instance, being able to generate an iOS Asset Catalog containing named colors (*.colorset)
Hi, there are multiple things I would like to have in SD, which are already listed in the issues.
I agree with what @jacoblapworth asks for, and it is already in #366.
For Sass modules with @use
, I would like to have a simple way to generate simple Sass files with automatic addition of @use
directives where required, depending on references: #618
As Design Tokens are often part of a Design System, I would like to have a simple way to document tokens. I'm currently struggling with Storybook to do that, as I showed in #477 and https://github.com/storybookjs/storybook/issues/7671#issuecomment-797064663 . Maybe there could be a Storybook plugin as part of the SD project. Maybe for other Design System / documentation tools too.
I would also like to be able to "treat file path as prefix for property path", as asked in #104
I would appreciate the ability to transform design tokens into color palettes usable by designers such as .ase, .clr and .sketchpallete.
You can refer to to the following project to estimate the required effort:
- https://github.com/IBM-Design/color-bee <-- Color Bee takes one JavaScript file of colors and creates .ase, .clr, .json, .scss, and .sketchpallete files
- https://github.com/kitoko552/clrpalette <-- Generate a .clr from a JSON file
There is also mac centric projects (e.g., objective-c and swift):
- https://github.com/ramonpoca/ColorTools
- https://github.com/tomokitakahashi/ColorPalletGen
- https://github.com/kaelig/tokens2palettes-example
- https://github.com/muukii/ColorGen
- https://github.com/naoty/clr
- https://github.com/RedMadRobot/RMRColorTools-iOS
I want more built-in support for integrations/plugins/extensions to popular design tools like figma, sketch, framer-motion...
Now that there is an official glossary published by the Design Tokens W3C Community Group: https://www.designtokens.org/glossary/
Just as "properties" were renamed to "tokens" for v3, v4 could see "category" (in CTI) renamed to "type", but then "type" would have to be renamed to something elseβ¦ maybe "property"? π
We would move from CTI to TPIβ¦
I would love to see the possibility to derive different tokens from the same source! For example color-red
would lead to color-red
(hex) and color-red-rgb
(rgb). color-red-rgb
can then be referenced by other tokens, like any other token can.
Right now we have to use formats, which makes referencing the derived rgb-tokens difficult. To us, the rgb-tokens are first-level tokens. We simply dont want to specify them additionally to the hex-tokens, since that is redundant.
While I have different use cases, I also would love something like @andre-brdoch see: #695
feature request possibly:
- add
outputReferences
to the scss/map-deep - would expect the option https://amzn.github.io/style-dictionary/#/formats?id=references-in-output-files
https://amzn.github.io/style-dictionary/#/formats?id=scssmap-deep
before:
/**
* Do not edit directly
* Generated on Tue, 05 Oct 2021 21:06:03 GMT
*/
$list-components-date-font-weight: 900 !default;
$links-bar-font-size: 14px !default;
$blocks: (
'list': (
'components': (
'date': (
'font-weight': $list-components-date-font-weight
)
)
),
'links-bar': (
'font-size': $links-bar-font-size
)
);
ideally after:
/**
* Do not edit directly
* Generated on Tue, 05 Oct 2021 21:06:03 GMT
*/
$blocks: (
'list': (
'components': (
'date': (
'font-weight': 900
)
)
),
'links-bar': (
'font-size': 14px
)
);
Dynamic outputs would be awesome as well https://github.com/amzn/style-dictionary/issues/667#issue-941786692
this library is still in development, right? @chazzmoney
This is still in development, we are working a bit more slowly recently because other priorities and personal things. And we are still looking to build a plan for a 4.0 release in the future.
I might already be able to do this, but I'm new to using style-dictionary; I haven't seen it in the docs though.
It would be cool if I could do something like this:
"size": {
"base": { "value": 4 },
"half": { "value": "{size.base.value}", "divide": 2 },
"2": { "value": "{size.base.value}", "multiply": 2},
"3": { "value": "{size.base.value}", "multiply": 3},
}
Or perhaps accepting the MathJSON formatting: "half": { "value": ["Divide", "{size.base.value}", 2] }
.
This way, if a designer changed their minds about what the base was, I could change a single value and then let math do the rest. (also if there is already a way to do this please let me know).
Thanks for considering!
There might already be a clever way to achieve a nicely formatted design token changelog, or be out of scope for a CLI tool, but I'd love it if StyleDictionary could help provide an output of what tokens changed - from one generation to another (one version to another).
To give an example, StyleDictionary could accept two separate properties folders as input. Could be one version of properties folder from master branch, and another from current topic branch. The output would be a nicely formatted list of which tokens were added, removed and changed.
Simply thinking out loud π¨βπ»
Define files programatically
I would like to be able to generate files based on current dictionary. When you have a dynamic number of components or you have more than 100 components tokenized it's hard to maintain the list of files.
Export all components variables into a single file is not efficient when you can include in your app only a sub set of all available components.
I would like to have something like this:
files: [{
destination: `components/*.css`,
format: 'css/component',
filter: token => token.path[0] === 'component',
split: dictionary => {
const uniqueItems = [...new Set(
dictionary.allTokens
.filter(token => token.attributes?.item)
.map(token => token.attributes.item)
)]
return uniqueItems.map(item => ({
destination: `${component}.css`,
filter: token => token.item === item,
}));
}
}]
Then easily you can get 1 file per item or any other split you would like to do attending to the token properties.
Migrate to ESM
Deprecate CommonJS in in favor of ESM.
Support for naming structures with nested/default values.
Given end result token names of:
$color-white
$color-white-alpha
It's not currently possible to achieve this with a token structure like:
color: { white: { value: '#fff', alpha: { value: 'rgba(1,1,1,0.8)', }, }, }
The alpha token is treated as an attribute of the white token.
We're currently solving this with a
default
value, which is then renamed in the formatter to remove the suffix. Not an ideal solution as we should only be mutating tokens during the transform step.color: { white: { default: { value: "#fff", }, alpha: { value: 'rgba(1,1,1,0.8)', }, }, }
Possible solutions
* A new type of transformer for modifying paths. This could allow us to rearrange the structure dependent on platform/token matcher. * Provide a configuration to limit the keys of attributes, in order for the parser to understand when to continue traversing the object for values. * this could also be achieved by enabling users to provide a custom traverser
I had this same issue, and followed @MrDevinB's suggestion of using a special character like "@": https://github.com/amzn/style-dictionary/issues/119#issuecomment-580472661
I'd love to see things restructured into external files / folders and I second @didoo 's Typescript sentiments.
Ability to have transforms that allow one-to-many tokens.
This would be useful for something like color steps in a palette to be dynamically generated.
An idea for it
"neutral": {
"light": {
"value": "{ color.lightest.value }",
"steps": {
"type": "darken",
"amount": {
"50": 0.5,
"100": 1,
"150": 1.5,
"200": 2,
"250": 2.5,
"300": 3,
"350": 3.5,
"400": 4,
"450": 4.5,
"500": 5
}
}
}
}
For an output of tokens:
neutral.light.50.value
neutral.light.100.value
neutral.light.150.value
neutral.light.200.value
neutral.light.250.value
neutral.light.300.value
neutral.light.350.value
neutral.light.400.value
neutral.light.450.value
neutral.light.500.value
HTML formatter to visualize the tokens in a website
Web application to modify/export style dictionaries
Web application to modify/export style dictionaries
Making it easy for non-developers to do edits would be a really big one. Right now the technical threshold can make design tokens feel alien to designers, while they are probably equally (if not more) relevant to design.
Current priorities appear to include:
- Typed tokens (this should help with context and formats)
- Token Browser / Editor (something to view, modify tokens - and maybe document output too?)
- Mono-repo w/ maintained library of formats (and encouraging the community to build more)
- Support for ESM import/export - and maybe rewriting everything into typescript
- Custom output file organization, including support for proper import handling of outputReferences
- Better logging, warning, and error control
Build-in solutions & documentation for Dark mode, High-contrast mode
For CSS, it would be nice to automatically split up HSL values as well into separate custom properties.
For JS, this seems possible using attribute/color
.
Also follow the W3C spec while doing it.
https://design-tokens.github.io/community-group/format/#design-token-properties
{
"color": {
"white": {
"value": "#ffffff"
}
}
}
:root {
--color-white: hsl(0 0% 100%);
--color-white-h: 0;
--color-white-s: 0%;
--color-white-l: 100%;
}