Skip to content

Constraints

Conversion for tokens with constrained values will be explained here. The idea is to use a Style Dictionary platform for each constraint, which also means, there will be one CSS generated per such platform.

Uses:

Input

density.tokens.json
json
{
  "spacing": {
    "density": {
      "$value": [
        {
          "value": 1,
          "features": {
            "density": "comfortable"
          }
        },
        {
          "value": 1.2,
          "features": {
            "density": "spacious"
          }
        },
        {
          "value": 0.8,
          "features": {
            "density": "compact"
          }
        }
      ],
      "$description": "",
      "$type": "number"
    }
  }
}

Configuration

In order to filter for tokens, we will set the constraints on the platform itself and then use the isConstrainedByPlatform() to match tokens against them.

config.js
js
import StyleDictionary from 'style-dictionary';

import {
  isConstrainedByPlatform,
  registerTheemo
} from '@theemo/style-dictionary';

registerTheemo(StyleDictionary);

/** @type import("style-dictionary/types").Config */
const config = {
  source: ['tokens/**/*.json'],
  preprocessors: ['theemo/token'],
  platforms: {
    css: {
      // ...
    },
    // constrained tokens (to combine them later under given selectors)
    'density-comfortable': {
      transformGroup: 'theemo',
      buildPath: 'build/',
      constraints: {
        features: {
          density: density
        }
      },
      options: {
        outputReferences: true,
        showFileHeader: false
      },
      files: [
        {
          format: 'css/variables',
          destination: `density-comfortable.css`,
          filter: isConstrainedByPlatform
        }
      ]
    }
  }
};

export default config;

This is apparently for one constraint match. Usually there are more such values, so it is prime candidate to turn these into functions:

config.js
js
import 
StyleDictionary
from 'style-dictionary';
import {
isConstrainedByPlatform
,
registerTheemo
} from '@theemo/style-dictionary';
registerTheemo
(
StyleDictionary
);
function
makeDensityPlatform
(
density
) {
return {
transformGroup
: 'theemo',
buildPath
: 'build/',
constraints
: {
features
: {
density
:
density
} },
options
: {
outputReferences
: true,
showFileHeader
: false
},
files
: [
{
format
: 'css/variables',
destination
: `density-${
density
}.css`,
filter
:
isConstrainedByPlatform
} ] }; } /** @type import("style-dictionary/types").Config */ export default {
source
: ['tokens/**/*.json'],
preprocessors
: ['theemo/token'],
platforms
: {
css
: {
// ... }, // constrained tokens (to combine them later under given selectors) 'density-comfortable':
makeDensityPlatform
('comfortable'),
'density-spacious':
makeDensityPlatform
('spacious'),
'density-compact':
makeDensityPlatform
('compact')
} };

Output

css
:root {
  --spacing-density: 0.8;
}
css
:root {
  --spacing-density: 1;
}
css
:root {
  --spacing-density: 1.2;
}