# Theme Service

Source: https://lumeo.nativ.sh/docs/services/theme

# Theme Service

Switch between light, dark, and system mode, change color schemes at runtime, and react to theme changes.

## Current State

These values update in real time as you interact with the demos below. This is the live state of the `ThemeService` singleton.

CurrentMode

System

CurrentScheme

zinc

IsDark

false

## Quick Start

Inject `ThemeService` and call `InitializeAsync()` once on first render. This reads the user's persisted preference from `localStorage` and applies it to the page.

@inject ThemeService ThemeService @code { protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { await ThemeService.InitializeAsync(); StateHasChanged(); } } }

`InitializeAsync` requires JS interop, so it must be called in `OnAfterRenderAsync`, not `OnInitialized`.

## Dark Mode

Toggle between light and dark mode, or let the operating system decide. Click the buttons below to see the page theme change instantly.

### Toggle

Switches between light and dark mode. The simplest way to add a theme toggle to your app.

Switch to Dark

IsDark = false

await ThemeService.ToggleModeAsync();

### Set Explicit Mode

Set a specific mode directly. The active mode is highlighted.

Light Dark System

// Set to a specific mode await ThemeService.SetModeAsync(ThemeMode.Light); await ThemeService.SetModeAsync(ThemeMode.Dark); await ThemeService.SetModeAsync(ThemeMode.System);

## Color Schemes

Change the entire color palette at runtime. Click a scheme below to apply it to this page. The active scheme is indicated by a ring.

Zinc

zinc

Blue

blue

Green

green

Rose

rose

Orange

orange

Violet

violet

Amber

amber

Teal

teal

// Change the active color scheme await ThemeService.SetSchemeAsync("blue"); // Read the current scheme string current = ThemeService.CurrentScheme; // e.g. "zinc" // Iterate all available schemes foreach (var scheme in ThemeService.AvailableSchemes) { // scheme.Id => "zinc" // scheme.DisplayName => "Orange" // scheme.PreviewColor => "hsl(14 70% 50%)" }

## Listening for Changes

Subscribe to the `OnThemeChanged` event to update your component whenever the user switches themes. Always unsubscribe in `Dispose()` to prevent memory leaks.

@implements IDisposable @inject ThemeService ThemeService <p>Current mode: @ThemeService.CurrentMode</p> <p>Current scheme: @ThemeService.CurrentScheme</p> <p>Is dark: @ThemeService.IsDark</p> @code { protected override void OnInitialized() { ThemeService.OnThemeChanged += HandleThemeChanged; } private void HandleThemeChanged() { // Properties are already updated when this fires \_ = InvokeAsync(StateHasChanged); } public void Dispose() { ThemeService.OnThemeChanged -= HandleThemeChanged; } }

Always use `await InvokeAsync(StateHasChanged)` inside the handler. The event may fire from a non-UI context, and calling `StateHasChanged()` directly can throw.

## Persisted Preferences

Theme preferences are automatically saved to `localStorage` whenever you call `SetModeAsync`, `ToggleModeAsync`, or `SetSchemeAsync`. When the user returns, `InitializeAsync()` reads the stored values and restores the last-used theme.

localStorage Key

Example Value

Description

lumeo-theme-mode

"dark"

The user's preferred mode (light, dark, or system).

lumeo-theme-scheme

"blue"

The user's preferred color scheme ID.

No server-side storage is required. If no preference is found, the service defaults to `ThemeMode.System` and the `"zinc"` color scheme.

## API Reference

### Properties

Property

Type

Description

CurrentMode

ThemeMode

The active mode: System, Light, or Dark.

CurrentScheme

string

The active color scheme ID (e.g. "zinc", "blue").

IsDark

bool

Whether dark mode is currently active. Reflects the resolved state (including System mode detection).

AvailableSchemes

IReadOnlyList<ThemeSchemeInfo>

Static list of all built-in color schemes with their ID, display name, and preview color.

### Methods

Method

Returns

Description

InitializeAsync()

Task

Reads persisted preferences from localStorage and applies them. Call once in OnAfterRenderAsync.

SetModeAsync(ThemeMode)

Task

Sets the mode to System, Light, or Dark. Persists the choice and fires OnThemeChanged.

ToggleModeAsync()

Task

Toggles between light and dark mode. Persists the choice and fires OnThemeChanged.

SetSchemeAsync(string)

Task

Changes the active color scheme by ID (e.g. "blue"). Persists the choice and fires OnThemeChanged.

### Events

Event

Type

Description

OnThemeChanged

Action?

Fired after any mode or scheme change. Subscribe in OnInitialized, unsubscribe in Dispose().

### ThemeMode Enum

Value

Description

System

Follows the operating system's light/dark preference via `prefers-color-scheme`.

Light

Forces light mode regardless of OS setting.

Dark

Forces dark mode regardless of OS setting.

### ThemeSchemeInfo Record

Property

Type

Description

Id

string

Unique identifier for the scheme (e.g. "zinc", "blue").

DisplayName

string

Human-readable name (e.g. "Orange", "Blue").

PreviewColor

string

CSS color value for preview swatches (e.g. "hsl(14 70% 50%)").
