1.0.0-beta.1 ā€¢ Published 1 month ago

@quartzds/style-dictionary-extensions v1.0.0-beta.1

Weekly downloads
-
License
Apache-2.0
Repository
github
Last release
1 month ago

Style Dictionary extensions for the Quartz design tokens

CI Status NPM Package License REUSE status

šŸ’” Overview

This package provides extensions and helper functions to transform Quartz design tokens into resources for developers using Style Dictionary. Those design tokens are edited using the Tokens Studio plugin for Figma.

Prerequisites

  • A hierarchy of JSON files produced by the Tokens Studio plugin
  • node "^14.17.0 || >=16.0.0"
  • npm >=6
  • Style Dictionary ^3.8.0

Token transformation rules

Translating design tokens into platform-specific assets requires rules. Quartz uses specific rules based on its own conventions. The goal of this library is to package all those transformation rules into a convenient API for Style Dictionary.

Supported platforms

  • CSS

Coming soon:

  • Android
  • iOS
  • JavaScript
  • TypeScript

šŸ’æ Installation

npm install style-dictionary, @quartzds/style-dictionary-extensions

šŸ“– Usage

Create a build script that will configure and run Style Dictionary to output platform-specific assets, using the helpers provided by this package.

Register Quartz extensions

Start by registering Quartz extensions into the Style Dictionary instance using the setupQuartzConfig() helper function:

import StyleDictionary from 'style-dictionary'
import { setupQuartzConfig } from '@quartzds/style-dictionary-extensions'

setupQuartzConfig(StyleDictionary)

Then, create one or more Style Dictionary configurations to transform the design tokens for your target platforms.

Create Style Dictionary configurations

This package provide transform groups for every supported target platform.

Use the QdsTransformGroup enum to specify the id of the target platform in the transformGroup property of your configuration.

import { QdsTransformGroup } from '@quartzds/style-dictionary-extensions'

const desktopConfig = {
  platforms: {
    android: {
      transformGroup: QdsTransformGroup.androidPlatform,
      ...
    },
    css: {
      transformGroup: QdsTransformGroup.cssPlatform,
      ...
    },
    ios: {
      transformGroup: QdsTransformGroup.iosPlatform,
      ...
    },
  },
  ...
}

Apply the Quartz filter

You must provide the qdsDefaultFilter.name to the filter property of the generated platform files configuration:

import { QdsTransformGroup, qdsDefaultFilter } from '@quartzds/style-dictionary-extensions'

const lightThemeConfig = {
  platforms: {
    css: {
      transformGroup: QdsTransformGroup.cssTheme,
      files: [
        filter: qdsDefaultFilter.name,
        ...
      ],
      ...
    },
    ...
  },
  ...
}

Run Style Dictionary generation

Finally, let Style Dictionary build all the platforms for each of your configuration objects:

var sd = StyleDictionary.extend(desktopConfig)
sd.cleanAllPlatforms() // Optional
sd.buildAllPlatforms()

sd = StyleDictionary.extend(lightThemeConfig)
sd.cleanAllPlatforms() // Optional
sd.buildAllPlatforms()

šŸ““ Full example

This example assumes the following structure of design tokens files generated by the Tokens Studio plugin:

src/
ā””ā”€ā”€ tokens
    ā”œā”€ā”€ private.json <-- don't export these tokens (internal bindings)
    ā”œā”€ā”€ platform
    ā”‚   ā”œā”€ā”€ desktop.json
    ā”‚   ā””ā”€ā”€ mobile.json
    ā””ā”€ā”€ theme
        ā”œā”€ā”€ dark.json
        ā””ā”€ā”€ light.json

We want to transform these tokens into the following platform-specific assets:

dist/
ā”œā”€ā”€ css
ā”‚   ā”œā”€ā”€ platform
ā”‚   ā”‚   ā”œā”€ā”€ desktop.css
ā”‚   ā”‚   ā””ā”€ā”€ mobile.css
ā”‚   ā””ā”€ā”€ theme
ā”‚       ā”œā”€ā”€ dark.css
ā”‚       ā””ā”€ā”€ light.css
ā”œā”€ā”€ android
ā”‚   ā”œā”€ā”€ platform
ā”‚   ā”‚   ā”œā”€ā”€ desktop.xml
ā”‚   ā”‚   ā””ā”€ā”€ mobile.xml
ā”‚   ā””ā”€ā”€ theme
ā”‚       ā”œā”€ā”€ dark.xml
ā”‚       ā””ā”€ā”€ light.xml
ā””ā”€ā”€ ios
    ā”œā”€ā”€ platform
    ā”‚   ā”œā”€ā”€ desktop.swift
    ā”‚   ā””ā”€ā”€ mobile.swift
    ā””ā”€ā”€ theme
        ā”œā”€ā”€ dark.swift
        ā””ā”€ā”€ light.swift

Here is the script to achieve that:

import type { Config, FileHeader } from 'style-dictionary'
import StyleDictionary from 'style-dictionary'

import {
  qdsDefaultFilter,
  QdsTransformGroup,
  setupQuartzConfig,
} from '@quartzds/style-dictionary-extensions'

/*
 * Register Quartz extensions
 */

setupQuartzConfig(StyleDictionary)

/*
 * Style Dictionary configurations
 */

const lightThemeConfig = {
  platforms: {
    css: {
      transformGroup: QdsTransformGroup.cssTheme,
      files: [
        {
          destination: `dist/css/theme/light.css`,
          format: 'css/variables',
          filter: qdsDefaultFilter.name,
        },
      ],
    },
    android: {
      transformGroup: QdsTransformGroup.androidTheme,
      files: [
        {
          destination: `dist/android/theme/light.xml`,
          format: 'android/resources',
          filter: qdsDefaultFilter.name,
        },
      ],
    },
    ios: {
      transformGroup: QdsTransformGroup.iosTheme,
      files: [
        {
          destination: `dist/ios/theme/light.swift`,
          format: 'ios-swift/enum.swift',
          filter: qdsDefaultFilter.name,
        },
      ],
    },
  },

  include: [`./tokens/private.json`],
  source: [`./tokens/theme/light.json`],
}

const darkThemeConfig = {
  /* Same as lightThemeConfig */
}

const desktopConfig = {
  platforms: {
    css: {
      transformGroup: QdsTransformGroup.cssPlatform,
      files: [
        {
          destination: `dist/css/platform/desktop.css`,
          format: 'css/variables',
          filter: qdsDefaultFilter.name,
        },
      ],
    },
    android: {
      transformGroup: QdsTransformGroup.androidPlatform,
      files: [
        {
          destination: `dist/android/platform/desktop.xml`,
          format: 'android/resources',
          filter: qdsDefaultFilter.name,
        },
      ],
    },
    ios: {
      transformGroup: QdsTransformGroup.iosPlatform,
      files: [
        {
          destination: `dist/ios/platform/desktop.swift`,
          format: 'ios-swift/enum.swift',
          filter: qdsDefaultFilter.name,
        },
      ],
    },
  },

  include: [`./tokens/private.json`],
  source: [`./tokens/platform/desktop.json`],
}

const mobileConfig = {
  /* Same as desktopConfig */
}

/*
 * Style Dictionary generation
 */

const allConfigs = [
  desktopConfig,
  mobileConfig,
  lightThemeConfig,
  darkThemeConfig,
]

for (const config of allConfigs) {
  const sd = StyleDictionary.extend(config)
  sd.cleanAllPlatforms() // Optional
  sd.buildAllPlatforms()
}

āš–ļø License

See the LICENSE file for license rights and limitations.