Skip to content

Publish design tokens#

Description#


Beta: The --token-* CSS custom properties are in beta. We encourage you to start using them and welcome your feedback. The token API may still change, but we will communicate any breaking changes.


The design tokens are synchronized from Figma with the "Design Tokens" GitHub Action and converted to CSS variables with the make-properties script. We currently generate color and radius tokens. Typography is skipped.

Overview#

  • Design tokens are synchronized from Figma by a GitHub Action, which opens a draft pull request for review.
  • We generate color tokens and radius values. Typography aliases and string values are skipped for now.
  • We export Foundation colors, plus light and dark brand token modes for DNB and Sbanken (Carnegie is light-only for now)

How to update#

1. Run the "Design Tokens" workflow#

  1. Open Actions → Design Tokens, then select Run workflow on main.
  2. The workflow reads the Figma variables with the variables REST API, writes the *.tokens.json files listed below, regenerates the CSS files and their test snapshots, builds the library and Portal, updates the visual snapshots and opens a draft pull request from a new tokens/automation-figma-sync-YYYYMMDD-HHMMSS branch. If Figma and the Eufemia design tokens are already synchronized, it reports that no changes were found.
  3. Review the token values, removals and visual snapshots before marking the pull request ready.
  4. Review and (squash) merge the pull request.

Run on any other branch, the tokens are committed to that branch instead. The Output branch input overrides where the commit goes, and can name an existing branch or a new one, but not main or a release branch. An existing branch is built on as it is, without being rebased. A draft pull request is opened for the branch unless it already has one, and an open pull request is never modified. A new PR targets the branch it was created from.

The tokens and their test snapshots are committed separately from the screenshots, so the screenshot commit can be reviewed, or dropped, on its own. The commits are attributed to whoever started the run, and a new pull request is assigned to them. The pull request itself, and its comments, come from the GitHub Actions bot.

The Generate screenshots input is on by default. Turning it off skips the screenshot run, so the image snapshots are left untouched and have to be updated separately.

Every mode of the exported collections has to be listed in TOKEN_EXPORTS (packages/dnb-eufemia/scripts/figma/tasks/tokensExtractor.ts). A mode that is in Figma but not there is skipped with a warning, and only becomes CSS once it is added both to TOKEN_EXPORTS and to the token files in makePropertiesFile.ts. A mode that is listed but no longer in Figma fails the run.

The workflow writes color.tokens.json with only the foundation colors the brand collection actually uses, because the API returns the remote variables used in the file. A manual export contains the whole collection instead, so switching between the two shows up as a large diff in that one file without changing the generated CSS.

The workflow needs the repository secret FIGMA_TOKEN (a personal access token with the file_variables:read scope) and the repository variable FIGMA_TOKENS_FILE (the key of the "💻 Eufemia - Web" file). The Figma variables API is only available to Enterprise organizations.

2. Exporting design tokens manually#

As a fallback, the same files can be exported by hand.

We currently export the Figma variable collections for:

  • "Foundation" collection "colors" (color.tokens.json)
  • "💻 Eufemia - Web" collection "brand" with modes:
    • "dnb-light" (brand/dnb-light.tokens.json)
    • "dnb-dark" (brand/dnb-dark.tokens.json)
    • "sbanken-light" (brand/sbanken-light.tokens.json)
    • "sbanken-dark" (brand/sbanken-dark.tokens.json)
    • "dnbcarnegie-light" (brand/dnbcarnegie-light.tokens.json)
    • "dnbeiendom-light" (brand/dnbeiendom-light.tokens.json)
    • "dnbeiendom-dark" (brand/dnbeiendom-dark.tokens.json)

The Eiendom theme still uses the DNB tokens, so its exports do not generate CSS yet.

Place color.tokens.json directly in packages/dnb-eufemia/src/style/themes/figma, and place the brand-mode exports in its brand subfolder.

Detailed steps:

  • Go to the "💻 Eufemia - Web" file in Figma. (You need edit permissions to see sub-collections)
  • Active "Design" mode.
  • Click the "Open variables" icon next to the label "Variables" in the right side-menu (must deselect elements to see the side-menu).
  • Click the "Collections options" icon next to the "Collections" heading and ensure "All collections" is selected.
  • Right click the collections "brand" and "colors" and select "Export Modes".
  • Unzip the downloaded JSON files and place them in packages/dnb-eufemia/src/style/themes/figma, using the relative filenames listed above.

We export the collections from the same Figma file in order to ensure the collections are in sync. Each brand-mode export is a complete snapshot of the collection, so light and dark files also contain shared font and radius values. The generator produces one typography scale per brand from the light export. Dark mode does not change font sizes or line heights.

3. Generate CSS files#

The CSS files are automatically generated during the "Prebuild" step by the makePropertiesFile.ts script (packages/dnb-eufemia/scripts/prebuild/tasks/makePropertiesFile.ts).

Generate locally (manual)#

To generate the files manually you can run the command yarn workspace @dnb/eufemia make-properties.

To fetch the tokens from Figma locally, add FIGMA_TOKEN and FIGMA_TOKENS_FILE to your .env file and run yarn workspace @dnb/eufemia figma:tokens.

Naming conventions/transforms#

Since Figma has different rules and limitations than CSS we have established some naming conventions to avoid errors.

  • only use alphanumeric characters. (a-z and 0-9)
  • Variables are not case-sensitive. (onDark and ondark are considered the same variable)
  • We use dashes (-) to separate groups and words.

Transforms#

During the CSS generation, Figma variables are converted to lower case. And groups are separated by dashes (-).

Only characters a-z A-Z 0-9. and - are supported. Any unsupported characters will throw an error.

We also add the prefix token to the variables from the Brand collection.

Example#

Figma variable: Color/Dimmer/Action-Pressed-Subtle-OnDark

CSS variable: --token-color-dimmer-action-pressed-subtle-ondark

Potential issues#

Even following all the rules, we still risk naming overlap since groups and words use the same separator in CSS color/action/pressed and color/action-pressed would map to the same variable.

But these will at least be caught on build.

Suggest an edit