Design tokens
Design tokens are the single source of truth to name and store design decisions.Neutral selected-state tokens
When the platform-dst-tokens-finesse feature flag is enabled, color tokens for selected states use neutral colors instead of blue.
Installation
| Install | yarn add @atlaskit/tokens |
|---|---|
| Source | Bitbucket.org, (opens new window) |
| npm | @atlaskit/tokens, (opens new window) |
| Bundle | unpkg.com, (opens new window) |
API
token(path, fallback)
The token() function takes a dot-separated token name and returns a valid CSS custom property for
the corresponding token. This method will warn you if an unknown token is provided.
Additionally, provide a fallback argument to the token() method to ensure experiences remain
consistent for users until we are ready to launch. When the theme CSS is not present in your app,
the fallback color will render instead. Keep the fallback colour as the color visible in your app
today.
| Description | Name of the color token in string form |
|---|---|
| Type | keyof CSSTokenMap |
| Description | Optional color value, represented as a color code or hex value, used for when token usage has not been switched on for the site |
|---|---|
| Type | string |
import { token } from '@atlaskit/tokens';
const buttonStyles = {
backgroundColor: token('color.background.brand.bold'),
color: token('color.text.inverse'),
};
setGlobalTheme(themeState, themeLoader);
Use the setGlobalTheme method to switch themes globally at runtime. It:
- updates the
data-themeanddata-color-modeattributes on your page's HTML tag, anddata-custom-themeif theme options are provided. - dynamically loads in the CSS required to support each selected theme, and adds it to a series of
<style>tag in your page's document head. - optionally generates and loads customized themes based on the options provided.
- optionally overrides default theme loading behavior if a
themeLoaderfunction has been provided. E.g. when appending<style>elements isn't possible.
The themeState object includes the following properties:
- colorMode: Determines whether the light or dark color theme is shown. If set to
auto, the browser will use the OS setting to determine which is shown. - dark: The color theme to be shown when a "dark" theme is requested by the user (or triggered by OS setting).
- light: The color theme to be shown when a "light" theme is requested by the user (or triggered by OS setting).
- spacing: The spacing theme to be shown.
- typography: The typography theme to be shown.
- shape: The typography theme to be shown.
- UNSAFE_themeOptions: Options for customizing the loaded themes, such as a custom brand color.
| Description | Used to specify which themes the site is currently using. Omitted properties will fall back to the default value. To update properties, pass a function that returns the new theme state. |
|---|---|
| Default | { colorMode: "auto", dark: "dark", light: "light", spacing: "spacing", typography: "typography" } |
| Type | {
colorMode?: ColorMode<"light", "dark", "auto">,
light?: ThemeIds,
dark?: ThemeIds,
spacing?: ThemeIds,
typography?: ThemeIds,
shape?: ThemeIds,
UNSAFE_themeOptions?: CustomThemeSchema // { brandColor: HexColor }
} | ((themeState: ThemeState) => ThemeState) |
| Description | A callback function that can be used to override the default theme loading functionality. It will run the function for each required theme ID instead of creating `<style>` elements. For example, this can be used to add `<link>` elements for each theme instead. |
|---|---|
| Type | (id: ThemeIds) => void |
| Description | A Promise of a function, that can be used to stop listening for changes to system theme. |
|---|---|
| Type | Promise<() => void> |
Example usage
import { token, setGlobalTheme } from '@atlaskit/tokens';
const App = () => {
setGlobalTheme({
light: 'light',
dark: 'dark',
colorMode: 'auto',
});
return <div style={{ backgroundColor: token('elevation.surface') }}>...</div>;
};
Example usage to update properties
import { Button } from '@atlaskit/button';
import { token, setGlobalTheme } from '@atlaskit/tokens';
const App = () => {
setGlobalTheme({
light: 'light',
dark: 'dark',
colorMode: 'auto',
});
const switchColorMode = () => {
setGlobalTheme((themeState) => ({
...themeState,
colorMode: themeState.colorMode === 'light' ? 'dark' : 'light',
}));
};
return (
<div style={{ backgroundColor: token('elevation.surface') }}>
<Button onClick={switchColorMode}>Switch color mode</Button>
...
</div>
);
};
Example usage with custom theme options
Custom theming is in alpha.
Custom theming is in alpha, the UNSAFE_themeOptions API is subject to change or removal in minor or patch releases. For Atlassians, please reach out to Design System Team to learn more.
When UNSAFE_themeOptions is set in ThemeState, custom themes will be generated at runtime based on
the options provided. The available options for the UNSAFE_themeOptions prop are defined below:
- brandColor: sets a custom brand color that replaces the Atlassian blue. Affects
brand,selectedandlinkcolor tokens
| Description | The schema for defining custom themes |
|---|---|
| Type | {
brandColor: HexColor
} |
The theme generation logic is lazy-loaded only when UNSAFE_themeOptions is set.
import { token, setGlobalTheme } from '@atlaskit/tokens';
const App = () => {
setGlobalTheme({
colorMode: 'auto',
UNSAFE_themeOptions: {
brandColor: '#64329A',
},
});
return <div style={{ backgroundColor: token('elevation.surface') }}>...</div>;
};
Example usage with a theme loader
The themeLoader parameter takes a synchronous function, which will be called with the themeId
for each theme that needs to be loaded onto the page based for the provided ThemeState. If
colorMode is set to ‘light’, the theme set in ThemeState.dark will not be loaded, and visa
versa.
import { token, setGlobalTheme } from '@atlaskit/tokens';
const App = () => {
const themeLoader = (id) => {
const link = document.createElement('link');
const stylesheetUrl = `https://test-cdn.com/atlaskit-tokens_${id}.css`;
link.rel = 'stylesheet';
link.href = stylesheetUrl;
link.dataset.theme = id;
document.head.appendChild(link);
};
setGlobalTheme(
{
light: 'light',
dark: 'dark',
colorMode: 'auto',
},
themeLoader,
);
return <div style={{ backgroundColor: token('elevation.surface') }}>...</div>;
};
useThemeObserver()
A React hook which returns the current themes and color mode set on <html>. It is useful for
watching the theme and then performing side-effects when it changes.
| Description | Returns the current themes and color mode set. |
|---|---|
| Type | {
colorMode?: ColorMode<"light", "dark", "auto">,
light?: ThemeIds,
dark?: ThemeIds,
spacing?: ThemeIds,
typography?: ThemeIds,
} |
Example usage
import { useThemeObserver } from '@atlaskit/tokens';
const App = () => {
const theme = useThemeObserver();
console.log(theme); // { light: light, dark: dark, ... }
return <div>...</div>;
};
ThemeMutationObserver(callback)
An observer which watches the <html> element for changes to the theme. In React, use the
useThemeObserver hook.
| Description | Watches the <html> element for changes to the theme. The supplied callback function fires when the theme changes. |
|---|---|
| Type | (theme: ThemeState) => unknown |
Example usage
import { ThemeMutationObserver } from '@atlaskit/tokens';
const observer = new ThemeMutationObserver((newTheme) => {
console.log(newTheme); // { light: light, dark: dark, ... }
});
observer.observe();
observer.disconnect();
themeObjectToString(themes)
The themeObjectToString() function converts a theme state object into a formatted string. Useful
for cases where the theme state needs to be stored or transferred between systems via iframes etc.
The returned value could be provided as an argument to JavaScript's built-in encodeURIComponent()
function to convert the string into a URL friendly format.
| Description | |
|---|---|
| Type | {
light?: ThemeIds,
dark?: ThemeIds,
spacing?: ThemeIds,
typography?: ThemeIds,
} |
| Description | A string in the format used by the `data-theme` html attribute; or a stringified theme state object used for constructing a URL as query params |
|---|---|
| Type | string |
Example usage
import { themeObjectToString } from '@atlaskit/tokens';
const theme = {
colorMode: 'auto',
dark: 'dark',
light: 'light',
spacing: 'spacing',
};
const themeString = themeObjectToString(theme);
console.log(themeString);
// 'colorMode:auto dark:dark light:light spacing:spacing'
const themeQueryString = encodeURIComponent(themeString);
console.log(themeQueryString);
// 'colorMode%3Aauto%20dark%3Adark%20light%3Alight%20spacing%3Aspacing'
themeStringToObject(themes)
The themeStringToObject() function converts a string representation of the theme state into an
object that:
- can be passed to the
setGlobalTheme()function; - can be used for parsing a URL query parameters from a stringified theme state object.
An example of the expected formatting of the themes string is
'dark:dark light:light spacing:spacing'.
| Description | A string in the format used by the `data-theme` html attribute; or a stringified theme state object as a URL query string |
|---|---|
| Type | string |
| Description | An object representation of the theme string supplied. |
|---|---|
| Type | {
light?: ThemeIds,
dark?: ThemeIds,
spacing?: ThemeIds,
typography?: ThemeIds,
} |
Example usage
import { setGlobalTheme, themeStringToObject } from '@atlaskit/tokens';
const newTheme = 'colorMode:auto dark:dark light:light spacing:spacing';
function onThemeChangeHandler(newTheme) {
setGlobalTheme(themeStringToObject(newTheme));
}
const parsedUrlProps = {
contentId: 'contentId',
hostname: 'hostname',
themeState: 'colorMode:auto dark:dark light:light UNSAFE_themeOptions:{"brandColor":"#ff0000"}',
};
parsedThemeState = themeStringToObject(decodeURIComponent(parsedUrlProps.themeState));
getTokenValue(path, fallback)
The getTokenValue() function takes the same dot-separated token names as the main token()
function, however it returns the currently computed value based on the current theme. This is useful
for things like <canvas> which cannot inherit a CSS Variable.
Additionally, provide a fallback argument to the getTokenValue() method to ensure experiences
remain consistent for users until we are ready to launch. When the theme CSS is not present in your
app, the fallback color will render instead. Keep the fallback colour as the color visible in your
app today.
| Description | Name of the color token in string form |
|---|---|
| Type | keyof CSSTokenMap |
| Description | Optional color value, represented as a color code or hex value, used for when token usage has not been switched on for the site |
|---|---|
| Type | string |
Example usage
import { getTokenValue } from '@atlaskit/tokens';
getTokenValue('path.to.token', '#000000');
Server-side Rendering (SSR) utilities
setGlobalTheme provides the required logic for loading, applying and configuring themes on the
client side of your app. However, if your app supports server-side rendering (SSR), additional
configuration will be required to ensure themes are loaded before your app hydrates, otherwise users
can experience a flash of unthemed content before their preferred theme is loaded in.
The tokens package provides a set of utilities to assist with this. Each accepts a themeState
object with the user's stored theme preferences, and returns content to be applied manually to your
document on SSR render.
If your app stores user theme preference on the client side, such as in localStorage, your app may
need additional logic to check client-side preferences before first paint, and update theme HTML
attributes appropriately.
The example below demonstrates how these scripts can be used to support SSR in a basic NextJS app:
class MyDocument extends Document<DocumentProps> {
static async getInitialProps(
ctx: DocumentContext,
): Promise<DocumentInitialProps & DocumentProps> {
const initialProps = await Document.getInitialProps(ctx);
// Pass user theme preferences to `@atlaskit/tokens` SSR utilities:
const themeAttrs = getThemeHtmlAttrs(themePreferences);
const themeStyles = await getThemeStyles(themePreferences);
const ssrAutoScript = getSSRAutoScript(themePreferences.colorMode);
return {
...initialProps,
theme: {
htmlAttrs: themeAttrs,
styles: themeStyles,
},
ssrAutoScript,
};
}
render() {
return (
<Html lang="en" {...this.props.theme.htmlAttrs}>
<Head>
{this.props.theme.styles.map((theme) => (
<style
key={theme.id}
{...theme.themeAttrs}
dangerouslySetInnerHTML={{ __html: theme.themeCss }}
/>
))}
<script dangerouslySetInnerHTML={ssrAutoScript} />
</Head>
<body>
<Main />
</body>
</Html>
);
}
}
export default MyDocument;
These utilities should only be used when configuring SSR.
getThemeStyles(themeState | "all")
When server-side rendering the app, a number of themes need to be added as <style> tags to the
<head> of the document, based on the user's theme preferences.
Given a themeState object representing the user's theme preferences, getThemeStyles provides an
array of objects that can be used to construct these <style> tags:
id:the ID of the loaded themeattrs:an object of data attributes to attach to the<style>tagcss:the string of CSS to set as theinnerHtmlof the<style>, containing the styles for that theme.
By default, getThemeStyles only supplies the color themes necessary for initial render, based on
the current themeState. I.e. if the user has automatic theme switching turned off, and is in light
mode, dark mode themes will not be returned.
When passing the string "all" as an argument to getThemeStyles, it will return objects for all
possible themes instead of just the ones associated with a themeState.
When UNSAFE_themeOptions is set in themeState, additional objects will be returned for
constructing custom theme <style> tags.
If an error is encountered while loading a specific theme, the theme styles for that theme will be missing from the returned array, and will only be visible to the user on app hydration.
| Description | Used to specify which themes the site is currently using. Omitted properties will fall back to the default value. |
|---|---|
| Default | { colorMode: "auto", dark: "dark", light: "light", spacing: "spacing", typography: "typography" } |
| Type | {
colorMode?: ColorMode<"light", "dark", "auto">,
light?: ThemeIds,
dark?: ThemeIds,
spacing?: ThemeIds,
typography?: ThemeIds,
UNSAFE_themeOptions?: { brandColor: HexColor }
} |
| Description | A promise that resolves to an array of objects with the theme styles. |
|---|---|
| Type | Promise<{
id: ThemeIds,
attrs: {
color-theme: ThemeIds
},
css: string
}[]> |
getThemeHtmlAttrs(themeState)
Generates the valid HTML attributes to set on the document, for a given theme configuration.
Use setGlobalTheme to set attributes correctly on the client side - this utility should only be
used when configuring SSR.
| Description | Used to specify which themes the site is currently using. Omitted properties will fall back to the default value. |
|---|---|
| Default | { colorMode: "auto", dark: "dark", light: "light", spacing: "spacing", typography: "typography" } |
| Type | {
colorMode?: ColorMode<"light", "dark", "auto">,
light?: ThemeIds,
dark?: ThemeIds,
spacing?: ThemeIds,
typography?: ThemeIds,
UNSAFE_themeOptions?: { brandColor: HexColor }
} |
| Description | A record of HTML attributes to be applied to the document root. |
|---|---|
| Type | Record<string, string> |
getSSRAutoScript(colorMode)
The getSSRAutoScript function enables SSR support for 'auto' theme switching. It provides a script
that, when executed before paint, sets the data-color-mode attribute based on the current system
theme, to avoid a flash of un-themed content on first paint.
The SSR server should attach the return value of this function as the innerhtml of a script tag
inside the <head> of the document element.
| Description | Used to specify which themes the site is currently using. Omitted properties will fall back to the default value. |
|---|---|
| Default | { colorMode: "auto", dark: "dark", light: "light", spacing: "spacing", typography: "typography" } |
| Type | {
colorMode?: ColorMode<"light", "dark", "auto">,
light?: ThemeIds,
dark?: ThemeIds,
spacing?: ThemeIds,
typography?: ThemeIds,
} |
| Description | A string containing a script to update `data-color-mode` attribute based on the current system theme. |
|---|---|
| Type | string |
Loading and applying themes on the client
If your app is unable to configure data-attributes or styles on the server at request time, it may
be necessary to load and apply themes on the client instead. This can be necessary for static sites
or apps that store the user's theme preferences on the client (such as in localStorage).
For these cases, the @atlaskit/tokens package provides synchronous alternative functions to
setGlobalTheme that can synchronously configure the page on first render.
On the server, use the SSR utilities above to generate the theme assets and bundle them with your application:
// webpack.config.js
const webpack = require('webpack');
const generate = require('generate-file-webpack-plugin');
const { getThemeStyles } = require('@atlaskit/tokens');
module.exports = async (env) => {
const themeStyles = await getThemeStyles();
return {
// ...
plugins: [
...themeStyles.map(({ id, css }) =>
generate({
file: `themes/atlaskit-tokens_${id}.css`,
content: css,
}),
),
],
};
};
At build time, add all required themes as <link>s or <styles> in your document template. To
ensure all recommended themes are included, we recommend generating the list at build time using
getThemeStyles.
<!-- Index.html -->
<html>
<head>
<link rel="stylesheet" href="path/to/atlaskit-tokens_<theme-name-1>.css" />
<link rel="stylesheet" href="path/to/atlaskit-tokens_<theme-name-2>.css" />
<!-- Generate links for all required styles using getThemeStyles ... -->
</head>
<body></body>
</html>
On the client, call enableGlobalTheme and UNSAFE_loadCustomThemeStyles to configure the page.
// App.ts
import { setGlobalTheme } from '@atlaskit/tokens';
import { UNSAFE_loadCustomThemeStyles } from `@atlaskit/tokens/custom-themes`
enableGlobalTheme(themePreferences);
UNSAFE_loadCustomThemeStyles(themePreferences);
Client-side configuration of themes can cause a flash of unthemed content
Styles and data-attributes added to the document via client-side Javascript will not block first paint; depending on how your app renders, your users may see a flash of unthemed content.
Where possible, we recommend configuring themes on the server instead.
More details on these two utilities are included below:
enableGlobalTheme(themeState)
The enableGlobalTheme function is a synchronous alternative to setGlobalTheme, that can be used
to configure the theme before first paint. It should only be used in cases where the document cannot
be configured by the server. Depending on when it is called, it may still result in a flash of
un-themed content.
Similar to setGlobalTheme, it updates data-attributes and adds listeners to the page for automatic
theme switching.
Unlike setGlobalTheme, enableGlobalTheme does not load CSS onto the page; instead themes should
be loaded manually, by extracting and bundling themes from getThemeStyles at build time. Custom
theme styles can be generated at runtime using UNSAFE_loadCustomThemeStyles (see below).
| Description | Used to specify which themes the site is currently using. Omitted properties will fall back to the default value. |
|---|---|
| Default | { colorMode: "auto", dark: "dark", light: "light", spacing: "spacing", typography: "typography" } |
| Type | {
colorMode?: ColorMode<"light", "dark", "auto">,
light?: ThemeIds,
dark?: ThemeIds,
spacing?: ThemeIds,
typography?: ThemeIds,
UNSAFE_themeOptions?: CustomThemeSchema // { brandColor: HexColor }
} |
| Description | A callback function that can be used to override the default theme loading functionality. It will run the function for each required theme ID instead of creating `<style>` elements. For example, this can be used to add `<link>` elements for each theme. |
|---|---|
| Type | (id: ThemeIds) => void |
| Description | A function, that can be used to stop listening for changes to system theme. |
|---|---|
| Type | () => void |
UNSAFE_loadCustomThemeStyles(themeState)
The UNSAFE_loadCustomThemeStyles function provides a synchronous way of generating and setting
custom theme styles on the page. It should only be used in cases where the styles cannot be
generated and set by the server. Depending on when it is called, it may still result in a flash of
un-themed content. The generated styles are activated by a data-custom-theme attribute on the
<html> element, which is set by setGlobalTheme or enableGlobalTheme.
It can be accessed from the entrypoint @atlaskit/tokens/custom-themes/
| Description | Used to specify which themes the site is currently using. Omitted properties will fall back to the default value. |
|---|---|
| Default | { colorMode: "auto", dark: "dark", light: "light", spacing: "spacing", typography: "typography" } |
| Type | {
colorMode?: ColorMode<"light", "dark", "auto">,
light?: ThemeIds,
dark?: ThemeIds,
spacing?: ThemeIds,
typography?: ThemeIds,
UNSAFE_themeOptions?: CustomThemeSchema // { brandColor: HexColor }
} |
Current surface color
The current surface is a dynamic color value implemented via CSS custom properties (CSS variables). Which allows UI to be styled with a color based on a parent element's surface color. This is useful when an element needs an opaque background based on a parent element's surface color. For example, when it needs to mask content.
Some components in the Atlassian Design System will set the CURRENT_SURFACE_CSS_VAR when they set
a surface color. The following components set the surface color CSS variable:
Get the current suface color
The current surface color can be used the same way as other design tokens are used:
- JavaScript syntax:
token('utility.elevation.surface.current') - CSS syntax:
--ds-elevation-surface-current
Example usage with the ModalDialog component
import Modal, { ModalBody } from '@atlaskit/modal-dialog';
import { token } from '@atlaskit/tokens';
function ExampleWithModal() {
return (
<Modal>
<ModalBody>
<div
style={{
backgroundColor: token('utility.elevation.surface.current'),
}}
>
This div's background color will be set to the background color of the Modal.
</div>
</ModalBody>
</Modal>
);
}
Set the current suface color
The simplest way to set the current surface color is by using the Box primitive. When the background
color of a Box is set to a surface token,
internally it will set the current surface color to that token for its children to utilise.
Example usage with the Box component
import { Box } from '@atlaskit/primitives';
import { token } from '@atlaskit/tokens';
function ExampleWithBox() {
return (
<Box backgroundColor="elevation.surface.raised">
<div style={{ backgroundColor: token('utility.elevation.surface.current') }}>
This div's background color will be set to the background color of the parent Box.
</div>
</Box>
);
}
For cases where the Box component cannot be used (for example, in non-react apps), the
CURRENT_SURFACE_CSS_VAR constant can be used to set the current surface color. The
CURRENT_SURFACE_CSS_VAR constant is the CSS custom property name for accessing the 'current
surface' value.
Example usage
import { CURRENT_SURFACE_CSS_VAR, token } from '@atlaskit/tokens';
function Example() {
return (
<div style={{ [CURRENT_SURFACE_CSS_VAR]: token('elevation.surface.overlay') }}>
<div style={{ backgroundColor: token('utility.elevation.surface.current') }}>
This div's background color will be the value assigned to `CURRENT_SURFACE_CSS_VAR`.
</div>
</div>
);
}