98 lines
2.2 KiB
Markdown
98 lines
2.2 KiB
Markdown
# 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
|
|
|
|
```razor
|
|
<ThemeToggle />
|
|
```
|
|
|
|
Place it anywhere in your layout — typically in a header or toolbar:
|
|
|
|
```razor
|
|
<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
|
|
|
|
1. **Toggle button** — renders a `<button>` with moon (light mode) and sun (dark mode) SVG icons
|
|
2. **Click handler** — `darkmode.js` toggles the `dark` class on `<html>` and persists to `localStorage`
|
|
3. **Icon sync** — shows the appropriate icon based on the current theme
|
|
4. **FOUC prevention** — a synchronous inline script in `App.razor` checks `localStorage` before first paint
|
|
|
|
### Required Setup in `App.razor`
|
|
|
|
Add this script in the `<head>` before any stylesheets:
|
|
|
|
```html
|
|
<script>
|
|
(function () {
|
|
try {
|
|
if (localStorage.getItem('theme') === 'dark')
|
|
document.documentElement.classList.add('dark');
|
|
} catch (e) { }
|
|
})();
|
|
</script>
|
|
```
|
|
|
|
And initialize the module in the `<body>`:
|
|
|
|
```html
|
|
<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:
|
|
|
|
```css
|
|
@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`:
|
|
|
|
```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.
|