Style Dictionary extensions for the Quartz design tokens
💡 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.