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

Strings get converted to unquoted strings in scss & css #462

Closed
lukasoppermann opened this issue Sep 23, 2020 · 5 comments
Closed

Strings get converted to unquoted strings in scss & css #462

lukasoppermann opened this issue Sep 23, 2020 · 5 comments

Comments

@lukasoppermann
Copy link
Contributor

Hey,

I noticed that all strings end up being unquoted, for example:

textCase: {
  value: "uppercase"
}

Will show up in the css file as:

  --body-text-case: uppercase;
@dbanksdesign
Copy link
Member

Some tokens would get wrapped in quotes, depending on the type of token and the transforms applied to that token. In some cases unquoted would be expected, like if you define a color as a hex string. In CSS or SCSS variables you would not want that to be quoted. And your example of "uppercase" you would actually want that unquoted in CSS and SCSS as well or else it wouldn't work.

There are some built-in transforms that quote certain types of tokens, such as the content/quote transform which wraps values in quotes if the token has a category of "content." The built-in transforms work by matching certain kinds of tokens based on the category/type/item of the token and transforming them appropriately. Not everyone uses the CTI method of defining what a type a token is, and you can define custom transforms that suite your needs.

Hopefully this helps! Let me know if you have any questions.

@lukasoppermann
Copy link
Contributor Author

Hey @dbanksdesign sorry, that was a bad example indeed. But font-family would be one that should be wrapped.

I understand the idea behind the CTI method but feel this is very limiting. Especially since it does not allow for token groups, e.g. font/h3 which includes for example the family, style and size.

Did you ever think about a type property or something like this? If so can you give me a hint why you did not include it?

@dbanksdesign
Copy link
Member

For font-family it looks like we are missing a built-in CSS/SCSS transform to handle that case. It looks like we have a built-in transform to wrap a font token in a string literal on Objective-C, but we didn't add one for CSS/SCSS. That could be something we add in to be consistent across platforms. If there is every something that doesn't exist in transforms and formats, that might be something we just overlooked 😅. But that doesn't mean it's impossible! That is why we put most of the functionality in transforms and formats and you can define your own in case we don't provide a built-in one or you want to do something differently.

We didn't include a type property because we actually want to be more flexible. We don't expect every token package to be structured or typed the same way. The CTI method is by no means the only way to do things. You can absolutely have a token with a type attribute like so:

{
  "color-background-primary": {
    "value": "#fff",
    "type": "color"
  }
}

And then use that type attribute in transforms:

const StyleDictionary = require('style-dictionary');
const chroma = require('chroma-js');

StyleDictionary.registerTransform({
  name: 'customColorTransform'
  type: 'value'
  matcher: (token) => token.type === 'color', // here is where you can use 'type' or any data on the token
  transformer: (token) => chroma(token.value).hsl()
});

The CTI structure categorizes tokens implicitly by object structure. So anything under the top-level namespace of "color" has the category of color, 2nd-level namespace of "background" has the type of background, etc. This CTI categorization happens in a built-in transform, the attribute/cti transform.

Our aim was to not prescribe any one singular way to structure and type tokens because everyone has different needs and opinions on how to do that. There are lots of people that don't use CTI and define their own way to type tokens.

Does that make sense?

@tonyjwalt
Copy link
Contributor

CSS seemed to be an odd one for us because some strings cannot be wrapped in quotes, while it's required for others. On my team we thought this behavior was a format thing, so we built a solution into our custom formatter. You can see that in PR 428 in the formatter file on line 32.

We applied a solution similar to what @dbanksdesign recommended, but used data-type on the attributes object instead of just type. We felt it was descriptive of an attribute of the token and this also allowed us to mix and match a token's type with the type of data used to define it.

As @dbanksdesign said, there are several ways to solve it. I just thought I'd share what we did if it helps.

@lukasoppermann
Copy link
Contributor Author

Hey @tonyjwalt I think this is an interesting solution for me.

@dbanksdesign to clarify where I am coming from.

I am currently working on a figma design token export plugin. I would like to ideally export a json file that can be converted by style-dictionary without any additional magic from my side.

CTI seems a bit limiting, as by default in Figma things like font styles include sizes, fonts and other things. If I understand you correct, I would have to include the "font-family" under the specific category content while the fontSize would be under the category size. Is this correct?

Currently I have a json (before trying to transform it for style-dictionary) that looks like this:

"body": {
    "h3": {
      "description": null,
      "values": {
        "fontSize": {
          "value": 20,
          "unit": "pixels"
        },
        "textDecoration": {
          "value": "none"
        },
        "fontFamily": {
          "value": "Roboto"
        },
        "fontStyle": {
          "value": "Medium"
        },
        "letterSpacing": {
          "value": 2,
          "unit": "percent"
        },
        "lineHeight": {
          "value": 160.0000023841858,
          "unit": "percent"
        },
        "paragraphIndent": {
          "value": 5,
          "unit": "pixels"
        },
        "paragraphSpacing": {
          "value": 8,
          "unit": "pixels"
        },
        "textCase": {
          "value": "uppercase"
        }
      }
    }

I think it would make sense to have this converted into tokens like:

--font-body-h3-fontSize: 20px;
--font-body-h3-textDecoration: none;
--font-body-h3-fontFamily: "Roboto"; 

Does this make sense? Or am I missing something here?

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

3 participants