Skip to main content
Urbicon UI
source

ThemeSwitcher

A button that switches the theme between light, dark, and system, and remembers the choice in localStorage. It cycles through the three by default, or toggles between light and dark only.

Playground

Variant
Size
Strategy
<ThemeSwitcher />

01 Examples

Cycle vs. toggle

Default cycles light → dark → system. Pass strategy='toggle' to flip between light and dark only.
<ThemeSwitcher />
<ThemeSwitcher strategy="toggle" />

Variants and sizes

<ThemeSwitcher variant="ghost" size="sm" />
<ThemeSwitcher variant="outlined" size="md" />
<ThemeSwitcher variant="filled" size="lg" />

In a settings panel

An outlined trigger inline with related appearance preferences.

Appearance

Color theme

Reduce motion

<div
  class="bg-surface-elevated border-border-subtle w-full overflow-hidden rounded-2xl border"
>
  <div class="border-border-subtle border-b px-5 py-3">
    <h3 class="text-text-primary text-sm font-semibold">Appearance</h3>
  </div>
  <div class="divide-border-subtle divide-y">
    <div class="flex items-center justify-between px-5 py-3">
      <p class="text-text-primary text-sm font-medium">Color theme</p>
      <ThemeSwitcher variant="outlined" size="sm" />
    </div>
    <div class="flex items-center justify-between px-5 py-3">
      <p class="text-text-primary text-sm font-medium">Reduce motion</p>
      <Toggle size="sm" intent="primary" />
    </div>
  </div>
</div>

02 Customization

Branded trigger

Override the button and icon slots for a gradient brand look.
<ThemeSwitcher
  slotClasses={{
    button:
      'bg-linear-to-r from-violet-500 to-fuchsia-500 text-white hover:from-violet-600 hover:to-fuchsia-600 shadow-md shadow-violet-500/20',
    icon: 'h-5 w-5'
  }}
/>

03 Accessibility

The trigger carries a dynamic aria-label and title that name the active theme ("Light mode" / "Dark mode" / "System theme"). Focusable via Tab, activated with Enter / Space; uses focus-visible: for keyboard-only rings. In system mode the theme follows the OS through color-scheme: light dark, so prefers-color-scheme changes take effect on their own.

04 API Reference

11 props
11 props
Prop
Type
Default
Description

05 Types

Local type definitions used by this component.

6 types
Name
Kind
Category
Used by
Description

06 Installation

Import

import { ThemeSwitcher } from '@urbicon-ui/blocks';

FOUC Prevention

<!-- Add to app.html <head> for flash-free theme loading -->
<script>
  (() => {
    var d = document.documentElement;
    // Storage is not guaranteed usable: reading it throws where it is switched
    // off (a hardened profile, an embedded webview), and an unguarded read
    // aborts the rest of this head script.
    var read = (k) => {
      try {
        return localStorage.getItem(k);
      } catch {
        return null;
      }
    };
    // Only explicit choices set a class; system mode leaves
    // color-scheme: light dark to follow the OS via light-dark().
    var t = read('urbicon-theme');
    if (t === 'dark') d.classList.add('dark');
    else if (t === 'light') d.classList.add('light');
  })();
</script>