@grafana/design-tokens
v0.0.35
Published
Design Tokens for Grafana
Readme
Design Tokens
A proof of concept for a Source of Truth for Design Tokens across Grafana Labs products, using Style Dictionary.
Architecture
This Design Tokens package has several primary goals:
- Provide a Source of Truth for Design Tokens used across all Grafana applications
- Apply and document a layer of semantics to small, discrete design decisions which can be used to inform product design decisions made by both humans and AI tools.
- Provide a convenient API for exposing these tokens in a framework-agnostic format, allowing them be consumed directly within other libraries.
- To be independent of pre-existing Grafana interface libraries (e.g.
@grafana/dataand@grafana/ui), to aid with decoupling and adoption. - To facilitate the migration of existing Grafana UI to any future visual refresh of the product.
Source of Truth
The Design Tokens that live within src/tokens/ follow the Design Tokens
Format community proposal JSON format, with three distinct types of token,
broken up as follows:
- Primitives
- Semantic
- Components
Primitive Tokens
Primitive tokens represent abstract values, absent context about how they are
intended to be used. For example, a color token of blue-50 might have a value
of #0000cc. Primitive tokens are usually then referenced by the semantic
tokens.
Semantic Tokens
Semantic tokens define the relationship between a given token and its usage —
usually mapping to a primitive (or other semantic) token. For example, you might
have a token of primary.color which maps to blue-50. Additionally, multiple
semantic tokens with the same name might exist for different color modes (light
and dark).
Component Tokens
Component tokens are tokens that map specific properties of a component
implementation to a semantic tokens, for example linkColor could map to
primary.color.
Legacy Tokens
Since facilitating migration of existing Grafana UI is one of the primary goals
of this package, the API provided by the library also provides a convenience
wrapper to the existing legacy design tokens, using a structure mirroring the
existing API of useTheme2() provided by @grafana/ui. An example of how to
migrate existing calls is given further below.
getDesignTokens()
The utility function getDesignTokens() exposes all of the tokens defined
within the src/tokens/ directory.
import { getDesignTokens } from '@grafana/design-tokens';
const { primitives, semantic } = getDesignTokens({ mode: 'dark' });As well as the new semantic design tokens, the function also exposes equivalent
legacy tokens to those in @grafana/data’s createTheme() function. These
provide a mechanism for retrieving design token values in an API-compatible
structure, to allow them to be dropped in in place of the existing
implementations:
// createTheme.ts
import { getDesignTokens } from '@grafana/design-tokens';
export function createTheme(options: NewThemeOptions = {}): GrafanaTheme2 {
const {
name,
colors: colorsInput = {},
spacing: spacingInput = {},
shape: shapeInput = {},
typography: typographyInput = {},
visualization: visualizationInput = {},
} = options;
const { legacy } = getDesignTokens({ mode: colorsInput.mode });
const colors = {
...createColors(colorsInput),
...legacy.colors,
};
...
}Colocating the legacy tokens along with the new tokens will aid in the transition for existing component implementations.
Migrating from useTheme2()
For a component that currently uses CSS in JS to build its styles with
useTheme2(), you can migrate this to use getDesignTokens() instead.
First, ensure you’re importing getDesignTokens from the package:
import { getDesignTokens } from '@grafana/design-tokens';Then, when building the styles to apply to your component, update the style getter function:
export function getStyles(theme: GrafanaTheme2) {
+ const { legacy } = getDesignTokens({ mode: theme.colors.mode });
return {
- color: theme.colors.primary.text,
+ color: legacy.colors.primary.text,
- borderColor: theme.colors.border.strong,
+ borderColor: legacy.colors.border.strong,
};
}This API is intended to facilitate migration of components until such time as
an equivalent and comprehensive set of semantic tokens is available, at which
point the legacy API will be deprecated. In the interim, migrating to using the
legacy tokens API will allow you to reduce or remove your dependence on the
useTheme2() API without any UI breakage.
Building & Publishing
At present a temporary publish workflow exists using GitHub Actions. To publish
a new version of this package, you simply need to merge to the main branch,
ensuring that the version number (following semver) in package.json has been
incremented.
Future improvements
- Automatically increment the version using semver based on semantic commits
- Deploy the static CSS resources to a CDN
