Style dictionary utils
style-dictionary-utils
is a collection of parsers
, filters
, transformers
and formats
for Style Dictionary that make working with w3c design tokens a lot easier.
Installation
Install the style-dictionary-utils
as well as style-dictionary
.
npm i -D style-dictionary-utils style-dictionary
If you are using .json5
files to define your design tokens install json5
as well.
npm i -D json5
How to use style dictionary version 3?
If you are not ready to upgrade to style dictinary version 3 you can continue using style-dictionary-utils
by locking to v2
currently v2.4.1
version.
Getting started
The easiest way to use style-dictionary-utils
is to import the prepared StyleDictionary
object into your build file:
// build.ts
import StyleDictionary from 'style-dictionary-utils'
const myStyleDictionary = StyleDictionary.extend({
"platforms": {
"ts": {
"transforms": ['color/hexAlpha', 'shadow/css'],
"files": [{
"filter": "isSource",
"destination": "tokens.ts",
"format": "javascript/esm",
}]
}
}
});
myStyleDictionary.buildAllPlatforms();
Now all the included utilities* are available to you via the keys mentioned in the docs below.
* You only need to register the w3cTokenJson5Parser
if you want to use json5
.
Extending style dictionary
You can still extend style dictionary with your own transformers and formats like before.
The only difference is that you must use the StyleDictionary
object that you import from style-dictionary-utils
.
// build.ts
import StyleDictionary from 'style-dictionary-utils'
StyleDictionary.registerTransform({
name: 'transform/pxToRem',
type: `value`,
transitive: true,
transformer: () => // ...
})
Look at the tests to get an idea how it works.
Included utilities
- Parsers
- Formats
- Transformers
- Filters
- Special Filter
📠 Parsers
w3cTokenJsonParser
This parser parses .json
with w3c design tokens.
This means the following files can be used with this parser.
{
"token": {
"value": "#223344",
"type": "color",
"description": "token description"
},
"w3cToken": {
"$value": "#223344",
"$type": "color",
"$description": "token description"
}
}
The parser will keep most propertys as is and only change $value
to value
and $description
or description
to comment
. This required for Style Dictionary.
To register the parsers add the following code to your build file.
import StyleDictionary from 'style-dictionary-utils'
import { w3cTokenJsonParser } from 'style-dictionary-utils/dist/parser/w3c-token-json-parser'
StyleDictionary.registerParser(w3cTokenJsonParser)
w3cTokenJson5Parser (not autoloaded)
If you are using .json5
or .jsonc
files to define your design tokens you need to use the w3cTokenJson5Parser
. This is NOT enabled by default as it requires an additonal package, json5
, to work.
This parser is exactly the same as the w3cTokenJsonParser
with the only difference that it can parse .json5
or .jsonc
.
To register the parsers add the following code to your build file.
import StyleDictionary from 'style-dictionary-utils'
import { w3cTokenJson5Parser } from 'style-dictionary-utils/dist/parser/w3c-token-json5-parser'
StyleDictionary.registerParser(w3cTokenJson5Parser)
Make sure to install json5
by running npm i -D json5
.
If you’re using Prettier, be aware that the default configuration removes quote props, which are needed in $type
and $value
props in order to parse the tokens.
Here’s an example of a prettier config that overrides the default:
semi: false
singleQuote: true
overrides:
- files: '*.json[c|5]'
options:
quoteProps: preserve
singleQuote: false
📑 Formats
javascript/esm
The javascript/esm
format exports a token dictionary as an es6 export
statement.
export default {
colors: {
primary: '#0D70E6'
}
}
Usage:
const myStyleDictionary = StyleDictionary.extend({
"platforms": {
"ts": {
"transforms": //...,
"files": [{
// ...
"format": "javascript/esm",
}]
}
}
});
javascript/commonJs
The javascript/commonJs
format exports a token dictionary as an commonJs module
.
exports.default = {
colors: {
primary: '#0D70E6'
}
}
Usage:
const myStyleDictionary = StyleDictionary.extend({
"platforms": {
"js": {
"transforms": //...,
"files": [{
// ...
"format": "javascript/commonJs",
}]
}
}
});
css/advanced
The css/advanced
format exports a token dictionary as a css
file with css variables. It allows you to define media queries that can wrap specific parts of your css variables. If nothing is defined the entire file will be wrapped in a :root
selector.
You can change the selector by defining it in file.options.selector
.
You can define rules on a file level using file.options.rules
. If one or more rules are defined, only tokens within any of the rules will be output. You can define as many rule objects within file.options.rules
as you want. Tokens can be part of one or multiple rules.
A rule object may have any or all of the three properties atRule
, selector
and matcher
.
selector
is a string that is wrapped around your css. If theselector
is undefined, the default selector or one define atfile.options.selector
will be used. If you don't want a selector, set it tofalse
.atRule
can be a string or array of strings, that are wrapped around the css andselector
with the first being the outer layer.matcher
is a filter function that returns true for tokens that should be included in the query. If you want to match all tokens, just return true from the matcher.
body[theme="dark"] {
--color-background-primary: #ff0000;
--color-background-secondary: #0000ff;
}
@media (min-width: 768px) {
body[theme="dark"] {
--color-button-primary: #c1c1c1;
--color-button-secondary: #007D79;
}
}
Usage:
const myStyleDictionary = StyleDictionary.extend({
"platforms": {
"css": {
"transforms": //...,
"files": [{
// ...
"format": "css/advanced",
"options": {
selector: `body[theme="dark"]`, // defaults to :root; set to false to disable
rules: [
{
atRule: '@media (min-width: 768px)',
selector: `body[size="medium"]` // this will be used instead of body[theme="dark"]`
matcher: (token: StyleDictionary.TransformedToken) => token.filePath.includes('tablet'), // tokens that match this filter will be added inside the media query
}]
}
}]
}
}
});
🤖 Transformers
Transforms change the value
or name
of a token.
You can use transforms by refering the name in the array value of the transforms
property of a platform
.
Transform group
If you want to use the same transformers
multiple times you can create a transform group
for easy reference.
StyleDictionary.registerTransformGroup({
name: 'webHex',
transforms: [
'color/hexAlpha',
'dimension/pixelToRem',
'font/css'
]
});
css/extended
transform group
This packages ships a predefined transform group, called css/extended
.
It includes all transforms from the original css
transform group as well as the following transforms: color/rgbAlpha
, shadow/css
, font/css
, fontFamily/css
, fontWeight/number
, name/pathToDotNotation
, cubicBezier/css
, border/css
.
You can use it like any other transform Group:
const myStyleDictionary = StyleDictionary.extend({
"platforms": {
"css": {
"transformGroup": 'css/extended',
"files": [{
// ...
}]
}
}
});
name/pathToDotNotation
This name
transformer replaces the token name with the entire path of the token in dot.notation.
This is especially useful for flat .js
or .json
files.
To use it simply add name/pathToDotNotation
to the transforms
array.
const myStyleDictionary = StyleDictionary.extend({
"platforms": {
"ts": {
"transforms": ['name/pathToDotNotation'],
"files": [{
// ...
}]
}
}
});
Before transformation
{
colors: {
red: {
100: {
// ...
}
}
}
}
After transformation
{
"colors.red.100": {
// ...
}
}
name/pathToCamelCase
This name
transformer replaces the token name with the entire path of the token in camelCase notation.
To use it simply add name/pathToCamelCase
to the transforms
array.
const myStyleDictionary = StyleDictionary.extend({
"platforms": {
"ts": {
"transforms": ['name/pathToCamelCase'],
"files": [{
// ...
}]
}
}
});
Before transformation
{
colors: {
bg: {
default: {
// ...
}
}
}
}
After transformation
{
"colorsBgDefault": {
// ...
}
}
color/rgbAlpha
This value
transformer replaces the value of a token with a $type
or type
of color
with an rgba
string. If the token has an alpha
value, it will be used as the alpha
of the rgba
string.
Note: If your initial color value has an alpha value (e.g. hex8
) AND you add an alpha
property, the alpha
property will simply replace the previous alpha value.
const myStyleDictionary = StyleDictionary.extend({
"platforms": {
"ts": {
"transforms": ['color/rgbAlpha'],
"files": [{
// ...
}]
}
}
});
Before transformation
{
colors: {
blue: {
500: {
value: "#0D70E6",
$type: "color",
alpha: 0.4
}
}
}
}
After transformation
{
colors: {
blue: {
500: {
value: "rgba(13, 112, 230, 0.4)",
$type: "color",
alpha: 0.4
}
}
}
}
color/hexAlpha
This value
transformer replaces the value of a token with a $type
or type
of color
with a hex
string. If the token has an alpha
value, it will be used as the alpha
of the hex8
string.
Note: If your initial color value has an alpha value (e.g. rgba
) AND you add an alpha
property, the alpha
property will simply replace the previous alpha value.
const myStyleDictionary = StyleDictionary.extend({
"platforms": {
"ts": {
"transforms": ['color/hexAlpha'],
"files": [{
// ...
}]
}
}
});
Before transformation
{
colors: {
blue: {
500: {
value: "rgba(13, 112, 230, 0.4)",
$type: "color",
alpha: 0.2
}
}
}
}
After transformation
{
colors: {
blue: {
500: {
value: "#0D70E633", // prev alpha value is replaced with 0.2 from alpha property
$type: "color",
alpha: 0.2
}
}
}
}
color/hex
This value
transformer replaces the value of a token with a $type
or type
of color
with a hex
string.
const myStyleDictionary = StyleDictionary.extend({
"platforms": {
"ts": {
"transforms": ['color/hex'],
"files": [{
// ...
}]
}
}
});
Before transformation
{
colors: {
blue: {
500: {
value: "rgba(13, 112, 230, 0.4)",
$type: "color"
}
}
}
}
After transformation
{
colors: {
blue: {
500: {
value: "#0D70E666",
$type: "color"
}
}
}
}
color/rgba
This value
transformer replaces the value of a token with a $type
or type
of color
with an rgba
string.
const myStyleDictionary = StyleDictionary.extend({
"platforms": {
"ts": {
"transforms": ['color/rgba'],
"files": [{
// ...
}]
}
}
});
Before transformation
{
colors: {
blue: {
500: {
value: "#0D70E666",
$type: "color"
}
}
}
}