Skip to content

Releases: amzn/style-dictionary

v4.0.0-prerelease.28

14 May 11:46
a140902
Compare
Choose a tag to compare
v4.0.0-prerelease.28 Pre-release
Pre-release

Minor Changes

  • 4225d78: Added the following transforms for CSS, and added them to the scss, css and less transformGroups:

    • fontFamily/css -> wraps font names with spaces in ' quotes
    • cubicBezier/css -> array value, put inside cubic-bezier() CSS function
    • strokeStyle/css/shorthand -> object value, transform to CSS shorthand
    • border/css/shorthand -> object value, transform to CSS shorthand
    • typography/css/shorthand -> object value, transform to CSS shorthand
    • transition/css/shorthand -> object value, transform to CSS shorthand
    • shadow/css/shorthand -> object value (or array of objects), transform to CSS shorthand

    The main intention here is to ensure that Style Dictionary is compliant with DTCG draft specification out of the box with regards to exporting to CSS, where object-value tokens are not supported without transforming them to shorthands (or expanding them, which is a different feature that was added in 4.0.0-prerelease.27).

Patch Changes

  • a5bafac: Colors that are not recognized by tinycolor2 as valid color formats (e.g. linear-gradient(...)) are now ignored by the builtin color transforms filter functions.

v4.0.0-prerelease.27

09 May 16:45
f6e7177
Compare
Choose a tag to compare
v4.0.0-prerelease.27 Pre-release
Pre-release

Major Changes

  • f2ed88b: BREAKING: File headers, when registered, are put inside the hooks.fileHeaders property now, as opposed to fileHeader.
    Note the change from singular to plural form here.

    Before:

    export default {
      fileHeader: {
        foo: (defaultMessages = []) => ['Ola, planet!', ...defaultMessages, 'Hello, World!'],
      },
    };

    After:

    export default {
      hooks: {
        fileHeaders: {
          foo: (defaultMessages = []) => ['Ola, planet!', ...defaultMessages, 'Hello, World!'],
        },
      },
    };
  • f2ed88b: BREAKING: Actions, when registered, are put inside the hooks.actions property now, as opposed to action.
    Note the change from singular to plural form here.

    Before:

    export default {
      action: {
        'copy-assets': {
          do: () => {}
          undo: () => {}
        }
      },
    };

    After:

    export default {
      hooks: {
        actions: {
          'copy-assets': {
            do: () => {}
            undo: () => {}
          }
        },
      },
    };
  • f2ed88b: Filters, when registered, are put inside the hooks.filters property now, as opposed to filter.
    Note the change from singular to plural form here.

    Before:

    export default {
      filter: {
        'colors-only': (token) => token.type === 'color,
      },
      platforms: {
        css: {
          files: [{
            format: 'css/variables',
            destination: '_variables.css',
            filter: 'colors-only',
          }],
        },
      },
    };

    After:

    export default {
      hooks: {
        filters: {
          'colors-only': (token) => token.type === 'color,
        },
      },
      platforms: {
        css: {
          files: [{
            format: 'css/variables',
            destination: '_variables.css',
            filter: 'colors-only',
          }],
        },
      },
    };

    In addition, when using registerFilter method, the name of the filter function is now filter instead of matcher.

    Before:

    import StyleDictionary from 'style-dictionary';
    
    StyleDictionary.registerFilter({
      name: 'colors-only',
      matcher: (token) => token.type === 'color',
    });

    After:

    import StyleDictionary from 'style-dictionary';
    
    StyleDictionary.registerFilter({
      name: 'colors-only',
      filter: (token) => token.type === 'color',
    });

    These changes also apply for the filter function (previously matcher) inside transforms.

  • f2ed88b: BREAKING: Transform groups, when registered, are put inside the hooks.transformGroups property now, as opposed to transformGroup.

    Before:

    export default {
      // register it inline or by SD.registerTransformGroup
      transformGroup: {
        foo: ['foo-transform'],
      },
    };

    After:

    export default {
      hooks: {
        transformGroups: {
          foo: ['foo-transform'],
        },
      },
    };
  • f2ed88b: BREAKING: Formats, when registered, are put inside the hooks.formats property now, as opposed to format.
    The formatter handler function has been renamed to format for consistency.

    The importable type interfaces have also been renamed, Formatter is now FormatFn and FormatterArguments is now FormatFnArguments.
    Note that you can also use Format['format'] instead of FormatFn, or Parameters<Format['format']> instead of FormatFnArguments, so these renames may not matter.

    Before:

    import StyleDictionary from 'style-dictionary';
    import type { Formatter, FormatterArguments } from 'style-dictionary/types';
    
    // register it with register method
    StyleDictionary.registerFormat({
      name: 'custom/json',
      formatter: ({ dictionary }) => JSON.stringify(dictionary, 2, null),
    });
    
    export default {
      // OR define it inline
      format: {
        'custom/json': ({ dictionary }) => JSON.stringify(dictionary, 2, null),
      },
      platforms: {
        json: {
          files: [
            {
              destination: 'output.json',
              format: 'custom/json',
            },
          ],
        },
      },
    };

    After:

    import StyleDictionary from 'style-dictionary';
    import type { FormatFn, FormatFnArguments } from 'style-dictionary/types';
    
    // register it with register method
    StyleDictionary.registerFormat({
      name: 'custom/json',
      format: ({ dictionary }) => JSON.stringify(dictionary, 2, null),
    });
    
    export default {
      // OR define it inline
      hooks: {
        formats: {
          'custom/json': ({ dictionary }) => JSON.stringify(dictionary, 2, null),
        },
      },
      platforms: {
        json: {
          files: [
            {
              destination: 'output.json',
              format: 'custom/json',
            },
          ],
        },
      },
    };
  • e83886c: BREAKING: preprocessors must now also be explicitly applied on global or platform level, rather than only registering it. This is more consistent with how the other hooks work and allows applying it on a platform level rather than only on the global level.

    preprocessors property that contains the registered preprocessors has been moved under a wrapping property called hooks.

    Before:

    export default {
      // register it inline or by SD.registerPreprocessor
      // applies automatically, globally
      preprocessors: {
        foo: (dictionary) => {
          // preprocess it
          return dictionary;
        },
      },
    };

    After:

    export default {
      // register it inline or by SD.registerPreprocessor
      hooks: {
        preprocessors: {
          foo: (dictionary) => {
            // preprocess it
            return dictionary;
          },
        },
      },
      // apply it globally
      preprocessors: ['foo'],
      platforms: {
        css: {
          // or apply is per platform
          preprocessors: ['foo'],
        },
      },
    };
  • 2f80da2: BREAKING: className, packageName, mapName, type, name, resourceType and resourceMap options for a bunch of built-in formats have been moved from file to go inside the file.options object, for API consistency reasons.

    Before:

    {
      "files": [
        {
          "destination": "tokenmap.scss",
          "format": "scss/map-deep",
          "mapName": "tokens"
        }
      ]
    }

    After:

    {
      "files": [
        {
          "destination": "tokenmap.scss",
          "format": "scss/map-deep",
          "options": {
            "mapName": "tokens"
          }
        }
      ]
    }
  • f2ed88b: BREAKING: Transforms, when registered, are put inside the hooks.transforms property now, as opposed to transform.
    The matcher property has been renamed to filter (to align with the Filter hook change), and the transformer handler function has been renamed to transform for consistency.

    Before:

    export default {
      // register it inline or by SD.registerTransform
      transform: {
        'color-transform': {
          type: 'value',
          matcher: (token) => token.type === 'color',
          transformer: (token) => token.value,
        },
      },
      platforms: {
        css: {
          // apply it per platform
          transforms: ['color-transform'],
        },
      },
    };

    After

    export default {
      // register it inline or by SD.registerTransform
      hooks: {
        transforms: {
          'color-transform': {
            type: 'value',
            filter: (token) => token.type === 'color',
            transform: (token) => token.value,
          },
        },
      },
      platforms: {
        css: {
          // apply it per platform
          transforms: ['color-transform'],
        },
      },
    };
  • f2ed88b: BREAKING: Parsers, when registered, are put inside the hooks.parsers property now, as opposed to parsers.
    parsers property has been repurposed: you will now also need to explicitly apply registered parsers by name in the parsers property, they no longer apply by default.
    When registering a parser, you must also supply a name property just like with all other hooks, and the parse function has been renamed to parser for consistency.

    Before:

    export default {
      // register it inline or by SD.registerPreprocessor
      parsers: [
        {
          pattern: /\.json5$/,
          parse: ({ contents, filePath }) => {
            return JSON5.parse(contents);
          },
        },
      ],
    };

    After:

    export default {
      hooks: {
        parsers: {
          name: 'json5-parser',
          pattern: /\.json5$/,
          parser: ({ contents, filePath }) => {
            return JSON5.parse(contents);
          },
        },
      },
      // apply it globally by name reference
      parsers: ['json5-parser'],
    };
  • 7b82150: BREAKING: For formats using the fileHeader formatHelpers utility, it will no longer display a timestamp in the fileHeader output by default. This is now an opt-in by setting file.formatting.fileHeaderTimestamp to true. The reason for making this opt-in now is that using Style Dictionary in the context of a CI (continuous integration) pipeline is a common use-case, and when running on pull request event, output files always show a diff in git due to the timestamp changing, which often just means that the diff is bloated by ...

Read more

v4.0.0-prerelease.26

16 Apr 11:09
76d5ab4
Compare
Choose a tag to compare
v4.0.0-prerelease.26 Pre-release
Pre-release

Minor Changes

  • 3485467: Fix some inconsistencies in some of the templates, usually with regards to spaces/newlines

Patch Changes

  • 6cfce97: Fix logging to be ordered by platform when building or cleaning platforms. This now happens in parallel, resulting in the logs being ordered randomly which was a small regression to the logging experience.
  • 061c67e: Hotfix to address outputReferencesTransformed util not handling object-value tokens properly.

v4.0.0-prerelease.25

12 Apr 12:59
50a69dc
Compare
Choose a tag to compare
v4.0.0-prerelease.25 Pre-release
Pre-release

Major Changes

  • 0b81a08: BREAKING: no longer wraps tokens of type asset in double quotes. Rather, we added a transform asset/url that will wrap such tokens inside url("") statements, this transform is applied to transformGroups scss, css and less.

Minor Changes

  • 2da5130: Added outputReferencesTransformed utility function to pass into outputReferences option, which will not output references for values that have been transitively transformed.

Patch Changes

  • 47face0: Token merging behavior changed so that upon token collisions, metadata props aren't accidentally merged together.

v4.0.0-prerelease.24

05 Apr 09:41
27d0622
Compare
Choose a tag to compare
v4.0.0-prerelease.24 Pre-release
Pre-release

Major Changes

  • 5e167de: BREAKING: moved formatHelpers away from the StyleDictionary class and export them in 'style-dictionary/utils' entrypoint instead.

    Before

    import StyleDictionary from 'style-dictionary';
    
    const { fileHeader, formattedVariables } = StyleDictionary.formatHelpers;

    After

    import { fileHeader, formattedVariables } from 'style-dictionary/utils';
  • 90095a6: BREAKING: Allow specifying a function for outputReferences, conditionally outputting a ref or not per token. Also exposes outputReferencesFilter utility function which will determine whether a token should be outputting refs based on whether those referenced tokens were filtered out or not.

    If you are maintaining a custom format that allows outputReferences option, you'll need to take into account that it can be a function, and pass the correct options to it.

    Before:

    StyleDictionary.registerFormat({
      name: 'custom/es6',
      formatter: async (dictionary) => {
        const { allTokens, options, file } = dictionary;
        const { usesDtcg } = options;
    
        const compileTokenValue = (token) => {
          let value = usesDtcg ? token.$value : token.value;
          const originalValue = usesDtcg ? token.original.$value : token.original.value;
    
          // Look here 👇
          const shouldOutputRefs = outputReferences && usesReferences(originalValue);
    
          if (shouldOutputRefs) {
            // ... your code for putting back the reference in the output
            value = ...
          }
          return value;
        }
        return `${allTokens.reduce((acc, token) => `${acc}export const ${token.name} = ${compileTokenValue(token)};\n`, '')}`;
      },
    });

    After

    StyleDictionary.registerFormat({
      name: 'custom/es6',
      formatter: async (dictionary) => {
        const { allTokens, options, file } = dictionary;
        const { usesDtcg } = options;
    
        const compileTokenValue = (token) => {
          let value = usesDtcg ? token.$value : token.value;
          const originalValue = usesDtcg ? token.original.$value : token.original.value;
    
          // Look here 👇
          const shouldOutputRef =
            usesReferences(original) &&
            (typeof options.outputReferences === 'function'
              ? outputReferences(token, { dictionary, usesDtcg })
              : options.outputReferences);
    
          if (shouldOutputRefs) {
            // ... your code for putting back the reference in the output
            value = ...
          }
          return value;
        }
        return `${allTokens.reduce((acc, token) => `${acc}export const ${token.name} = ${compileTokenValue(token)};\n`, '')}`;
      },
    });

v4.0.0-prerelease.23

27 Mar 10:19
de2c394
Compare
Choose a tag to compare
v4.0.0-prerelease.23 Pre-release
Pre-release

Patch Changes

  • f8c40f7: fix(types): add missing type keyword for type export from index.d.ts

v4.0.0-prerelease.22

26 Mar 23:08
3537e8d
Compare
Choose a tag to compare
v4.0.0-prerelease.22 Pre-release
Pre-release

Patch Changes

  • daa78e1: Added missing type exports

v4.0.0-prerelease.21

26 Mar 16:42
be346a8
Compare
Choose a tag to compare
v4.0.0-prerelease.21 Pre-release
Pre-release

Minor Changes

  • 8b6fff3: Fixes some noisy warnings still being outputted even when verbosity is set to default.

    We also added log.warning "disabled" option for turning off warnings altogether, meaning you only get success logs and fatal errors.
    This option can be used from the CLI as well using the --no-warn flag.

Patch Changes

  • 77ae35f: Fix scenario of passing absolute paths in Node env, do not remove leading slash in absolute paths.

v4.0.0-prerelease.20

25 Mar 16:45
5f2f8c5
Compare
Choose a tag to compare
v4.0.0-prerelease.20 Pre-release
Pre-release

Minor Changes

  • aff6646: Allow passing a custom FileSystem Volume to your Style-Dictionary instances, to ensure input/output files are read/written from/to that specific volume.
    Useful in case you want multiple Style-Dictionary instances that are isolated from one another in terms of inputs/outputs.

    import { Volume } from 'memfs';
    // You will need a bundler for memfs in browser...
    // Or use as a prebundled fork:
    import memfs from '@bundled-es-modules/memfs';
    const { Volume } = memfs;
    
    const vol = new Volume();
    
    const sd = new StyleDictionary(
      {
        tokens: {
          colors: {
            red: {
              value: '#FF0000',
              type: 'color',
            },
          },
        },
        platforms: {
          css: {
            transformGroup: 'css',
            files: [
              {
                destination: 'variables.css',
                format: 'css/variables',
              },
            ],
          },
        },
      },
      { volume: vol },
    );
    
    await sd.buildAllPlatforms();
    
    vol.readFileSync('/variables.css');
    /**
     * :root {
     *   --colors-red: #FF0000;
     * }
     */

    This also works when using extend:

    const extendedSd = await sd.extend(cfg, { volume: vol });

v4.0.0-prerelease.19

19 Mar 13:05
220bc88
Compare
Choose a tag to compare
v4.0.0-prerelease.19 Pre-release
Pre-release

Major Changes

  • 79bb201: BREAKING: Logging has been redesigned a fair bit and is more configurable now.

    Before:

    {
      "log": "error" // 'error' | 'warn'  -> 'warn' is the default value
    }

    After:

    {
      "log": {
        "warnings": "error", // 'error' | 'warn'  -> 'warn' is the default value
        "verbosity": "verbose" // 'default' | 'verbose' | 'silent'  -> 'default' is the default value
      }
    }

    Log is now and object and the old "log" option is now "warnings".

    This configures whether the following five warnings will be thrown as errors instead of being logged as warnings:

    • Token value collisions (in the source)
    • Token name collisions (when exporting)
    • Missing "undo" function for Actions
    • File not created because no tokens found, or all of them filtered out
    • Broken references in file when using outputReferences, but referring to a token that's been filtered out

    Verbosity configures whether the following warnings/errors should display in a verbose manner:

    • Token collisions of both types (value & name)
    • Broken references due to outputReferences & filters
    • Token reference errors

    And it also configures whether success/neutral logs should be logged at all.
    Using "silent" (or --silent in the CLI) means no logs are shown apart from fatal errors.

  • bcb5ef3: Remove reliance on CTI token structure across transforms, actions and formats.

    Breaking changes:

    • Token type will now be determined by "type" (or "$type") property on the token, rather than by checking its CTI attributes. This change has been reflected in all of the format templates as well as transform "matcher" functions that were previously checking attributes.category as the token type indicator.
    • Types are mostly aligned with DTCG spec types, although a few additional ones have been added for compatibility reasons:
      • asset -> string type tokens where the value is a filepath to an asset
      • icon -> content type string tokens where the content resembles an icon, e.g. for icon fonts like Microsoft codicons
      • html -> HTML entity strings for unicode characters
      • content -> regular string content e.g. text content which sometimes needs to be wrapped in quotes
    • Built-in name transforms are now reliant only on the token path, and are renamed from name/cti/casing to just name/casing. name/ti/camel and name/ti/constant have been removed. For example name/cti/kebab transform is now name/kebab.
    • Transform content/icon has been renamed to html/icon since it targets HTML entity strings, not just any icon content.
    • font/objC/literal, font/swift/literal and font/flutter/literal have been removed in favor of font/objC/literal, font/swift/literal and font/flutter/literal, as they do he exact same transformations.
    • typescript/module-declarations format to be updated with current DesignToken type interface.

    Before:

    {
      "color": {
        "red": {
          "value": "#FF0000"
        }
      }
    }

    After:

    {
      "color": {
        // <-- this no longer needs to be "color" in order for the tokens inside this group to be considered of type "color"
        "red": {
          "value": "#FF0000",
          "type": "color"
        }
      }
    }

Patch Changes

  • 8e297d6: Fix outputReferences for DTCG spec tokens, by using token.original.$value instead of token.original.value.