elbe/ui

Light and dark themes with system preference detection, a persisted choice, and a configurable dark class.

Setup

The service is available out of the box with sensible defaults. Register provideTheme only when you want to override them.

import { provideTheme } from '@elbe/ui/theme';

export const appConfig: ApplicationConfig = {
  providers: [
    provideTheme({
      darkClass: 'dark',
      lightColor: '#ffffff',
      darkColor: '#0a0a0a',
    }),
  ],
};

Configuration

Every option is optional and falls back to the default shown above.

  • darkClass: class toggled on <html> when the dark theme is active. Defaults to 'dark'.
  • lightColor: content of the theme-color meta tag in the light theme. Defaults to '#ffffff'.
  • darkColor: content of the theme-color meta tag in the dark theme. Defaults to '#0a0a0a'.

Usage

Inject ElbTheme anywhere. isDark is a signal, so templates and computed values update when the theme changes.

import { ElbTheme } from '@elbe/ui/theme';

private readonly theme = inject(ElbTheme);

// Toggle between light and dark.
this.theme.toggle();

// Or set an explicit theme, including the system modes.
this.theme.setTheme('system-dark');

// Read the resolved theme.
readonly isDark = this.theme.isDark;

System preference

When no explicit choice has been made, the service follows the operating system and reacts to changes. Choosing 'light' or 'dark' persists that choice in localStorage, while 'system-light' and 'system-dark' keep following the system.

Theme color

The service updates an existing theme-color meta tag on every change so the browser chrome matches the resolved theme. Add one to your index.html:

<meta name="theme-color" content="#ffffff" />