ThemeToggle
Import
Section titled “Import”import { ThemeToggle } from '@delightstack/components';Basic Usage
Section titled “Basic Usage”View code
<ThemeToggle />Examples
Section titled “Examples”Bindable Theme State
Section titled “Bindable Theme State”Bind to the theme prop to read or control the current theme preference.
<script> import { ThemeToggle } from '@delightstack/components';
let theme = $state<'light' | 'dark' | 'auto'>('auto');</script>
<ThemeToggle bind:theme /><p>Current theme: {theme}</p>Two-State Toggle (No Auto)
Section titled “Two-State Toggle (No Auto)”Disable the system/auto option to cycle only between light and dark.
View code
<ThemeToggle disable_auto />With a Text Label
Section titled “With a Text Label”Set show_label to display the current mode name (“Light” / “Dark” / “Auto”) beside the icon. Pass label to override the text with your own.
View code
<ThemeToggle show_label /><ThemeToggle show_label label="Appearance" />Detecting Effective Dark Mode
Section titled “Detecting Effective Dark Mode”Bind to is_dark to get the resolved dark state (taking system preference into account when theme is 'auto').
<script> import { ThemeToggle } from '@delightstack/components';
let theme = $state<'light' | 'dark' | 'auto'>('auto'); let is_dark = $state(false);</script>
<ThemeToggle bind:theme bind:is_dark />
{#if is_dark} <p>Dark mode is active</p>{:else} <p>Light mode is active</p>{/if}In a Header / Navbar
Section titled “In a Header / Navbar”Use a smaller size to fit in navigation bars.
<script> import { ThemeToggle } from '@delightstack/components';</script>
<header> <nav><!-- nav items --></nav> <ThemeToggle size="0" /></header>Reacting to Changes
Section titled “Reacting to Changes”Use the onchange callback to run logic when the theme changes.
<ThemeToggle onchange={(newTheme) => { console.log('Theme changed to:', newTheme); }}/>Custom Tooltip
Section titled “Custom Tooltip”Override the default tooltip text.
View code
<ThemeToggle tooltip="Change appearance" />| Prop | Type | Default | Description |
|---|---|---|---|
theme | 'light' | 'dark' | 'auto' | 'auto' | Current theme preference ($bindable()) |
is_dark | boolean | false | Computed resolved dark state ($bindable(), read-only). True when effective appearance is dark. |
size | '0' | '1' | '2' | '1' | Component size ('0' = 18px icon, '1' = 24px icon, '2' = 32px icon) |
disable_auto | boolean | false | Hide the auto/system option (two-state toggle only) |
show_label | boolean | false | Show a text label beside the icon (“Light” / “Dark” / “Auto”) |
label | string | undefined | Custom label text override. Falls back to the current mode name when show_label is set. |
tooltip | string | '' | Override the default tooltip text. Defaults to the aria-label value. |
id | string | undefined | Element ID |
class | string | '' | Additional CSS classes |
onchange | (theme: 'light' | 'dark' | 'auto') => void | undefined | Called when the theme changes |
Events
Section titled “Events”| Event | Detail | Description |
|---|---|---|
onchange | 'light' | 'dark' | 'auto' | Fires after cycling to a new theme state |
Theme Cycle Order
Section titled “Theme Cycle Order”| Mode | Cycle |
|---|---|
| Three-state (default) | light -> dark -> auto -> light |
Two-state (disable_auto) | light -> dark -> light |
Theme Application
Section titled “Theme Application”When the theme changes, the component:
- Sets
document.documentElement.style.colorSchemeto'light'or'dark'based on the effective dark state. - Saves the preference to
localStorageunder the key'delightstack:theme'. - Watches for system preference changes via
matchMedia('(prefers-color-scheme: dark)')and updatesis_darkreactively when theme is'auto'.
Anti-Flash Script
Section titled “Anti-Flash Script”To prevent a flash of wrong theme on page load, add the following inline script to your HTML <head> (runs synchronously before the body renders):
<head> <script> (function() { try { var saved = localStorage.getItem('delightstack:theme'); var prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; var theme = (saved === 'light' || saved === 'dark' || saved === 'auto') ? saved : 'auto'; var is_dark = theme === 'dark' || (theme === 'auto' && prefersDark); document.documentElement.style.colorScheme = is_dark ? 'dark' : 'light'; } catch(e) {} })(); </script></head>Accessibility
Section titled “Accessibility”- Renders as a
<button>element with a descriptivearia-label(e.g., “Theme: dark”, “Theme: auto (system preference)”) - Keyboard toggle via Space and Enter keys
- Focus ring on
:focus-visible - Tooltip via
{@attach tooltip()}showing the current state - The SVG icon uses
aria-hidden="true"since the button’saria-labelconveys the meaning - When theme is
'auto', a small “A” indicator appears on the button