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
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.
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.
Set Explicit Mode
Set a specific mode directly. The active mode is highlighted.
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.
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.
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%)"). |