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

RFC: What would you like to see in Style Dictionary 4.0?πŸ‘©πŸ½β€πŸ’»πŸ’‘ #643

Open
chazzmoney opened this issue May 27, 2021 · 97 comments

Comments

@chazzmoney
Copy link
Collaborator

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.
@bherbst
Copy link
Contributor

bherbst commented May 27, 2021

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 a className option to the format that generates the LightColors, but that feel hacky- I'd love if references could keep some of that context for me.

@dbanksdesign dbanksdesign pinned this issue May 27, 2021
@lewishealey
Copy link

I'd love to be able to create different formats and transforms based off different sources (if we can't do already)

@dbanksdesign
Copy link
Member

@lewishealey could you elaborate a bit on this?

@chazzmoney
Copy link
Collaborator Author

@didoo @nhoizey @EvanLovely @kharrop @Tenga @jbarreiros @tonyjwalt @7studio @lukasoppermann

Would love your thoughts!

@lukasoppermann
Copy link
Contributor

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)

@didoo
Copy link
Contributor

didoo commented Jun 8, 2021

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” πŸ˜€

@jacoblapworth
Copy link
Contributor

jacoblapworth commented Jun 8, 2021

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

@isaachorton
Copy link

I would like the ability to create multi-file formats. For instance, being able to generate an iOS Asset Catalog containing named colors (*.colorset)

Asset Catalog Ref

@nhoizey
Copy link
Contributor

nhoizey commented Jun 9, 2021

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 storybookjs/storybook#7671 (comment) . 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

@bhdicaire
Copy link

bhdicaire commented Jun 10, 2021

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:

There is also mac centric projects (e.g., objective-c and swift):

@uptonking
Copy link

uptonking commented Jul 6, 2021

I want more built-in support for integrations/plugins/extensions to popular design tools like figma, sketch, framer-motion...

@nhoizey
Copy link
Contributor

nhoizey commented Jul 6, 2021

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…

@andre-brdoch
Copy link

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.

@lukasoppermann
Copy link
Contributor

While I have different use cases, I also would love something like @andre-brdoch see: #695

@JackHowa
Copy link

JackHowa commented Oct 6, 2021

feature request possibly:

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
  )
);

@JackHowa
Copy link

JackHowa commented Oct 8, 2021

Dynamic outputs would be awesome as well #667 (comment)

this library is still in development, right? @chazzmoney

@dbanksdesign
Copy link
Member

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.

@MelSumner
Copy link

MelSumner commented Oct 13, 2021

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!

@alehar9320
Copy link

alehar9320 commented Oct 15, 2021

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 πŸ‘¨β€πŸ’»

@jorgecasar
Copy link

jorgecasar commented Nov 1, 2021

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.

@jorgecasar
Copy link

Migrate to ESM

Deprecate CommonJS in in favor of ESM.

@irwinsol
Copy link

irwinsol commented Nov 5, 2021

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 "@": #119 (comment)

@gearsandcode
Copy link

I'd love to see things restructured into external files / folders and I second @didoo 's Typescript sentiments.

@jholt1
Copy link

jholt1 commented Dec 21, 2021

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

@aitorllj93
Copy link

HTML formatter to visualize the tokens in a website

@aitorllj93
Copy link

aitorllj93 commented Dec 24, 2021

Web application to modify/export style dictionaries

@andre-brdoch
Copy link

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.

@Baribj
Copy link

Baribj commented Apr 16, 2023

Its been quite a while since this thread started, any plans to update the community with a roadmap for version 4 ?

@frshwtr
Copy link

frshwtr commented Apr 26, 2023

Having a way to make custom transforms configurable with options would help with making them more re-usable.

For example, I want to append a token with meta information relating to the specific build running. Currently I can achieve this with different custom transforms, but this results in repeated code where passing an option to configure the changing data would be more efficient.

Another approach we use is to add extra layers into our source JSON hierarchy, but this adds some extra superflous information to the input JSON and may also pollute it with information that's irrelevant to the source.

@thomasmattheussen
Copy link

async actions and async transforms

@mryechkin
Copy link

I'd like to be able to retain the order of tokens as they are defined in the source. Currently that doesn't sound like it's possible: #777 (comment)

@azan-n
Copy link

azan-n commented Sep 15, 2023

Variable references in CSS and OKLCH support. The OKLCH support is just a tinycolor2 limitation and I'm guessing they'll come around any time now.

The applications that I am working on expect colors in CSS, JS, and Android (sometimes).

Primarily a CSS output like the following would be required wherein I could possibly change the hue at runtime for customizing the theme on the application at runtime.

html {
  --hue: 320;
  
  --swatch-1: oklch(99% .05 var(--hue));
  --swatch-2: oklch(90% .1 var(--hue));
  --swatch-3: oklch(80% .2 var(--hue));
  --swatch-4: oklch(72% .25 var(--hue));
  --swatch-5: oklch(67% .31 var(--hue));
  --swatch-6: oklch(50% .27 var(--hue));
  --swatch-7: oklch(35% .25 var(--hue));
  --swatch-8: oklch(25% .2 var(--hue));
  --swatch-9: oklch(13% .2 var(--hue));
  --swatch-10: oklch(5% .1 var(--hue));
  
  --text-1: var(--swatch-1);
  --text-2: var(--swatch-2);
  --surface-1: var(--swatch-10);
  --surface-2: var(--swatch-9);
  --surface-3: var(--swatch-8);
}

Credits: https://github.com/argyleink/gui-challenges/blob/main/color-palettes/oklch-palette.css

This poses many challenges, like

  1. Interplay with Figma – If in the future we work with dedicated designers working day and night in Figma, this would mean that Figma would need to receive tokens from SD and not the other way around.
  2. For most JS and Android use cases, these OKLCH colors would need to be converted to HEX, which would possibly also be the case if we ship from SD to Figma
  3. SD would need to have some sort of GUI so that designers could use SD as the source of truth and not Figma. I think this is only natural because these configurations need to live closer to the code.

I hope I'm making sense. Thanks for all the great work SD team.

@aitorllj93
Copy link

Hello, checking this issue after long time. Would like to know, is Style Dictionary 4.0 happening? This was opened 2 years ago and the lack of information makes me think we should not wait for anything new from it. Still I think there's lot of feedback and many interesting proposals that should be taken in consideration. By the way, if the library is now in "maintenance mode", does anyone know about other alternatives with faster improvements?

cc @chazzmoney

@dsvgl
Copy link

dsvgl commented Sep 18, 2023

@aitorllj93 have a look at https://cobalt-ui.pages.dev

@jorenbroekema
Copy link
Collaborator

jorenbroekema commented Sep 29, 2023

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.

@jorgecasar
Technically it is already possible to generate a files array programmatically to accomplish what you want, but I agree it would be cool to provide some kind of utility that makes this simpler.

A JSON way of doing it might be:

{
  "files": [{
    "format": "css/component",
    "filter": "componentFilter", // assume this is registered, it's optional
    "split": {
      "by": "{attributes.item}", // any prop ref on token in dictionary
      "destination": "components/*/tokens.css" // * replaced by resolved "by" value e.g. attributes.item = "button"
    }
  }]
}

Or if you need more flexibility, I suppose you can always go a bit deeper with JS instead

const cfg = {
  files: [{
    format: 'css/component',
    filter: token => token.path[0] === 'component',
    split: {
      by: (token) => token.attributes.item, // some prop on the token's attributes
      destination: (byValue) => `components/${byValue}/tokens.css`
    }
  }]
}

@jorenbroekema
Copy link
Collaborator

Hey everyone, we just published a statement about v4 of Style-Dictionary, I know many of you are asking in here what is the status for v4, and I'm happy to say, it's being actively worked on :) see https://github.com/amzn/style-dictionary#version-4 or https://amzn.github.io/style-dictionary/#/version_4

@didoo
Copy link
Contributor

didoo commented Oct 9, 2023

Hey everyone, we just published a statement about v4 of Style-Dictionary, I know many of you are asking in here what is the status for v4, and I'm happy to say, it's being actively worked on :) see https://github.com/amzn/style-dictionary#version-4 or https://amzn.github.io/style-dictionary/#/version_4

Hi @jorenbroekema the board linked in the document shared above is not visible/accessible (the link returns a 404). Is it expected because it's not public? πŸ€”

@Tahul
Copy link

Tahul commented Oct 11, 2023

I don't have access to the roadmap either, but that is a very great news! πŸ˜„

I have fully ported Style Dictionary to ESM / browser and updated this whole repository to a more modern stack here:
https://github.com/Tahul/style-dictionary-esm

I would be interested in joining efforts to align this with V4.

@jorenbroekema
Copy link
Collaborator

jorenbroekema commented Oct 12, 2023

I don't have access to the roadmap either, but that is a very great news! πŸ˜„

I have fully ported Style Dictionary to ESM / browser and updated this whole repository to a more modern stack here: https://github.com/Tahul/style-dictionary-esm

I would be interested in joining efforts to align this with V4.

That's really cool, I didn't realize someone else was also trying to make it ESM / browser compatible.

Here's my PR to do the same thing #1014

I think the main difference is that my PR makes sure there is no reliance on things that aren't standards in the browser, e.g. JSON imports, extensionless import specifiers, etc., things that Vite allows out of the box. I prefer to make sure everything really works out of the box in browser & Node, without a single bit of build-tooling or plugins required.
The other difference is that I'll likely go for a headless browser testing framework, to ensure that tests run in actual browsers rather than JSDOM/similar, still have to start on that and will require a bit of rewriting of tests probably.

I think using fast-glob is a good idea, I just checked and you can pass a custom FS implementation to it just as you can for glob, so it seems like a good candidate then if it's faster :). Using something like consola to improve logging is also great, I was thinking that it would be a good idea to rethink logging in style-dictionary a bit anyways to help users solve their issues faster, perhaps we can chat at some point and have you collaborate with us on that part? Dropping lodash and maybe the internal es6 util file as well would be great too as a separate contribution, if you're interested. You can most easily reach out to me in the Tokens Studio slack https://join.slack.com/t/tokens-studio/shared_invite/zt-1p8ea3m6t-C163oJcN9g3~YZTKRgo2hg -> style-dictionary-v4 channel

@jorenbroekema
Copy link
Collaborator

Hey everyone, we just published a statement about v4 of Style-Dictionary, I know many of you are asking in here what is the status for v4, and I'm happy to say, it's being actively worked on :) see https://github.com/amzn/style-dictionary#version-4 or https://amzn.github.io/style-dictionary/#/version_4

Hi @jorenbroekema the board linked in the document shared above is not visible/accessible (the link returns a 404). Is it expected because it's not public? πŸ€”

Thanks for letting us know, we've made a request to the amzn github organisation owners to make the board public.

@hansmbakker
Copy link

hansmbakker commented Oct 13, 2023

Hi, great news regarding the v4 release being worked on!

My requests would be:

@jorenbroekema
Copy link
Collaborator

Board is public now πŸŽ‰ . Just a disclaimer that the board is not set in stone, more stuff will surely get added, and even if something is not included, it might just mean that it's a good idea but not a priority to get it into the v4.0.0 release e.g. because it's a non-breaking enhancement to the library :)

@starblazingunicorn
Copy link

Will v4.0.0 have the support for format such as Kotlin?

@jorenbroekema
Copy link
Collaborator

Will v4.0.0 have the support for format such as Kotlin?

We're certainly open to contributions for adding predefined formats in the style-dictionary library for popular platforms e.g. Kotlin! Feel free to open a new issue, probably start with an example of Design Token JSON format and how that would look like in Kotlin format, so we can work our way backwards and see how the formatter for that should look like, and whether any transforms are needed.

Preferably contribute to the v4 branch rather than the main branch (v3)

@tl-NASEEBULLAH-AHMADI
Copy link

Do we have a rough estimate when V4 will be ready?

@jorenbroekema
Copy link
Collaborator

Do we have a rough estimate when V4 will be ready?

My estimate is Q2 2024, not sure if early or late into the quarter.

@t-keshi
Copy link

t-keshi commented Feb 19, 2024

feature request 1: Add options.outputNumberLiterals to TypeScript/ES6 declarations

Style Dictionary currently supports outputStringLiteral, but does not yet support outputNumberLiteral.

Related issue: Link
Related PR: Link

feature request 2: Make object literal types recursively compatible with TypeScript/ES6 declarations

export const LineHeightsNormal: "150%"; // This can be a string literal
export const TypographyTextSBold: { fontFamily: string, lineHeight: string }; // // This cannot be a string literal

@jorenbroekema
Copy link
Collaborator

jorenbroekema commented Feb 19, 2024

@t-keshi both of those features sound reasonable, would you be open to creating a pull request to the v4 branch for them?

For number literal, do I understand correctly that you'd like:

export const MyNumber : number;

to be for example typed more strictly e.g. if the value is 5?:

export const MyNumber : 5;

@tpict
Copy link

tpict commented Feb 27, 2024

  • a non-flat version of javascript/es6, or alternatively the ability to export the variable created by javascript.object
  • as above for TS declarations
  • some kind of integration with csstype

@gangsthub
Copy link

First class TypeScript support

@tibuurcio
Copy link

#768 would be great :)

@jorenbroekema
Copy link
Collaborator

First class TypeScript support

It was added in v4 branch, so feel free to start using the prereleases if you want to make use of this πŸŽ‰

#768 would be great :)

I agree, I'll add it to the list, as I think my suggestion for this issue will be a breaking change. I'll reply in the issue as well to elaborate.

@pws-pm
Copy link

pws-pm commented Apr 16, 2024

+1 on the following

@hansmbakker
Copy link

@pws-pm have a look at #1162 - I started working on this there, but will need some guidance on this from @jorenbroekema

@pws-pm
Copy link

pws-pm commented Apr 18, 2024

@pws-pm have a look at #1162 - I started working on this there, but will need some guidance on this from @jorenbroekema

i gave a shot in making a plugin for cobalt ui with gpt4, you can check it out here:
drwpow/cobalt-ui#251

I don't know if it may help you

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