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

Math resolve not done on expressions with inconsistent spacing #251

Open
a-petrukhnov opened this issue Jan 22, 2024 · 3 comments
Open

Math resolve not done on expressions with inconsistent spacing #251

a-petrukhnov opened this issue Jan 22, 2024 · 3 comments
Labels
bug Something isn't working

Comments

@a-petrukhnov
Copy link

Hello
Here is my tokens example
https://codesandbox.io/p/devbox/figma-tokens-8p8ycw

I have few challanges from designers:

  1. They use code like this {borderRadiusDefault} * {badge.sizeSM} / {controlSizeMD} for border-radiuses, which compiles to something like this 48px /2 * 64px / 48px. So I nee to wrap some tokens values in to calc()
  2. They use some number variables that can not be transformed to pixels by default, for example --sdShadowXSm: 0;. So I have to use transformDimension for that tokens.

Default build script works fine, but can not solve my problems.
When I tried to write custom transformers (build-tokens.mjs:10), like in commented code in my sandbox, variables naming brokes

For example:
--sdShadowXSm: 0; - before transformation
--xs: 2px; - after transformation

Can`t understand what I am doing wrong. And how can I do custom transformations and keep variables names safe.
Appreciate your help!

@jorenbroekema
Copy link
Member

jorenbroekema commented Jan 22, 2024

Confirmed bug, minimal reproduction here.

To work around this issue, place ensure that your math operations either don't contain any spaces, or consistently have 1 space before and after operators (like /, * etc). In your case, 48px /2 * 64px / 48px should become 48px / 2 * 64px / 48px by ensuring that your borderRadiusDefault token is 48px / 2 instead of 48px /2

I'll try to fix this but our resolve math utility is a little bit fragile given that we also need to support multi-value tokens, which also happen to use space as separator, this makes the string interpolation we have to do to support both of these features really complicated. I can't guarantee that I'll find a fix 😓

@jorenbroekema jorenbroekema added the bug Something isn't working label Jan 22, 2024
@a-petrukhnov
Copy link
Author

Oh, I see it. It works with fixed spaces!

But the main question was about "Custom transforms leads to incorrect variables names"
Here is the example https://codesandbox.io/p/sandbox/figma-tokens-transforms-3qktlq

tokens JSON

{
  "shadow": {
    "blur": {
      "xs": {
        "value": "2",
        "type": "number"
      },
      "sm": {
        "value": "{shadow.blur.xs} * 2",
        "type": "number"
      }
    }
  }
}

Builder script

import StyleDictionary from "style-dictionary";
import {
  registerTransforms,
  permutateThemes,
  transforms,
  transformDimension,
} from "@tokens-studio/sd-transforms";

registerTransforms(StyleDictionary);

const config = {
  source: ["./tokens.json"],
  platforms: {
    css: {
      transformGroup: "tokens-studio",
      prefix: "sd",
      buildPath: "./",
      files: [
        {
          destination: "_vars.css",
          format: "css/variables",
        },
      ],
    },
  },
};

const sd = new StyleDictionary(config);
await sd.cleanAllPlatforms();
await sd.buildAllPlatforms();

Compiles to:

:root {
  --sdShadowBlurXs: 2;
  --sdShadowBlurSm: 4;
}

I want to transform these numbers to pixels, so change code of my builder to

import StyleDictionary from "style-dictionary";
import {
  registerTransforms,
  transforms,
  transformDimension,
} from "@tokens-studio/sd-transforms";

StyleDictionary.registerTransform({
  type: "value",
  name: "numbersToPx",
  transitive: true,
  matcher: (token) => token.type === "number",
  transformer: (token) => {
    return transformDimension(token.value);
  },
});

registerTransforms(StyleDictionary);

StyleDictionary.registerTransformGroup({
  name: "custom/tokens-studio",
  transforms: [...transforms, "numbersToPx"],
});

const config = {
  source: ["./tokens.json"],
  platforms: {
    css: {
      transformGroup: "custom/tokens-studio",
      prefix: "sd",
      buildPath: "./",
      files: [
        {
          destination: "_vars.css",
          format: "css/variables",
        },
      ],
    },
  },
};

const sd = new StyleDictionary(config);
await sd.cleanAllPlatforms();
await sd.buildAllPlatforms();

And the output is:

:root {
  --xs: 2px;
  --sm: 4px;
}

So, the name-folding is lost. What I am doing wrong?

@jorenbroekema
Copy link
Member

If you use a custom transform group, you'll also need to add a custom name transform e.g. name/cti/kebab:

StyleDictionary.registerTransformGroup({
  name: "custom/tokens-studio",
  transforms: [...transforms, "name/cti/kebab", "numbersToPx"],
});

@jorenbroekema jorenbroekema changed the title Custom transforms leads to incorrects names in generated CSS variables Math resolve not done on expressions with inconsistent spacing Jan 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants