Capabilities
Client Library
Color Theme Compliance (Beta)
UI Functions

Rate this page:

Using Atlassian Design Tokens in your Power-Up

Whether you are trying to migrate an existing Power-Up or creating a new one, this guide will help you understand how to use Atlassian Design Tokens. Using Atlassian Design Tokens in your Power-Up is the easiest way to make your Power-Up color theme compliant, so your Power-Up can look its best regardless if your user is in light mode or dark mode.

Make sure you're familiar with the Style Guide before moving on.

What are Atlassian Design Tokens?

Atlassian design tokens represent colors that you can use in your css to make your Power-Up color theme compliant. Each token has a name and two colors: the light mode version and the dark mode version.

A list of all the design tokens can be found on the Atlassian Design Tokens reference page.

Color tokens are often named based off of the intent of the component it’s trying to color, not the necessarily actual name of the color. Here are some examples of color tokens:

  1. --ds-text (or color.text in JS syntax) is used for normal text. It’s a dark gray in light mode, but a lighter gray in dark mode.
  2. --ds-link (or color.link in JS syntax) is used for links. It’s a dark blue in light mode, but a light blue in dark mode.
  3. --ds-background-success is used for backgrounds communicating a favorable outcome, such as success message. There is also --ds-background-success-hovered, which is the “hovered” color of this background. Success colors are typically green.

Choosing the Right Token

Here is the Atlassian Design Tokens reference page, which allows you to search for tokens. It also has a “Token Picker” which acts as a decision flowchart to help you land on the right color token for the component you are trying to color.

For best usage, switch the syntax type to “CSS syntax” (instead of JavaScript syntax).

Using the Token in your CSS

Once you’ve chosen the token that you want, it’s off to the races! Let’s say we’re working on a card-back-section, and we’ve chosen these color tokens:

  1. --ds-text (or color.text in JS syntax) for our text color.
  2. --ds-background-neutral (or color.background.neutral in JS syntax) for our background color

Head over to your css file and use the "var” css syntax to use the token.

1
2
/* card-back-section.css */
.my-component {
  color: var(--ds-text);
  background-color: var(--ds-background-neutral);
}

Now, in the HTML of your card back section, make sure your sheet is linked like so:

1
2
<!-- card-back-section.html -->
<html>
  <head>
    <link rel="stylesheet" href="https://p.trellocdn.com/power-up.min.css" />
    <link rel="stylesheet" href="./css/card-back-section.css" />
    <script src="https://p.trellocdn.com/power-up.min.js"></script>
  </head>
  <body>
    <div class="my-component">...</div>
  </body>
  <script src="./js/card-back-section.js"></script>
</html>

And finally, inside your card-back-section.js, make sure to call TrelloPowerUp.iframe(), which will initialize your iframe’s color theme listener, so it stay up to date with the user’s current theme setting.

1
2
// card-back-section.js
const t = window.TrelloPowerUp.iframe();

And you’re done! Now try looking at the your Power-Up’s card back section in both light and dark modes in Trello. In dark mode, the component should turn darker and the text inside turns lighter.

What is this “JS Syntax”?

For the most part, we’ve been using CSS syntax for color tokens, which always start with --ds. However, each token also has a JS syntax, which starts with color. These are used in javascript code to represent color tokens.

How do I get the value of a token in JavaScript?

The "JS Syntax" for tokens is used in JS code together with t.getColorToken and t.getComputedColorToken which are special utility functions that allow you to get the value for the CSS variable or the actual computed value of a token, accordingly. Let's take a look at some examples:

1
2
// card-back-section.js
const t = window.TrelloPowerUp.iframe();

const myElement = document.getElementById('my-element');

const infoBgColor = t.getColorToken(
  'color.background.information',
  'lightblue'
);

// var(--ds-background-information, red)
console.log(infoBgColor);

myElement.style.backgroundColor = infoBgColor;

What if I need the actual computed value of a token and not just the CSS variable?

If you need the actual computed value of a token (i.e. the HEX value for a given token), you can use the t.getComputedColorToken function. Just like the t.getColorToken function, it takes a token name in "JS syntax" and a fallback value as arguments, and returns the actual computed value of the token for the current theme. For example:

1
2
// card-back-section.js
const t = window.TrelloPowerUp.iframe();

const myElement = document.getElementById('my-element');

// infoBgColor will be '#082145' for dark mode and '#E9F2FF' for light mode
const infoBgColor = t.getComputedColorToken(
  'color.background.information',
  'lightblue'
);

myElement.style.backgroundColor = infoBgColor;

For more examples on how to use Atlassian Design Tokens in javascript code, refer to the Atlassian design examples page.

The token function you see in the Atlassian design examples page is analogous to the t.getColorToken function in the example above.

Ensuring your Power-Up JS Code is always in sync with Trello's theme

Whether you need to tell your CSS-in-JS library what Trello's current theme is or you simply want to get the computed value for a given token, it is always a good idea to make sure your Power-Up is always in sync with Trello's theme by making use of the t.subscribeToThemeChanges function, this utility function takes a callback as an argument and will return a function that you can call to unsubscribe from theme changes. Here's an example:

1
2
// card-back-section.js
const t = window.TrelloPowerUp.iframe();

const myElement = document.getElementById('my-element');

const unsubThemeChangeListener = t.subscribeToThemeChanges((theme) => {
  console.log('Recalculating color.background.information for theme: ', theme);

  const infoBgColor = t.getComputedColorToken(
    'color.background.information',
    'lightblue'
  );

  myElement.style.backgroundColor = infoBgColor;
});

...

// After we're done listening to theme changes, we can unsubscribe
unsubThemeChangeListener();

Now that's a very basic example, so, for a more realistic one we can use React to look at how to keep our app up to date with Trello's theme:

1
2
// React >=18
import { createContext, useSyncExternalStore, useContext } from 'react';

const t = window.TrelloPowerUp.iframe({
  // Some config ...
});

const ThemeContext = createContext();

const subscribe = (cb) => {
  const unsubThemeChangeListener = t.subscribeToThemeChanges(cb);

  return () => {
    unsubThemeChangeListener();
  };
};

const getSnapshot = () => t.getContext().theme;

const ThemeProvider = ({ children }) => {
  const theme = useSyncExternalStore(subscribe, getSnapshot);

  // By "re-exporting" and consuming the token functions from
  // the theme context, we can ensure that the functions will
  // be re-run whenever the theme changes
  const value = {
    theme,
    getColorToken: t.getColorToken,
    getComputedColorToken: t.getComputedColorToken,
  };

  return <ThemeContext.Provider
value={value}>{children}</ThemeContext.Provider>;
};

const useTheme = () => {
  const context = useContext(ThemeContext);

  if (context === undefined) {
    throw new Error('useTheme must be used within a ThemeProvider');
  }

  return context;
};

const SomeComponent = () => {
  const { theme, getComputedColorToken } = useTheme();

  return (
  <div>
    <h1>
      The computed value for the <code>color.background.information<code> token
in {theme} mode is: {getComputedColorToken('color.background.information',
'lightblue')}
    </h1>
  </div>
  );
};

const App = () => {
  return (
    <ThemeProvider>
      <SomeComponent />
    </ThemeProvider>
  );
};

For React versions 17.X.X and below you can replace the useSyncExternalStore hook with a useState and an useEffect hook:

1
2
// In ThemeProvider
const [theme, setTheme] = useState(t.getContext().theme);

useEffect(() => {
  const unsubThemeChangeListener = t.subscribeToThemeChanges((theme) =>
    setTheme(theme)
  );

  return () => {
    unsubThemeChangeListener();
  };
}, []);

Opting out of loading Atlassian Design Tokens for your Power-Up

If for some reason you don't want to load Atlassian Design Tokens in your Power-Up, you can opt out of loading them by setting the useADSTokens option to false when initializing your Power-Up iframe:

If you need to listen to Trello's theme changes, you can still use the t.subscribeToThemeChanges function as described in Ensuring your Power-Up JS Code is always in sync with Trello's theme.

1
2
const t = window.TrelloPowerUp.iframe({
  useADSTokens: false,
  // Rest of the config ...
});

By opting out of using Atlassian Design Tokens no CSS variables will be loaded into your iframe's document, and so the t.getColorToken and t.getComputedColorToken functions will no longer work.

Rate this page: