Theme Switcher

A component that allows the user to switch between light and dark mode.

There is no dedicated theme switcher component in Basecoat.

Instead, we offer a short JavaScript <script> block you can insert in the <head> of your page.

Usage

HTML + JavaScript

Step 1: Include the JavaScript script

Insert the following JavaScript block right at the beginning of the <head> your page. We do this instead of using a separate file to ensure the theme is defined before the page loads, avoiding a flash of unstyled or mist-styled content.

<script>
  (() => {
    try {
      const stored = localStorage.getItem('themeMode');
      if (stored ? stored === 'dark'
                  : matchMedia('(prefers-color-scheme: dark)').matches) {
        document.documentElement.classList.add('dark');
      }
    } catch (_) {}

    const apply = dark => {
      document.documentElement.classList.toggle('dark', dark);
      try { localStorage.setItem('themeMode', dark ? 'dark' : 'light'); } catch (_) {}
    };

    document.addEventListener('basecoat:theme', (event) => {
      const mode = event.detail?.mode;
      apply(mode === 'dark' ? true
            : mode === 'light' ? false
            : !document.documentElement.classList.contains('dark'));
    });
  })();
</script>

Step 2: Add your switcher

To change the theme, you need to dispatch a basecoat:theme event:

<button
  type="button"
  aria-label="Toggle dark mode"
  data-tooltip="Toggle dark mode"
  data-side="bottom"
  onclick="document.dispatchEvent(new CustomEvent('basecoat:theme'))"
  class="btn-icon-outline size-8"
>
  <span class="hidden dark:block"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4" /><path d="M12 2v2" /><path d="M12 20v2" /><path d="m4.93 4.93 1.41 1.41" /><path d="m17.66 17.66 1.41 1.41" /><path d="M2 12h2" /><path d="M20 12h2" /><path d="m6.34 17.66-1.41 1.41" /><path d="m19.07 4.93-1.41 1.41" /></svg></span>
  <span class="block dark:hidden"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" /></svg></span>
</button>

JavaScript events

basecoat:theme

By default, the event will toggle the theme, but you can also add a mode to the detail to set the theme explicitly:

<!-- Toggles the theme -->
<button type="button" onclick="document.dispatchEvent(new CustomEvent('basecoat:theme'));">Toggle theme</button>
<!-- Sets the theme to dark -->
<button type="button" onclick="document.dispatchEvent(new CustomEvent('basecoat:theme', { detail: { mode: 'dark' } }));">Set dark theme</button>