Creating Custom Themes

You can start using Arcade with the theme we provide but at some point you might want to apply custom values to the design tokens and align them with your brand. To solve that, Arcade has a Node CLI for creating new themes and theme fragments.

First, you need to create a file where and use our theming JS API to define new theming tokens. For instance, we can do it in src/themes/definition.js file.

Adding themes

addTheme function lets you create themes containing all token values. In case you pass just some values, all other design token values will be inherited from the Arcade default theme during build time.

With this example, we have defined a theme that will only change the foregroundNeutral token value. All other values will be used from the default theme, so you can use this theme as your main theme passed to the Arcade provider.

Adding theme fragments

addThemeFragment function lets you create themes containing just a subset of design tokens. All other values will be inherited from the parent theme in the browser runtime, which means you shouldn't be using theme fragments as your main theme.

This approach is especially helpful when you want to customize just a handful of values for a specific component. For instance, you can create a Twitter theme fragment to then create a TwitterButton component.

Keeping other values inherited in runtime makes it easier to combine themes together. If you have two themes used in your product, you don't have to build a Twitter theme for each of them since theme fragment can be used in both.

CLI

Now that we have a file with a theme and theme fragment added, we can use Arcade CLI to generate these themes. Let's add an NPM script to call the CLI to your package.json:

Running yarn build:themes or npm run build:themes now will take your added theme definitions from src/themes/definition.js file and compile them into the src/themes folder. For each theme and theme fragment script will create a folder with their name. It will contain a css variables file with all token values and a React component to use in the application.

Note that all fragments will be saved to a fragments folder inside themes folder.

Using in the application

With the themes built, you can now import them in your code. We can start by picking the main theme for the application:

Our product now uses a custom theme and has a new foregroundNeutral token value available. It still uses other tokens from the default Arcade theme, which means Button component uses purple color for its background. Let's create a TwitterButton component with a different button background color. Every theme we generate is not just an object with values, but a React component that will apply the theme for its children.

This concept is called Scoped theming, and you can learn more about it in a separate section.

Typescript support

Both addTheme and addThemeFragment are fully typed using Typescript, including the theme definition format. You can write your theme definitions in Typescript, compile your project and call the CLI then:

By default, Arcade generates jsx components for themes when using CLI. You can generate tsx components with --target argument.

Tokens format

Theme is represented with an object that has token types as keys. Each token type contains an object of token objects with their values.

Most of the tokens you define in the theme object and some of them will be generated automatically based on other values. You can find more about the result css output for tokens in the Design Tokens section.

Color

Format:

Available token names:

  • All onBackground color tokens are generated automatically.
  • hexDark value is optional in case you're not using dark mode or if the values are same in both modes
  • black and white tokens should preserve their values in both light and dark mode

Unit

Format:

Available token names:

  • x1 - x10 unit tokens will be auto generated based on your base token px value.

Font family

Format:

Available token names:

Two font family types let you differentiate between regular text and larger headings but still keeping the product styles consistent.

Font weight

Format:

Available token names:

Font

Format:

Available token names:

  • fontWeightToken refers to the font weight token names
  • fontFamilyToken refers to the font family token names
  • responsive is an optional field to make the typography responsive based on the viewport size
  • responsive values refer to the font token names and are mobile first. In our format example it means that token is using title1 for s-m and display3 for l+.

Shadow

Format:

Available token names:

  • Uses an array of values to apply multiple shadows to the same element
  • colorToken is referring to a color token name

Duration

Format:

Available token names:

  • Used for animation durations

Easing

Format:

Available token names: