Style-dictionary: Handling @custom-media vars

Created on 5 Jun 2020  路  3Comments  路  Source: amzn/style-dictionary

Hi,

We use @custom-media for our media query vars. Out of the box this doesn't work. I didn't expect it too, but I wondered if this was something that will be supported or if there was a transform out there that could help.

Trying the standard way:

{
    "@custom": {
       "media": { "value": "--mq-xsmall (min-width: 20em)" },
       "comment": "320px"
    } 
}

Will output:

--custom-media: --mq-xsmall (min-width: 20em);

Problems with this:

  1. It is outputted inside the :root @custom-media needs to be outside of this
  2. -- should be @

I could write a transform for issue 2, but I'm not sure where to start with 1.

Any help or info appreciated.

Most helpful comment

Hi, we had the same issue and solved it with a custom formatter. Here are the relevant sections of our build script:

const StyleDictionary = require("style-dictionary");

const styleDictionaryConfig = {
  source: ["src/tokens/**/*.+(js|json)"],
  platforms: {
    css: {
      transformGroup: "css",
      buildPath: "src/styles/compiled/",
      files: [
        {
          destination: `custom-media.css`,
          format: "custom/format/custom-media",
          filter: { attributes: { category: "viewport" } },
        },
      ],
    },
  },
};

/**
 * Custom Format: Custom Media
 * This converts our viewport tokens to the very specific `@custom-media`
 * variable definition format.
 * 
 * 1. Some of our tokens are named using underscores. Convert to hyphens.
 */
StyleDictionary.registerFormat({
  name: "custom/format/custom-media",
  formatter(dictionary) {
    return dictionary.allProperties
      .map((prop) => {
        const { attributes, value } = prop;
        const size = attributes.type.replace(/_/g, "-"); // 1
        return `@custom-media --${size}-viewport (${value});`;
      })
      .join("\n");
  },
});

const StyleDictionaryExtended = StyleDictionary.extend(styleDictionaryConfig);
StyleDictionaryExtended.buildAllPlatforms();

All 3 comments

Update. For now I just used a script to merge the outputted vars with a static css file containing the custom media after the token build had finished.

@matt-tyas retreading this territory with @custom-media in style dictionary. Could you share your script? Or wherever you landed?

Hi, we had the same issue and solved it with a custom formatter. Here are the relevant sections of our build script:

const StyleDictionary = require("style-dictionary");

const styleDictionaryConfig = {
  source: ["src/tokens/**/*.+(js|json)"],
  platforms: {
    css: {
      transformGroup: "css",
      buildPath: "src/styles/compiled/",
      files: [
        {
          destination: `custom-media.css`,
          format: "custom/format/custom-media",
          filter: { attributes: { category: "viewport" } },
        },
      ],
    },
  },
};

/**
 * Custom Format: Custom Media
 * This converts our viewport tokens to the very specific `@custom-media`
 * variable definition format.
 * 
 * 1. Some of our tokens are named using underscores. Convert to hyphens.
 */
StyleDictionary.registerFormat({
  name: "custom/format/custom-media",
  formatter(dictionary) {
    return dictionary.allProperties
      .map((prop) => {
        const { attributes, value } = prop;
        const size = attributes.type.replace(/_/g, "-"); // 1
        return `@custom-media --${size}-viewport (${value});`;
      })
      .join("\n");
  },
});

const StyleDictionaryExtended = StyleDictionary.extend(styleDictionaryConfig);
StyleDictionaryExtended.buildAllPlatforms();
Was this page helpful?
0 / 5 - 0 ratings

Related issues

clepore picture clepore  路  5Comments

dbanksdesign picture dbanksdesign  路  5Comments

dbanksdesign picture dbanksdesign  路  5Comments

valiksb picture valiksb  路  4Comments

dbanksdesign picture dbanksdesign  路  5Comments