One theme across Apex products

Every Apex product resolves its colors, font and mode in the same order, and reads the same shared sources: the --apx-* CSS tokens, a theme registry every product on the page shares, and, with an add-on, the page's Ignite UI theme. State your brand once in one of them and every product on the page follows it. This page is the map; each product's own pages have the detail.

Key takeaways

  • One order everywhere: an option you pass, then the product's own CSS, then the --apx-* tokens, then a named theme, then Ignite UI, then the built-in defaults.
  • One set of tokens: declare --apx-* on :root and every product reads them, including the font, and in ApexCharts, ApexGantt and ApexGrid a corner radius factor.
  • One registry: a theme registered with ApexCharts.registerTheme, ApexStock.registerTheme or registerTheme from apex-commons can be named from every product that takes a theme name.
  • One import per product for Ignite UI: each product has its own add-on, and none of them needs an extra licence key.
  • After a theme change that does not render anything, call refreshTokens() where the product has it, and re-render where it does not.

The order every product follows

Each color, the font and the mode resolve in one order, highest first. A higher source wins wherever it sets a value; a lower one fills only what nothing above it set.

RankSourceExamples
1An option you passcolors on a chart, nodePalette on a Sankey, fontFamily, theme.mode
2The product's own CSS--apex-tree-*, --apex-sankey-*, --apex-gantt-*, --apexstock-*, --apexmaps-* and --ag-* variables; your rules for a chart's tooltip and menus
3The family --apx-* tokens--apx-accent, --apx-fore, --apx-series-1, --apx-font-family
4A named theme or paletteA theme from the family registry, a product's built-in theme or preset, an explicit theme.palette
5Ignite UIThe --ig-* tokens, with the product's add-on loaded
6Built-in defaultsEach product's own palette and light mode

"An option you pass" means passed, not "different from the default": an option set to its own default value still wins. ApexGrid themes through CSS only and has no named themes, so for a grid the order is your --ag-* tokens, then --apx-*, then Ignite UI, then its built-in values, with theme="dark" or theme="light" on the host fixing the mode.

The --apx-* tokens

Declare the tokens once, usually on :root. Custom properties inherit, so a token set on a container reaches only the products inside it.

:root {
  --apx-accent: #0f766e;
  --apx-fore: #1f2937;
  --apx-grid: #e5e7eb;
  --apx-surface: #ffffff;
  --apx-series-1: #0f766e;
  --apx-series-2: #d97706;
  --apx-series-3: #2563eb;
  --apx-font-family: 'Inter', system-ui, sans-serif;
  --apx-radius-factor: 0.5;
}
TokenRole
--apx-accentThe color that means interactive or selected
--apx-foreText, and anything that must stay legible on the surface
--apx-gridHairlines: borders, gridlines, connectors
--apx-surfaceThe plane content sits on
--apx-series-1 to --apx-series-NAn ordered categorical palette, read up to its first gap
--apx-font-familyThe font, wherever you did not pass one
--apx-radius-factorScales the product's built-in corner radii: 1 (or unset) changes nothing and 0 squares the corners. Radii you set in options are not scaled. Read by ApexCharts, ApexGantt and ApexGrid

Which part of each product takes which token is on that product's theming page: ApexCharts, ApexGrid, ApexMaps, ApexTree, ApexSankey, ApexGantt and ApexStock. Each product also has a switch that stops it reading the tokens, such as theme.tokens: false on a chart or tokens="off" on a grid.

The shared theme registry

ApexCharts.registerTheme, ApexStock.registerTheme and registerTheme from apex-commons write to one registry that every Apex product on the page shares. Register a theme once and name it from any product:

import ApexCharts from 'apexcharts'

ApexCharts.registerTheme('brand', {
  mode: 'light',
  tokens: {
    accent: '#0f766e',
    fore: '#1f2937',
    grid: '#e5e7eb',
    surface: '#ffffff',
    series: ['#0f766e', '#d97706', '#2563eb'],
  },
})
ProductHow to name itWhat it takes
ApexChartstheme: { name: 'brand' }The whole definition: mode, palette, tokens, monochrome, accessibility
ApexStocktheme: { preset: 'brand' }, or setThemePreset('brand')mode, the accent, surface, fore and grid tokens, and the candle colors up and down when the entry has them
ApexSankeytheme: 'brand'tokens.series for the nodes, tokens.fore for the labels, tokens.grid for the node borders
ApexTreetheme: 'brand'The tokens
ApexGantttheme: 'brand'The tokens, and mode: 'dark' for the dark colors
ApexMapsAs a palette name, such as theme: { palette: 'brand' }tokens.series
ApexGridNo named themesUse the --apx-* tokens
  • A named theme ranks below the --apx-* tokens, so a token on :root wins over the registry.
  • ApexStock.registerTheme writes to the same registry, so registering a name there replaces an entry another product registered under it. Register each name once.
  • ApexSankey.registerTheme is a separate, Sankey-only store for diagram fields such as canvasStyle. Under the same name both apply, and the Sankey's own fields win where both set a value. A family theme's tokens.surface does not paint the Sankey canvas: canvasStyle does.
  • ApexCharts.unregisterTheme(name) removes a theme for every product. ApexStock and ApexSankey have no unregisterTheme.

Register a brand theme across Apex products measures each of these in a browser, including the failures that raise no error.

Ignite UI: one import per product

Each product follows an Ignite UI theme on the page through its own add-on. The add-ons need no extra licence key. Without its add-on, a product ignores the --ig-* tokens, with no error. The --apx-* tokens and the registry work either way.

ProductAdd-onSinceGuide
ApexChartsimport 'apexcharts/features/ignite-ui'8.8.0Using with Ignite UI
ApexGridimport 'apex-grid/ignite-ui'4.0.0Using with Ignite UI
ApexMapsimport 'apexmaps/ignite-ui'1.3.0Using with Ignite UI
ApexTreeimport 'apextree/ignite-ui'2.3.0Using with Ignite UI
ApexSankeyimport 'apexsankey/ignite-ui'1.14.0Using with Ignite UI
ApexGanttimport 'apexgantt/ignite-ui'3.21.0Using with Ignite UI
ApexStockimport 'apexstock/ignite-ui'0.6.0Using with Ignite UI

Import the add-on of every product on the page, before the first render. Some of them overlap (the tree, Sankey, Gantt and maps add-ons register one shared adapter, and in a bundler apexstock/ignite-ui loads the ApexCharts add-on itself), but an ApexCharts chart reads only its own add-on, and a map takes its basemap greys only from apexmaps/ignite-ui, so one import per product is the rule that always holds. With several tree, Sankey or Gantt add-ons on the page, the newest package's copy is the one they all read.

Ignite UI ranks just above the built-in defaults, so anything you already set, including the --apx-* tokens and a named theme, still wins. A product's designSystem: false (theme: { designSystem: false } on a chart, a map or a stock chart; design-system="off" on a grid) turns the Ignite UI layer off for that one instance and keeps the --apx-* tokens.

After a theme change

Products read the theme when they render. A stylesheet swap, such as an Ignite UI light to dark switch, or a class that changes the --apx-* tokens, renders nothing, so tell each product:

ProductAfter a change
ApexChartschart.refreshTokens()
ApexTreetree.refreshTokens()
ApexSankeysankey.refreshTokens()
ApexGanttgantt.render(), or gantt.update({})
ApexStockstock.update({})
ApexMapsmap.updateOptions({})
ApexGridNothing to call: it themes in CSS and follows the change live
const link = document.getElementById('ig-theme')
link.addEventListener(
  'load',
  () => {
    chart.refreshTokens()
    sankey.refreshTokens()
    gantt.update({})
  },
  { once: true }
)
link.href = '/themes/material-dark.css'

refreshTokens() re-reads the product's own CSS variables, the --apx-* tokens, the named theme and the Ignite UI theme, and repaints. A tree or Sankey keeps its nodes and view where they are. Call it as well when an add-on loads after the first render.

Frequently asked questions

Do I need Ignite UI to share one theme?

No. The --apx-* tokens and the theme registry are part of every product and need no other library. Ignite UI is one more source, read only when its add-on is loaded and its theme is on the page.

Why does my Sankey canvas stay transparent under a dark named theme?

Because a family theme's tokens.surface does not paint it. Register a SankeyTheme with a canvasStyle under the same name with ApexSankey.registerTheme; both registrations then apply. See Register a brand theme across Apex products.

Why did my chart lose its palette after I registered a stock preset?

ApexStock.registerTheme writes to the shared registry, and a preset under a name the chart already uses replaces the chart's entry, palette and tokens.series included. Register the name once, or give the stock preset its own name.