Skip to content
Components, switch product

Themes and dark mode

A theme is a set of design tokens applied under a data-theme attribute. Put the attribute on <html> for the whole page, or on any element to theme only what’s inside it.

The components are light by default. Dark mode is opt-in:

data-themeResult
NoneLight.
"dark"Always dark.
"auto"Follows the system setting, prefers-color-scheme.
<html data-theme="auto">
…
</html>

The default stays light even on a dark system, so adding the components to a page never changes its colors on its own. The dark values of each token are in Design tokens.

Clay is a warm theme with earthy neutrals and terracotta as the primary color. Load its stylesheet after the main one:

import '@golemui/gui-components/index.css';
import '@golemui/gui-components/themes/clay.css';

Then apply it with one of its three values:

data-themeResult
"clay"Clay, always light.
"clay-dark"Clay, always dark.
"clay-auto"Clay, following the system setting.

Clay sits in the golemui.theme cascade layer, above the tokens, so it applies whichever stylesheet loads first.

A theme sets the tokens it changes under its own data-theme values. Follow the same split as the built-in themes, three values for one theme, so each page can pick light, dark or the system setting.

  1. Set the light values under all three values. The dark variant starts from them and changes only what differs:

    [data-theme='sunset'],
    [data-theme='sunset-dark'],
    [data-theme='sunset-auto'] {
    --gui-intent-primary: #ea580c;
    --gui-intent-primary-hover: #c2410c;
    --gui-intent-primary-active: #9a3412;
    --gui-border-focus: #f97316;
    --gui-bg-default: #fff7ed;
    --gui-border-default: #fdba74;
    }
  2. Set the dark values twice: always under -dark, and under -auto on a dark system:

    [data-theme='sunset-dark'] {
    --gui-bg-default: #1c1210;
    --gui-bg-surface: #271a16;
    --gui-text-default: #fff7ed;
    --gui-border-default: #9a3412;
    }
    @media (prefers-color-scheme: dark) {
    [data-theme='sunset-auto'] {
    --gui-bg-default: #1c1210;
    --gui-bg-surface: #271a16;
    --gui-text-default: #fff7ed;
    --gui-border-default: #9a3412;
    }
    }

    To write the dark values once, put them in a Sass mixin or a shared custom property block and include it in both places, as the built-in themes do.

  3. Apply it like any other theme:

    <section data-theme="sunset-auto">
    <gui-textinput label="Email"></gui-textinput>
    </section>

Prefer the semantic tokens (--gui-bg-*, --gui-text-*, --gui-intent-*) to the primitive ramps: the components read the semantic ones, so a theme that sets them doesn’t depend on which ramp step each one uses.

data-theme works on any element, so one page can mix themes:

<main>
<gui-textinput label="Name"></gui-textinput>
</main>
<aside data-theme="clay-dark">
<gui-textinput label="Notes"></gui-textinput>
</aside>

To switch at runtime, change the attribute:

document.documentElement.dataset.theme = 'dark';