designtokens.io
v0.1.0
Published
A collection of transforms and utilities for design tokens
Readme
designtokens.io (experimental)
A collection of transforms and utilities for design tokens.
Note: This library expects design tokens to be formatted in accordance with the Design Tokens Format Module. The main divergence is
Token Groupshave an intermediary$tokensproperty which helps TypeScript distinguish betweenTokensandToken Groups, accurately validate token types, and infer design tokens. (SeecreateDesignTokensin theUsagesection.)
Installation
npm i designtokens.ioUsage
Create design tokens
import { createDesignTokens } from 'designtokens.io'
const designTokens = createDesignTokens({
tokenName: {
$description: 'Design token description',
$value: 'foo',
},
tokenAlias: {
$description: 'Alias token description',
$value: '{tokenGroup.tokenName}',
},
tokenGroup: {
$description: 'Token group description',
$tokens: {
tokenName: {
$description: 'Grouped token description',
$value: 'bar',
},
},
},
})If you are using TypeScript,
createDesignTokenswill validate input tokens match theDesignTokensinterface exactly and infer all members. This results in rich intellisense and type checking e.g.tokens.tokenGroup.$tokens.tokenName.$value
Note: There are identity function for each token type, e.g.
createDesignTokens,createDesignToken,createDesignTokenAlias,createDesignTokenComposite, andcreateDesignTokenGroup.
Transform design tokens to CSS variables
import * as fs from 'fs'
import { toCSSVars } from 'designtokens.io'
import { designTokens } from './designTokens'
await fs.promises.writeFile('design-tokens.css', toCSSVars(designTokens)):root {
--tokenName: foo;
--tokenAlias: var(--tokenGroup-tokenName);
--tokenGroup-tokenName: bar;
}Transform design tokens to SCSS variables
import * as fs from 'fs'
import { toSCSSVars } from 'designtokens.io'
import { designTokens } from './designTokens'
await fs.promises.writeFile('design-tokens.scss', toSCSSVars(designTokens))$tokenName: foo;
$tokenAlias: $tokenGroup-tokenName;
$tokenGroup-tokenName: bar;Create your own transform
import { traverse, DesignTokens } from 'designtokens.io'
interface ToDocsOptions {
title: string
}
export function toDocs(designTokens: DesignTokens, options: ToDocsOptions) {
const sections = [`# ${options.title}`]
function createSection(token, ctx) {
const isAliasToken = ctx.isAliasToken(token)
return [
`## ${ctx.path.join('.')}`,
token.$description && `> ${token.$description}`,
`**Value:** ${
isAliasToken
? ctx.getTokenFromAlias(token, ctx.tokens).$value
: token.$value
}`,
isAliasToken && `**Alias:** ${token.$value}`,
]
.filter(Boolean)
.join('\n\n')
}
traverse(designTokens, {
onToken: (token, ctx) => {
sections.push(createSection(token, ctx))
},
onAlias: (alias, ctx) => {
sections.push(createSection(alias, ctx))
},
})
return sections.join('\n\n\n')
}
// Usage:
import * as fs from 'fs'
import { designTokens } from './designTokens'
import { toDocs } from './toDocs'
await fs.promises.writeFile(
'design-tokens.md',
toDocs(designTokens, {
title: 'Design Tokens',
}),
)# Design Tokens
## tokenName
> Design token description
**Value:** foo
## tokenAlias
> Alias token description
**Value:** bar
**Alias:** {tokenGroup.tokenName}
## tokenGroup.tokenName
> Grouped token description
**Value:** barAPI
traverse(designTokens: DesignTokens, options: TraverseOptions)
Traverses the design tokens and executes synchronous callbacks for each token
type defined in the TraverseOptions.
designTokens: The design tokens to traverse.options: The traversal options.onToken(token: DesignToken, context: TraverseContext): Callback executed when a design token is visited.token: A reference to the design token object.context: An object containing metadata and helper methods.
onAlias(alias: DesignTokenAlias, context: TraverseContext): Callback executed when an alias token is visited.alias: A reference to the alias token object.context: An object containing metadata and helper methods.
onComposite(composite: DesignTokenComposite, context: TraverseContext): Callback executed when a composite token is visited.composite: A reference to the composite token object.context: An object containing metadata and helper methods.
onTokenGroup(tokenGroup: DesignTokenGroup, context: TraverseContext): Callback executed when a token group is visited.tokenGroup: A reference to the token group object.context: An object containing metadata and helper methods.
TraverseContext
An object provided to each visitor callback in TraverseOptions containing
helper methods and metadata about the current token.
name: Name of the current token, alias, composite or token group.tokens: A reference to the root design tokens object.path: An array of token names leading to the current token.- Note: This path has been filtered to exclude the
$tokensproperty. Helpful for composing token names such as CSS custom properties.
- Note: This path has been filtered to exclude the
rawPath: An array of token names leading to the current token.- Note: This path has not been filtered and contains the full path to the
current token from the root of the design tokens object. Helpful for
resolving an alias token's
$valueproperty.
- Note: This path has not been filtered and contains the full path to the
current token from the root of the design tokens object. Helpful for
resolving an alias token's
getPathFromAlias(alias: DesignTokenAlias): Retrieves the path to the token referenced in the alias token$value.getRawPathFromAlias(alias: DesignTokenAlias): Retrieves the raw path to the token referenced in the alias token$value.getTokenFromAlias(alias: DesignTokenAlias, tokens: DesignTokens): Retrieves the token referenced in the alias token$valuefrom the design tokens object.isDesignToken(tokenOrGroup: unknown): Type guard returningtrueif the input is a design token.isDesignTokenValue(value: unknown): Type guard returningtrueif the input is a valid design token value.isAliasToken(tokenOrGroup: unknown): Type guard returningtrueif the input is an alias token.isAliasTokenValue(value: unknown): Type guard returningtrueif the input is a valid alias token value.isCompositeToken(tokenOrGroup: unknown): Type guard returningtrueif the input is a composite token.isTokenGroup(tokenOrGroup: unknown): Type guard returningtrueif the input is a token group.
toCSSVars(designTokens: DesignTokens, options: ToCSSVarsOptions): string
designTokens: The design tokens to transform.options: The transformation options.selector: The selector wrapping the CSS variables. Set tonullto disable.prefix: The prefix added to each CSS variable.delimiter: The delimiter used when joining a design token path to create CSS variable names. Defaults to-.indent: The indentation used for each CSS variable. Defaults to 2 space characters.
toSCSSVars(designTokens: DesignTokens, options: ToSCSSVarsOptions): string
designTokens: The design tokens to transform.options: The options config.prefix: The prefix added to each SCSS variable name.delimiter: The delimiter used when joining a design token path to create SCSS variable names. Defaults to-.
createCSSVar(path: string[], options: CreatorOptions): string)
Creates a CSS custom property name from an array of names leading to a design token.
path: An array of names leading to a design token.options: The creator options.prefix: The prefix added to each CSS variable.delimiter: The delimiter used when joining a design token path to create CSS variable names. Defaults to-.
createCSSVar(['colors', 'blue', '500'], { prefix: 'dt' }) // '--dt-colors-blue-500'cssVarCreator(options: CreatorOptions): (path: string[]) => string
Higher order function to create prefixed CSS custom properties.
const createCSSVar = cssVarCreator({ prefix: 'dt', delimiter: '_' })
createCSSVar(['colors', 'blue', '500']) // '--dt_colors_blue_500'
createCSSVar(['colors', 'red', '500']) // '--dt_colors_red_500'createSCSSVar(path: string[], options: CreatorOptions): string)
Creates a SCSS variable name from an array of names leading to a design token.
path: An array of names leading to a design token.options: The creator options.prefix: The prefix added to each SCSS variable.delimiter: The delimiter used when joining a design token path to create SCSS variable names. Defaults to-.
createSCSSVar(['colors', 'blue', '500'], { prefix: 'dt' }) // '$dt-colors-blue-500'scssVarCreator(options: CreatorOptions): (path: string[]) => string
Higher order function to create prefixed SCSS custom properties.
const createSCSSVar = scssVarCreator({ prefix: 'dt', delimiter: '_' })
createSCSSVar(['colors', 'blue', '500']) // '$dt_colors_blue_500'
createSCSSVar(['colors', 'red', '500']) // '$dt_colors_red_500'