Tokens Studio Style Dictionary Transforms

repository·main·Indexed 42 days ago

https://github.com/tokens-studio/sd-transforms

A collection of custom Style Dictionary transforms and preprocessors designed to handle design tokens exported from the Tokens Studio Figma plugin. Version 2.0.3 provides tools for resolving math expressions, processing color modifiers, and managing multi-dimensional theming via the permutateThemes function.

Tokens
10.2K
Snippets
28
Records
37
Agent score
51%

What's inside Tokens Studio SD Transforms

  1. Implement theming with Tokens Studio PRO

    main

    If you are using the PRO version of Tokens Studio, you can integrate its theme data with Style Dictionary using sd-transforms.

    To implement this, you must:

    1. Register sd-transforms with Style Dictionary using register(StyleDictionary, { ... }).
    2. Parse your $themes.json file.
    3. Map through the themes to create individual Style Dictionary configurations.
    4. Crucial: Since version 0.16.0, you must explicitly set preprocessors: ['tokens-studio'] in your configuration object.
    5. For each theme, define a platform (e.g., css) using the tokens-studio transformGroup and specify your desired transforms and files destination.
    import { register } from '@tokens-studio/sd-transforms';
    import StyleDictionary from 'style-dictionary';
    import { promises } from 'fs';
    
    register(StyleDictionary, {
      /* options here if needed */
    });
    
    async function run() {
      const $themes = JSON.parse(await promises.readFile('$themes.json', 'utf-8'));
      const configs = $themes.map(theme => ({
        source: Object.entries(theme.selectedTokenSets)
          .filter(([, val]) => val !== 'disabled')
          .map(([tokenset]) => `${tokenset}.json`),
        preprocessors: ['tokens-studio'], // <-- since 0.16.0 this must be explicit
        platforms: {
          css: {
            transformGroup: 'tokens-studio',
            transforms: ['name/kebab'],
            files: [
              {
                destination: `vars-${theme.name}.css`,
                format: 'css/variables',
              },
            ],
          },
        },
      }));
    
      async function cleanAndBuild(cfg) {
        const sd = new StyleDictionary(cfg);
        await sd.cleanAllPlatforms();
        await sd.buildAllPlatforms();
      }
      await Promise.all(configs.map(cleanAndBuild));
    }
    
    run();
  2. Install @tokens-studio/sd-transforms

    main

    Install the package via npm to use custom Style Dictionary transforms designed for Tokens Studio design tokens.

    npm install @tokens-studio/sd-transforms
  3. Create a custom transform group

    main

    If you want to use the tokens-studio transform group but modify it (e.g., remove a specific transform or add another), use getTransforms to retrieve the existing transforms and register a new group.

    import { getTransforms } from '@tokens-studio/sd-transforms';
    import StyleDictionary from 'style-dictionary';
    
    // Register custom tokens-studio transform group
    // without 'px' being added to numbers without a unit
    // and also adding 'name/constant' for the token names
    StyleDictionary.registerTransformGroup({
      name: 'custom/tokens-studio',
      transforms: [...getTransforms({ platform: 'css' }), 'name/constant'].filter(
        transform => transform !== 'ts/size/px',
      ),
    });
  4. Configure the 'tokens-studio' preprocessor

    main

    You must explicitly add 'tokens-studio' to the preprocessors array in your Style Dictionary configuration. This enables several features:

    • Extraction of fontStyles from embedded fontWeights.
    • Alignment of Tokens Studio token types with DTCG token types (original types are stored at $extensions['studio.tokens'].originalType).
    • Exclusion of parent keys for single-file Tokens Studio exports.
    {
      "source": ["tokens/**/*.json"],
      "preprocessors": ["tokens-studio"],
      "platforms": {}
    }
  5. Use expandTypesMap with Style Dictionary expand

    main

    When using Style Dictionary's expand feature to expand object-value (composite) tokens, you must pass expandTypesMap from @tokens-studio/sd-transforms. This is necessary because Tokens Studio tokens have slightly different structures than standard DTCG tokens (e.g., shadow tokens use x/y instead of offsetX/offsetY, and typography tokens include extra properties like paragraphSpacing).

    import StyleDictionary from 'style-dictionary';
    import { expandTypesMap } from '@tokens-studio/sd-transforms';
    
    const sd = new StyleDictionary({
      source: ['tokens/**/*.json'],
      preprocessors: ['tokens-studio'],
      expand: {
        typesMap: expandTypesMap,
      },
      platforms: {},
    });
  6. Configure register() options

    main

    The register function accepts an options object to customize the behavior of the tokens-studio transform group.

    nametypedefaultdescription
    excludeParentKeysbooleanfalseWhether or not to exclude parent keys from your token files
    platform'css'|'compose''css'Which platform to use the transforms for
    namestring'tokens-studio'Under which name to register the transformGroup
    withSDBuiltinsbooleantrueWhether to append Style Dictionary built-in transforms for the platform into the tokens-studio group
    alwaysAddFontStylebooleanfalseWhether to always add a 'normal' fontStyle property to typography tokens lacking it
    ts/color/modifiersColorModifierOptionsundefinedColor modifier options (see below)

    Color Modifier Options:

    • format: ColorModifierFormat (e.g., 'hex', 'hsl', 'lch', 'p3', 'srgb'). Overrides the output format.
    register(StyleDictionary, {
      excludeParentKeys: true,
      platform: 'css',
      name: 'tokens-studio',
      'ts/color/modifiers': {
        format: 'hex',
      },
    });
  7. Configure math precision with ts/resolveMath

    main

    The ts/resolveMath transform evaluates math expressions within token values. You can control the decimal precision of the resulting values using the mathFractionDigits option within your platform configuration.

    {
      "source": ["tokens.json"],
      "platforms": {
        "css": {
          "mathFractionDigits": 3,
          "transformGroup": "tokens-studio",
          "files": [
            {
              "format": "css/variables",
              "destination": "output.css"
            }
          ]
        }
      }
    }
  8. Apply individual transforms or groups

    main

    You can apply the entire tokens-studio transform group to a platform, or specify individual transforms manually.

    Example of applying specific transforms to an SCSS platform:

    "scss": {
      "transforms": ["ts/size/px", "ts/opacity", "name/kebab"],
      "buildPath": "build/scss/",
      "files": [
        {
          "destination": "variables.scss",
          "format": "scss/variables"
        }
      ]
    }
  9. Full example: Multi-dimensional theming with Style Dictionary

    main

    This complete workflow demonstrates how to use permutateThemes to generate separate CSS variable files for every possible theme combination produced by multi-dimensional theming.

    import { register, permutateThemes } from '@tokens-studio/sd-transforms';
    import StyleDictionary from 'style-dictionary';
    import { promises as fsPromises } from 'fs';
    
    register(StyleDictionary, {});
    
    async function run() {
      const $themes = JSON.parse(await fsPromises.readFile('$themes.json', 'utf-8'));
      const themes = permutateThemes($themes, { separator: '_' });
      
      const configs = Object.entries(themes).map(([name, tokensets]) => ({
        source: tokensets.map(tokenset => `${tokenset}.json`),
        preprocessors: ['tokens-studio'],
        platforms: {
          css: {
            transformGroup: 'tokens-studio',
            transforms: ['name/kebab'],
            files: [
              {
                destination: `vars-${name}.css`,
                format: 'css/variables',
              },
            ],
          },
        },
      }));
    
      async function cleanAndBuild(cfg) {
        const sd = new StyleDictionary(cfg);
        await sd.cleanAllPlatforms();
        await sd.buildAllPlatforms();
      }
      await Promise.all(configs.map(cleanAndBuild));
    }
    
    run();
  10. Create a custom transform using sd-transforms functions

    main

    Every transformation is available as a raw JavaScript function. You can use these to build your own custom Style Dictionary transforms.

    import { transformDimension } from '@tokens-studio/sd-transforms';
    import StyleDictionary from 'style-dictionary';
    
    StyleDictionary.registerTransform({
      name: 'my/size/px',
      type: 'value',
      transitive: true,
      filter: token => ['fontSizes', 'dimension', 'borderRadius', 'spacing'].includes(token.type),
      transform: token => transformDimension(token.value),
    });
  11. Basic usage with register()

    main

    To use the transforms, import register from @tokens-studio/sd-transforms and pass your StyleDictionary instance to it. This registers the generic and CSS transforms as a transform group named tokens-studio.

    Note: This library is only available in ESM.

    import { register } from '@tokens-studio/sd-transforms';
    import StyleDictionary from 'style-dictionary';
    
    // will register them on StyleDictionary object
    register(StyleDictionary);
    
    const sd = new StyleDictionary({
      source: ['tokens/**/*.json'],
      preprocessors: ['tokens-studio'], // must be explicit since 0.16.0
      platforms: {
        css: {
          transformGroup: 'tokens-studio', // applies all transforms in the group
          transforms: ['name/kebab'],
          buildPath: 'build/css/',
          files: [
            {
              destination: 'variables.css',
              format: 'css/variables',
            },
          ],
        },
      },
    });
    
    await sd.cleanAllPlatforms();
    await sd.buildAllPlatforms();