Markdown:
Components

DarkToggle

A switch component for toggling between light and dark themes.

Usage

Use standalone. (flat pass-through over Toggle)

Svelte
<DarkToggle {...props} />

Anatomy

The class attribute values represent part names. Other attributes represent their corresponding props.

Svelte
<Toggle {...rest} bind:value={dark} bind:variant bind:element>
  {#if children}
    {children}
  {:else}
    <!-- Default Icon -->
  {/if}
</Toggle>

Props

NameTypeDefaultDescription
darkboolean-Bindable current color theme; defaults to the client's prefers-color-scheme setting
childrenSnippet-Toggle content; receives value, variant, and button element; uses DarkToggle defaults when omitted
leftSnippet-Snippet rendered before the toggle, e.g. a fixed sun icon; receives value, variant, and button element
rightSnippet-Snippet rendered after the toggle, e.g. a fixed moon icon; receives value, variant, and button element
role<enum>"button"button or switch ARIA role exposed by the underlying toggle
ariaLabelstring-Accessible label for the control; defaults to DarkToggle's own label when omitted
attachAttachment-Svelte attachment on the button
elementHTMLButtonElement-Bindable button element
stylingSVSClass-Styling override; uses DarkToggle defaults when omitted
variantSVSVariantNEUTRALBindable variant

Other HTMLButtonAttributes are passed to <button> via rest props; class is merged onto the control.

Styling

To learn more, see Styling.

Variant Management

Same as the Toggle 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 <button> 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 (<svg>): aria-hidden="true".

DarkToggle wraps Toggle and inherits its toggle behavior.

Standards Basis

DarkToggle is built on a native <button> through Toggle, so keyboard and assistive-technology support follows the browser standard for button controls. See the Concepts standards-first guidance for the library's approach.

Exports

Types

TypeScript
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<HTMLButtonElement>;
  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

TypeScript
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 <svelte:head> guard that sets the light / dark class on <html> 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:

Stylesheet
: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;
  }
}
*/

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.

Stylesheet
: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

With Interactive Variant

Preset for Demo
Enter variant as you like