amzn / style-dictionary

A build system for creating cross-platform styles.
https://styledictionary.com
Apache License 2.0
3.87k stars 543 forks source link

Exclude values from transformation #906

Closed istenrom closed 1 year ago

istenrom commented 1 year ago

Hi, we are using the size to rem transformation but how we can exclude some values from the transformation?

We have some tokens value in "%" that we want to keep as "%". Is it possible? Thanks in advanced.

An extract of the tokens.json


      "7xl": {
        "value": "48",
        "type": "borderRadius"
      },
      "circle": {
        "value": "50%",
        "type": "borderRadius"
      }
    },

And the config...

module.exports = { source: ["style-dictionary/tokens/**.json"], fileHeader: { autoGeneratedFileHeader: () => { return [Do not edit directly, this file was auto-generated]; }, }, platforms: { css: { transforms: [ "attribute/cti", "name/cti/kebab", "time/seconds", "content/icon", "attribute/color", "size/pxToRem", "shadow/spreadShadow", "color/rgb", ], prefix: "bv", buildPath: "build/", files: [ { destination: "variables.css", format: "css/variables", }, ], }, }, };

nahiyankhan commented 1 year ago

Are you using a custom px-to-rem transformation or the built in one? I would register a custom transform and use the matcher to ignore values that end with "%". Example (adjust as needed) -

StyleDictionary.registerTransform({
  name: 'custom/pxToRem',
  type: 'value',
  matcher: function(token) {
    return token.attributes.category === 'size' && !prop.value.endsWith('%')
  },
  transformer: function(token) {
    transformer: (token, options) => {
      const baseFont = getBasePxFontSize(options);
      const floatVal = parseFloat(token.value);

      if (isNaN(floatVal)) {
        throwSizeError(token.name, token.value, 'rem');
      }

      if (floatVal === 0) {
        return '0';
      }

      return `${floatVal / baseFont}rem`;
    }
  }
});
Sidnioulz commented 1 year ago

Hi,

You can reuse existing transformers when writing custom transforms. Here is how we transform all sizes to rem, except breakpoints:

const StyleDictionary = require('style-dictionary')

function isSize(token) {
  return token.attributes.category === 'size'
}

function isBreakpointSize(token) {
  return isSize(token) && token.attributes.type === 'breakpoint'
}

function isNotBreakpointSize(token) {
  return isSize(token) && token.attributes.type !== 'breakpoint'
}

StyleDictionary.registerTransform({
  type: 'value',
  name: 'size/not-breakpoint/pxToRem',
  matcher: isNotBreakpointSize,
  transformer: StyleDictionary.transform['size/pxToRem'].transformer,
})

StyleDictionary.registerTransform({
  type: 'value',
  name: 'size/breakpoint/px',
  matcher: isBreakpointSize,
  transformer: StyleDictionary.transform['size/px'].transformer,
})

And in our transforms, we have:

const transforms = [
  'attribute/cti',

  // ...

  'size/breakpoint/px',
  'size/not-breakpoint/pxToRem',

  // ...
]
dbanksdesign commented 1 year ago

Just hoppin in here. @nahiyankhan and @Sidnioulz provided great answers. @istenrom hopefully this answers your question!