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

Need a clear description on how to make it work with Style Dictionary #703

Closed
AndriiMatkivskyiSecurrency opened this issue May 13, 2022 · 13 comments · Fixed by tokens-studio/plugin-docs#82

Comments

@AndriiMatkivskyiSecurrency

Describe the bug
I really like this plugin and the ability to export all the tokens. Our design team also wants to use it for our new Design System.
And as I developer I really want to have a way to convert Figma Tokens's json into a code so it can be used directly in the Flutter app code. So I found that [Style Dictionary can do the trick and generate whatever platform code we need.

Also, I found that token-transformer was implemented to migrate from FT json format to Style Dictionary json format. And I used it but unfortunately, Style Dictionary generates invalid Flutter code.

To Reproduce
Steps to reproduce the behavior:

  • Create new file in Figma
  • Navigation to Figma Tokens plugin
  • Click on Load and Apply default preset
  • Export imported tokens into tokens.json
  • Convert that tokens with token-transformer into output.json (using token-transformer exported_tokens.json output.json global,light,dark,theme)
  • Add default Flutter configuration
"flutter": {
      "transformGroup": "flutter",
      "buildPath": "lib/uniqe/",
      "files": [
        {
          "destination": "style_dictionary.dart",
          "format": "flutter/class.dart",
          "className": "StyleDictionary"
        }
      ]
    },
  • Generate platform files with style-dictionary
  • Observer invalid lib/uniqe/style_dictionary.dart

I've uploaded all the related jsons and files here https://gist.github.com/AndriiMatkivskyiSecurrency/be0b2ad78ed5dc15eb6f0d89117eea47

Expected behavior
Mentioned way of working with Figma Tokens and Style Dictionary should work or at least it will be really great to have a clear guide on what should be done to make this work.

Screenshots or Screencasts
image

Figma file (optional)
I just created a new file and switch to plugin

JSON (optional)
I've attached a link to GithubGist

@jam-awake
Copy link

I'm documenting this partly for my own reference. Based on https://github.com/six7/figma-tokens-example, it seems the workflow is:

# Install deps
npm i -D token-transformer style-dictionary

# export the Figma Tokens' plugin data to a file (e.g. `tokens.json`)
# If one is using themes or Token Sets, I think all of them need to be
# checked before the export occurs

# Transform that JSON file into a tokens JSON file
# that Style Dictionary will understand
token-transformer tokens.json tokens/input.json

# Create a `config.json` file for Style Dictionary
# where that `input.json` file is one of the globs
# that will be consumed by Style Dictionary.
# Also specify one or more platforms
# (e.g. `css` is used below, but others exist)
cat > config.json EOF
{
  "source": [
    "tokens/input.json"
  ],
  "platforms": {
    "css": {
      "transformGroup": "css",
      "buildPath": "build/",
      "files": [
        {
          "destination": "css/variables.css",
          "format": "css/variables"
        }
      ]
    }
  }
}
EOF

# Run Style Dictionary to create the CSS files
style-dictionary build --config config.json

# View the output
cat build/css/variables.css

@AndriiMatkivskyiSecurrency
Copy link
Author

Thanks, @jam-awake , I tried with scss :

  • I am not sure that *% values for line-height are valid values for in scss syntax

image

  • the same for opacity:

image

So seems that style-dictionary just copy-paste tokens from input.json into _variables.scss without applying default transforms from config: https://github.com/amzn/style-dictionary/blob/main/lib/common/transformGroups.js#L66=

@AndriiMatkivskyiSecurrency
Copy link
Author

Same with shadows
image

@six7
Copy link
Collaborator

six7 commented May 18, 2022

For the shadow properties you need to transform dimension / sizing values such as blur, spread, y, x to the output format you want (px). For % line heights: you can just divide by 100 and remove the % with a style dictionary transformer.

We'll be adding a style dictionary config soon that should help, I'll link it in this issue once we have it!

In the meantime here are the transformers I'm using for the things you mentioned:

/**
 * Helper: Transforms dimensions to px
 */
function transformDimension(value) {
  if (value.endsWith("px")) {
    return value;
  }
  return value + "px";
}
/**
 * Transform fontSizes to px
 */
StyleDictionary.registerTransform({
  name: "size/px",
  type: "value",
  transitive: true,
  matcher: (token) =>
    ["fontSizes", "dimension", "borderRadius", "spacing"].includes(token.type),
  transformer: (token) => transformDimension(token.value),
});
/**
 * Helper: Transforms letter spacing % to em
 */
function transformLetterSpacing(value) {
  if (value.endsWith("%")) {
    const percentValue = value.slice(0, -1);
    return `${percentValue / 100}em`;
  }
  return value;
}
/**
 * Transform letterSpacing to em
 */
StyleDictionary.registerTransform({
  name: "size/letterspacing",
  type: "value",
  transitive: true,
  matcher: (token) => token.type === "letterSpacing",
  transformer: (token) => transformLetterSpacing(token.value),
});

@jam-awake
Copy link

I have a question about how to use token-transformer correctly. Since it accepts 4 inputs, some of which involve token sets, what is the correct way to call it?

Let's assume I have 3 token sets: global, dark, and light. global defines primitive tokens whereas dark and light are themes that define decision tokens. As such, there are some tokens in them that share the same name, so that a token name (e.g. foo) can refer to a different value (e.g. black, white) depending on the theme.

Per token-transformer --help, there's a few ways this could be called (ignoring the other CLI args for now):

# 1. only input/output files specified
token-transformer tokens.json output.json

# 2. specify all sets only
token-transformer tokens.json output.json global,dark,light

# 3. specify all sets with global excluded
token-transformer tokens.json output.json global,dark,light global

# 4. specify global+{theme} set, outputting to {theme}.json
token-transformer tokens.json dark.json global,dark
token-transformer tokens.json light.json global,light

# 5. specify global+{theme} set with global excluded, outputting to {theme}.json
token-transformer tokens.json dark.json global,dark global
token-transformer tokens.json light.json global,light global

Which of these 5 (assuming there aren't any others) is correct?

@six7
Copy link
Collaborator

six7 commented May 19, 2022

4, 5 would be correct for what you want to do. The others include both dark and light as sources (the equivalent of ticking all checkboxes in Figma Tokens)

The others would work, but would not produce the result you're after (as light would override dark and thus only out put that)

@AndriiMatkivskyiSecurrency
Copy link
Author

@six7 Thanks for your help. So in my case, I decided to go with another approach.
I've written a custom attribute transform() for StyleDictionary that depending on the type of token assigns a proper category to it. So this gives an ability to use default platform transforms (for my case it's Flutter and SCSS).
Not sure that this is a perfect solution but at least it works for now 😀

Also, @six7 do you have any specs for token values produced by the Figma plugin. For example for Font size is it pixels?
And the same for Font weight: what values it can have (only Bold, 'Regular' or maybe 700, 900etc.) ?

@csaunier
Copy link

csaunier commented Dec 7, 2022

Hello @AndriiMatkivskyiSecurrency 👋

I'm interesting in your custom transformer. Is it possible for you to share it ? 🙏


I'm too struggling a bit with FigmaTokens "types" that not match the "CTI" structure used by StyleDictionary.

For example, the equivalent of this FigmaTokens export :

{
  "core": {
    "m": {
      "value": "16",
      "type": "fontSizes"
    },
    "red": {
      "value": "#f00",
      "type": "color"
    }
  }
}

would be in StyleDictionnay :

{
  "size" : {
    "core": {
      "font": {
        "m": {
          "value": "16"
        }
      }
    }
  },
 "color": {
   "core": {
     "red": {
       "value": "#f00"
     }
   }
 }
}

@six7 , do you have any news about your "style dictionary config" ? 🙏

@amatkivskiy
Copy link

@csaunier
So I've implemented my custom CTI transformer for Figma Tokens maybe half of a year ago.
So the idea is to manually fix hierarchy of the Figma Tokens tree to make it compatible with StyleDictionary tree.

It also changes the category of some of the tokens, again to align with StyleDictionary categories.

StyleDictionary.registerTransform({
      name: "attribute/figma_cti",
      type: "attribute",
      matcher: (token) => true,
      transformer: function (token) {
        const attrNames = ["type", "item", "subitem", "state"];
        const originalAttrs = token.attributes || {};
        const generatedAttrs = {};

        if (["borderRadius", "borderWidth", "spacing", "fontSizes", "dimension"].includes(token.original.type)) {
          generatedAttrs["category"] = "size";
        } else if ("typography" == token.original.type) {
          generatedAttrs["category"] = "font";
        } else if ("opacity" == token.original.type) {
          generatedAttrs["category"] = "opacity";
        } else if ("transparent" == token.original.type) {
          generatedAttrs["category"] = "transparent";
        } else {
          generatedAttrs["category"] = token.original.type;
        }

        for (let i = 0; i < token.path.length && i < attrNames.length; i++) {
          generatedAttrs[attrNames[i]] = token.path[i];
        }

        return Object.assign(generatedAttrs, originalAttrs);
      },
    });

@amatkivskiy
Copy link

@six7 Any updates on this?

@six7
Copy link
Collaborator

six7 commented Mar 10, 2023

@six7 Any updates on this?

We're about to release this 👍

@RobbyUitbeijerse
Copy link

RobbyUitbeijerse commented Apr 18, 2023

Hey @six7 , any update on this? We can definitely use it to clean up our codebase a bit, to get rid of some fixes like @amatkivskiy his solution

@six7
Copy link
Collaborator

six7 commented Apr 19, 2023

Closing this as sd-transforms now supports most features token-transformer has supported. Added a page to our docs.

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

Successfully merging a pull request may close this issue.

6 participants