Expand commentComment on line R9Resolved

Migrating tokens

Overview

Halstack 16 introduces a new token-based theming system composed of core and alias tokens. In Halstack 15, theming relied on a JSON-based opinionatedTheme / advancedTheme object passed to the application wrapper. This migration page explains how to transition from the old theme object to the new CSS-token architecture.

What has changed

AreaHalstack 15Halstack 16
Theming mechanismTheme object (JSON) passed to providerCSS variables (core + alias tokens)
CustomizationopinionatedTheme / advancedThemeOverride core tokens (safe) and component tokens (advanced, upcoming)
Runtime updatesThemeProvider re-renders componentsCSS vars update instantly without rerenders
Naming consistencyNo token taxonomy, per-component stylesCore → Alias → Component (3-layer architecture)

Impact on adopters

Applications may need adjustments in the following areas:

  • Removal of old theme shape (advancedTheme / opinionatedTheme).
  • Migrating color, spacing, and typography overrides to CSS tokens.
  • Replacing any custom component overrides that referenced theme object values.
  • Updating global styles to rely on CSS variables instead of hardcoded values.
  • Refactoring prop values to rely on alias tokens instead of hardcoded values.

New token architecture

Core tokens

Core tokens define the raw, non-contextual values of the design system. They map directly to CSS variables. You can find a list with all the core tokens in this page.

Alias tokens

Alias tokens map raw core values to semantic meanings such as background, foreground, or border tokens. They provide a shared vocabulary across components. You can find a list with all the alias tokens in this page.

Component tokens (upcoming)

Component tokens will be introduced progressively. They will reference alias tokens and control component-level styling.

Migrating from the old theming strategy

Style overrides

Old JSON-based color overrides must be replaced by CSS variable assignments.

Previous version:

const customTheme = {
  button: {
    "baseColor": "#2b470b",
    "primaryFontColor": "#ffffff",
  }
}
// ...
return (
  <HalstackProvider theme={customTheme}>
    <DxcButton label="Theme test" />
  </HalstackProvider>
);

New version:

const opinionatedTheme = {
  "--color-primary-700": "#2b470b",
  "--color-absolutes-white": "#ffffff",
}
// ...
return (
  <HalstackProvider opinionatedTheme={opinionatedTheme}>
    <DxcButton label="Theme test" />
  </HalstackProvider>
);

This can be applied to colors, fonts, spacings and borders. However, keep in mind that, for now, only core tokens can be overwritten and they affect all the components which are wrapped within the HalstackProvider. Note that the former theme prop has been renamed to opinionatedTheme.

Apply themes dynamically

To support dynamic theme switching (for example, toggling between light and dark mode), you can store the theme object in a useState hook and update it in response to user actions. When the state changes, theHalstackProvider receives the updated CSS variables and the UI updates instantly without rerendering components manually.

const App = () => {
  // Light palette example
  const lightPalette = {
    "--color-primary-50": "#d3f0b4",
    "--color-primary-100": "#a2df5e",
    "--color-primary-200": "#77c81f",
    "--color-primary-300": "#68ad1b",
    "--color-primary-400": "#579317",
    "--color-primary-500": "#487813",
    "--color-primary-600": "#39600f",
    "--color-primary-700": "#2b470b",
    "--color-primary-800": "#1c2f07",
    "--color-primary-900": "#0d1503",

    "--color-secondary-50": "#fff9d6",
    "--color-secondary-100": "#ffed99",
    "--color-secondary-200": "#ffe066",
    "--color-secondary-300": "#e6c84d",
    "--color-secondary-400": "#ccad33",
    "--color-secondary-500": "#b39426",
    "--color-secondary-600": "#8f741f",
    "--color-secondary-700": "#6b5517",
    "--color-secondary-800": "#47370f",
    "--color-secondary-900": "#241b08",
  };

  // Dark palette example
  const darkPalette = {
    "--color-primary-50": "#ffd6e7",
    "--color-primary-100": "#ff99c2",
    "--color-primary-200": "#ff66a3",
    "--color-primary-300": "#e05584",
    "--color-primary-400": "#c5446d",
    "--color-primary-500": "#a83659",
    "--color-primary-600": "#872b47",
    "--color-primary-700": "#661f35",
    "--color-primary-800": "#441423",
    "--color-primary-900": "#220a12",

    "--color-secondary-50": "#f3e6db",
    "--color-secondary-100": "#e2c7a9",
    "--color-secondary-200": "#d1a577",
    "--color-secondary-300": "#b88252",
    "--color-secondary-400": "#99673f",
    "--color-secondary-500": "#7a5232",
    "--color-secondary-600": "#5c3f26",
    "--color-secondary-700": "#3e2b19",
    "--color-secondary-800": "#21170d",
    "--color-secondary-900": "#100b06",
  };

  const [theme, setTheme] = useState("light");

  const toggleTheme = () => {
    setTheme((prev) => {
      const newTheme = prev === "light" ? "dark" : "light";
      console.log("Toggling theme", newTheme);
      return newTheme;
    });
  };

  return (
    <HalstackProvider opinionatedTheme={theme === "light" ? lightPalette : darkPalette}>
      <DxcButton label="Toggle theme" onClick={toggleTheme} />
    </HalstackProvider>
  );
};

Any component wrapped by HalstackProvider will immediately reflect the new token values.

Removing legacy theming APIs

Ensure you remove:

  • All usage of the old opinionatedTheme and advancedTheme.
  • Theme props passed to DxcApplication or similar wrappers.
  • Any custom wrappers relying on the old theme shape.