Skip to content
LyEve UI v0.60.1

Theming

ThemeToggle

A small icon button that cycles Soft Light, Soft Dark and the operating system's own setting. Persists the choice to localStorage under the lyeve-theme key. Drop it in a navbar and you're done.

Basic

Three states, not two

The default cycle is light, dark, system. The icon shows the state the control is in rather than the one it is heading for, because with three states the action no longer implies the state, and the accessible name carries both.

system is stored under its own name rather than by clearing the key. A cleared key is indistinguishable from a visitor who has never chosen, and those are not the same fact: one has asked to follow the desktop and should keep following it when the desktop changes at dusk.

A surface that must not offer it passes an explicit order and gets the two-state control back with no other change.

Wiring it yourself

If you'd rather build a custom toggle (a labeled menu item, a Switch, a toolbar tab), import the same helpers the component uses:

import {
  getThemePreference,
  setThemePreference,
  nextThemePreference,
  resolveTheme,
  systemTheme,
  watchSystemTheme,
  type ThemePreference,
} from '@lyeve-labs/ui-kit';

setThemePreference('system');   // follow the desktop
getThemePreference();           // 'light' | 'dark' | 'system'
resolveTheme('system');         // what that paints right now
systemTheme();                  // 'dark' | 'light'
nextThemePreference('light');   // the next state in the cycle

// Repaint when the desktop flips, for a reader who chose 'system'.
const stop = watchSystemTheme();

// The two-state helpers still work and are unchanged.
// getTheme(), setTheme('dark'), toggleTheme()

Anti-FOUC boot

The component reads the theme on mount, so the very first paint may flash the wrong palette. Pair it with the inline boot script. See installation for the drop-in snippet, or use:

import { themeBootScript } from '@lyeve-labs/ui-kit';

// Render this inside an inline <script> in your <head>.
const html = '<' + 'script>' + themeBootScript() + '</' + 'script>';

API

PropTypeDefaultDescription
order readonly ThemePreference[] no defaultWhich preferences to offer, in the order the button cycles. Defaults to light, dark, system. Pass ['light', 'dark'] for a surface that must not offer system.
class string no defaultExtra classes on the button.