# DarkToggle
A switch component for toggling between light and dark themes.
## Usage
Use standalone. (flat pass-through over `Toggle`)
```svelte
```
## Anatomy
The `class` attribute values represent part names. Other attributes represent their corresponding props.
```svelte
{#if children}
{children}
{:else}
{/if}
```
## Props
| Name | Type | Default | Description |
|---|---|---|---|
| `dark` | `boolean` | - | Bindable current color theme; defaults to the client's `prefers-color-scheme` setting |
| `children` | `Snippet` | - | Toggle content; receives value, variant, and button element; uses DarkToggle defaults when omitted |
| `left` | `Snippet` | - | Snippet rendered before the toggle, e.g. a fixed sun icon; receives value, variant, and button element |
| `right` | `Snippet` | - | Snippet rendered after the toggle, e.g. a fixed moon icon; receives value, variant, and button element |
| `role` | `` | `"button"` | `button` or `switch` ARIA role exposed by the underlying toggle |
| `ariaLabel` | `string` | - | Accessible label for the control; defaults to DarkToggle's own label when omitted |
| `attach` | `Attachment` | - | Svelte attachment on the button |
| `element` | `HTMLButtonElement` | - | Bindable button element |
| `styling` | `SVSClass` | - | Styling override; uses DarkToggle defaults when omitted |
| `variant` | `SVSVariant` | `NEUTRAL` | Bindable variant |
Other `HTMLButtonAttributes` are passed to `` via rest props; `class` is merged onto the control.
## Styling
To learn more, see [Styling](/docs/styling).
### Variant Management
Same as the [Toggle](/docs/toggle#styling) component.
### Default Class Name
`svs-dark-toggle`
Internal dependent components combine the parent class with their own default class names, resulting in multiple classes (e.g., `svs-dark-toggle svs-toggle`).
## Accessibility
### ARIA Roles and Attributes
The component applies these automatically:
- Toggle button (`main` `` from Toggle): `aria-pressed` reflecting the dark/on state, plus `aria-label` from the built-in default `"Toggle theme color"` unless `ariaLabel` overrides it.
- Icon (``): `aria-hidden="true"`.
DarkToggle wraps [Toggle](/docs/toggle) and inherits its toggle behavior.
### Standards Basis
DarkToggle is built on a native `` through Toggle, so keyboard and assistive-technology support follows the browser standard for button controls. See the [Concepts standards-first guidance](/docs/concepts) for the library's approach.
## Exports
### Types
```ts
interface DarkToggleProps extends Omit<
HTMLButtonAttributes,
"children" | "value" | "type" | "role" | "aria-pressed" | "aria-checked" | "aria-label"
> {
dark?: boolean; // bindable (prefers-color-scheme)
children?: Snippet<[boolean, string, HTMLButtonElement | undefined]>; // Snippet<[value,variant,element]>
left?: Snippet<[boolean, string, HTMLButtonElement | undefined]>; // Snippet<[value,variant,element]>
right?: Snippet<[boolean, string, HTMLButtonElement | undefined]>; // Snippet<[value,variant,element]>
role?: "button" | "switch"; // ("button")
ariaLabel?: string;
attach?: Attachment;
element?: HTMLButtonElement; // bindable
styling?: SVSClass;
variant?: SVSVariant; // bindable (VARIANT.NEUTRAL)
// children, styling, and ariaLabel use DarkToggle defaults when omitted.
}
type DarkToggleReqdProps = never;
type DarkToggleBindProps = "dark" | "variant" | "element";
```
### Others
```ts
const THEME = { LIGHT: "light", DARK: "dark" } as const;
// Adds theme value to the class of the root element.
// If `window` is undefined, nothing is done.
function setThemeToRoot(theme?: string);
// Programmatic control of the page-wide (singleton) theme.
// These update the shared theme/DOM and the `dark` prop of every mounted instance.
function setTheme(dark: boolean); // set the page-wide theme
function toggleTheme(); // flip the page-wide theme
function isDark(): boolean; // whether the page-wide theme is currently dark
```
## Feature Details
### Switching Custom Property Values
Clicking on this component (toggling `dark`) will switch the values of custom properties detect from the CSS.
### Initial Theme Guard
DarkToggle emits an SSR-only `` guard that sets the `light` / `dark` class on `` before first paint, based on `prefers-color-scheme`. This is effective only when DarkToggle is in the initial server-rendered tree. Under a strict Content-Security-Policy, the inline script may be blocked; use an app-level blocking script with an appropriate nonce in that case.
### Automatic Theme Property Detection
Custom properties for each theme are automatically detected when written as follows:
**CSS**
```css
:root {
/* For Light Theme */
--color-background: #fff;
--color-text: #000;
--svs-brightness: 0.7;
--custom-property: ...; /* Ignored unless using specified prefixes */
font-family: ...; /* Can be defined alongside other properties */
}
@media (prefers-color-scheme: dark) {
:root {
/* For Dark Theme */
--color-background: #000;
--color-text: #fff;
--svs-brightness: 1.3;
}
}
/* Explicit color scheme definition is also possible
@media (prefers-color-scheme: light) {
:root {
--color-background: #fff;
--color-text: #000;
--svs-brightness: 0.7;
}
}
*/
```
**TailwindCSS**
```css
@import "tailwindcss";
@theme {
/* For Light Theme */
--color-background: #fff;
--color-text: #000;
--svs-brightness: 0.7;
--custom-property: ...; /* Ignored unless using specified prefixes */
--default-mono-font-family: ...; /* Can be defined alongside other properties */
}
@media (prefers-color-scheme: dark) {
:root {
/* For Dark Theme */
--color-background: #000;
--color-text: #fff;
--svs-brightness: 1.3;
}
}
```
Custom properties starts with `--color-` or `--svs-` declared in the `:root` pseudo-element will be automatically read. As a reminder, when configuring a light theme with `:root`, it should consist only of `:root` selectors, not including other selectors. Also, custom properties for a single theme should be described in a single declaration block.
Custom properties that start with `--color-` or `--svs-` declared in the `:root` pseudo-element will be automatically detected. Note that when configuring a light theme with `:root`, it should consist only of `:root` selectors and not include other selectors. Additionally, custom properties for a single theme should be defined in a single declaration block.
```css
:root {
--color-background: #fff;
}
/* This will not work as expected
:root {
--color-text: #000;
}
*/
```
## Examples
The example code uses Tailwind CSS along with `SVSClass`.
### Basic
**Code**
```svelte src=DarkToggleBasic.svelte
```
### With Interactive Variant
**Code**
```svelte src=DarkTogglePract.svelte
{#snippet children(value: boolean)}
{#if value}
{:else}
{/if}
{/snippet}
```