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

Is it possible to group tokens into reusable text styles? #1440

Open
alfred1000351 opened this issue Jan 30, 2025 · 1 comment
Open

Is it possible to group tokens into reusable text styles? #1440

alfred1000351 opened this issue Jan 30, 2025 · 1 comment
Labels

Comments

@alfred1000351
Copy link

Hi

I've been trying to figure this out for a while now with no luck. Below, I have my JSON for my typography token, and when I run my config, the tokens are created as separate lines. However, since it's typography, I'm trying to make it easier to use in the code. Ideally, it should generate a reusable text style that includes all the necessary properties.

I've tried several different ways to create a custom formatter, but nothing has worked. I'm using Style Dictionary v4.

End Goal

 .typography-desktop-body-strong-xl-strong {
    font-family: var(--typography-desktop-body-strong-xl-strong-font-family), sans-serif;
    font-weight: var(--typography-desktop-body-strong-xl-strong-font-weight);
    line-height: var(--typography-desktop-body-strong-xl-strong-line-height);
    font-size: var(--typography-desktop-body-strong-xl-strong-font-size);
    letter-spacing: var(--typography-desktop-body-strong-xl-strong-letter-spacing);
    text-transform: var(--typography-desktop-body-strong-xl-strong-text-case);
    text-decoration: var(--typography-desktop-body-strong-xl-strong-text-decoration);
  }`

variables.css file

  --typography-desktop-body-strong-xl-strong-font-family: Stolzl;
  --typography-desktop-body-strong-xl-strong-font-weight: Bold;
  --typography-desktop-body-strong-xl-strong-line-height: 20px;
  --typography-desktop-body-strong-xl-strong-font-size: 20px;
  --typography-desktop-body-strong-xl-strong-letter-spacing: 0%;
  --typography-desktop-body-strong-xl-strong-paragraph-spacing: 20px;
  --typography-desktop-body-strong-xl-strong-paragraph-indent: 0px;
  --typography-desktop-body-strong-xl-strong-text-case: none;
  --typography-desktop-body-strong-xl-strong-text-decoration: none;

My token.json file

{
    "Typography": {
      "Desktop": {
        "body": {
          "regular": {
            "xl": {
              "fontFamily": {
                "value": "{fontFamilies.stolzl}",
                "type": "fontFamilies"
              },
              "fontWeight": {
                "value": "{fontWeights.stolzl-0}",
                "type": "fontWeights"
              },
              "lineHeight": {
                "value": "{lineHeights.0}",
                "type": "lineHeights"
              },
              "fontSize": {
                "value": "{fontSize.2}",
                "type": "fontSizes"
              },
              "letterSpacing": {
                "value": "{letterSpacing.0}",
                "type": "letterSpacing"
              },
              "paragraphSpacing": {
                "value": "{paragraphSpacing.1}",
                "type": "paragraphSpacing"
              },
              "paragraphIndent": {
                "value": "{paragraphIndent.0}",
                "type": "paragraphIndent"
              },
              "textCase": {
                "value": "{textCase.none}",
                "type": "textCase"
              },
              "textDecoration": {
                "value": "{textDecoration.none}",
                "type": "textDecoration"
              }
            }
          }
        }
      }
    }
  }
@jorenbroekema
Copy link
Collaborator

jorenbroekema commented Feb 3, 2025

It's definitely possible through a custom format https://styledictionary.com/reference/hooks/formats/

Fair warning, I've tried to do this before, and it's pretty difficult to get it working in a reliable manner.
My advice would be to use an attribute transform to add attributes to each token that you want to include inside of a CSS class, so a fontFamily token for example would end up looking like this:

{
  value: 'Stolzl',
  type: 'fontFamily',
  attributes: {
    cssProp: 'font-family', // have your token.path[token.path.length - 1] (last item) map "fontFamily" to CSS property "font-family"
    cssClass: 'typography-desktop-body-regular-xl', // your token.path.slice(0, token.path.length - 1) (excludes last item) kebabcased
  },
  // this below is from the `name/kebab` transform
  name: 'typography-desktop-body-regular-xl-font-family'
}

And then in your format, you can format as you would normally for CSS but you'll add another custom format that specifically handles the tokens which should be grouped as CSS classes, so basically your tokens with cssProp/cssClass attributes:

  • Group these tokens together by their cssClass e.g. using a JavaScript keyed Map()
  • For each group, render the CSS text style class:
// wrap below also in a loop if you have more than 1 class
`.${cssClass} {
  ${props.map(prop => `${prop.cssProp}: var(--${name})${prop.fallback ? `, ${prop.fallback}` : ''};`).join('\n  ')}
}`

which then renders to CSS string (assuming we put a sans-serif fallback for fontFamily props):

.typography-desktop-body-regular-xl {
  font-family: var(--typography-desktop-body-regular-xl-font-family), sans-serif;
}

So yeah, definitely possible but requires quite a bit of custom formatting to get working.

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

No branches or pull requests

2 participants