lukasoppermann / style-dictionary-utils

A package of transforms, formats, filters, etc. to use in your style dictionary config to transform your design tokens
MIT License
176 stars 18 forks source link

transform function for `css/advanced`? #91

Open kerryj89 opened 2 months ago

kerryj89 commented 2 months ago

Hello!

Thank you for making css/advanced util, it looks like it'll be a huge timesaver to be able to save multiple rules to one file.

Anyway, I'm trying css/advanced with the single token wrapper strategy.

src/tokens/color/branding.json

{
  "color": {
    "primary": {
      "value": "#000000",
      "darkValue": "#FFFFFF"
    },
    "secondary": {
      "value": "#000FFF",
      "darkValue": "#FFF000"
    },
    "tertiary": {
      "value": "#00FF00",
      "darkValue": "#FF00FF"
    }
  }
}

build-token.ts

...
const extendedSd = await sd.extend({
  platforms: {
    css: {
      transformGroup: 'css',
      buildPath: 'dist/css',
      files: [{
        destination: 'variables.css',
        format: 'css/advanced',
        options: {
          selector: false,
          // Light mode (aka token.value)
          rules: [{
            atRule: false,
            selector: `:root`
          },
          // Dark mode (aka token.darkValue)
          {
            atRule: '@media (prefers-color-scheme: dark)',
            selector: `:root:not(.theme-light)`,
            matcher: (token: StyleDictionary.TransformedToken) => {
              // style-dictionary-utils provides no transform function at this level so we reassign
              token.value = token.darkValue;
              return token.hasOwnProperty('darkValue');
            },
          },
          {
            atRule: false,
            selector: `:root.theme-dark`,
            matcher: (token: StyleDictionary.TransformedToken) => {
              // style-dictionary-utils provides no transform function at this level so we reassign
              token.value = token.darkValue;
              return token.hasOwnProperty('darkValue');
            }
          }],
          outputReferences: true
        }
      }]
    },
  }
});
...

Initially I had transform: (token: StyleDictionary.TransformedToken) => token.darkValue under the matcher line but it seems that maybe isn't a thing with this extension.

I hackishly worked around it by setting token.value to token.darkValue but this seems destructive and seems to throw the other formats that come after it off for light mode (might've misread the output though).

Any tips or pointers on a better way?

Thanks!

lukasoppermann commented 2 months ago

Hey, this is an issue I still have to solve for a project as well.

I was thinking that maybe this can be solved by using preprocessors?

But I haven't tried it yet.

kerryj89 commented 2 months ago

I'd trust your call on this and not mine (only learned of style-dictionary a few days ago) - I didn't even know about preprocessors but the name makes it seem like it would change things before running other things. With that hunch, would it still allow me to flip to darkValue in the middle of ....files.options.rules? I found your lib really convenient for css where I didn't care for separate files per mode (light/dark).

lukasoppermann commented 2 months ago

Hey @kerryj89 , no it wouldn't allow you to do this.

You probably want to create a custom format for that. It seems like you want to do a prefers-color-scheme media query in the file?

You need a format in which you create a duplicate of your allTokens array and replace the value with darkValue and afterwards run it through formattedVariables.

I think this is the easiest way.