2.2 KiB
2.2 KiB
Theme Toggle
A dark/light mode toggle button that persists the user's preference to localStorage and applies it instantly without a page reload.
Usage
<ThemeToggle />
Place it anywhere in your layout — typically in a header or toolbar:
<header class="flex h-14 items-center px-4">
<h1 class="text-sm font-medium">My App</h1>
<div class="ml-auto">
<ThemeToggle />
</div>
</header>
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
Class |
string? |
— | Additional CSS classes appended to the button |
How It Works
- Toggle button — renders a
<button>with moon (light mode) and sun (dark mode) SVG icons - Click handler —
darkmode.jstoggles thedarkclass on<html>and persists tolocalStorage - Icon sync — shows the appropriate icon based on the current theme
- FOUC prevention — a synchronous inline script in
App.razorcheckslocalStoragebefore first paint
Required Setup in App.razor
Add this script in the <head> before any stylesheets:
<script>
(function () {
try {
if (localStorage.getItem('theme') === 'dark')
document.documentElement.classList.add('dark');
} catch (e) { }
})();
</script>
And initialize the module in the <body>:
<script type="module">
import { init as initDarkMode } from '/_content/Enciphered.Blazor.UIComponents/js/darkmode.js';
initDarkMode();
</script>
CSS Custom Variant
The library uses Tailwind CSS v4's custom variant for dark mode:
@custom-variant dark (&:where(.dark, .dark *));
This means dark mode is class-based (.dark on <html>) rather than media-query-based, giving users manual control.
Design Tokens
All color tokens have light and dark variants defined in the library's Styles/app.css:
:root {
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
/* ... */
}
.dark {
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
/* ... */
}
When the dark class is toggled, all components automatically switch to dark colors through these CSS custom properties.