Dark mode

GlacialWisp already everything in place to facilitate dark mode using css variables based on the users device preferences. However if you wish to be able to toggle dark mode, you must add two scripts to your templates to enable it.

Enable dynamic switching

To enable dynamic switching between light and dark mode, you must add this to the head of your templates.

function getTheme() {
  if (localStorage.getItem("userTheme") != null) {
    return localStorage.getItem("userTheme");
  }
  if (window.matchMedia) {
    if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
      return 'dark';
    } else if (window.matchMedia('(prefers-color-scheme: light)').matches) {
      return 'light';
    }
  }
  // fallback
  return 'light';
}
window.getTheme = getTheme;

function changeTheme() {
  document.documentElement.setAttribute(
    'data-theme',
    window.getTheme() == 'dark' ? 'dark' : 'light'
  );
}
window.changeTheme = changeTheme;

function setTheme(theme) {
  if (theme == 'dark') {
    localStorage.setItem("userTheme", "dark");
  } else if (theme == 'light') {
    localStorage.setItem("userTheme", "light");
  }
  window.changeTheme();
}
window.setTheme = setTheme;

(function() {
  setTheme(getTheme());
})();

Add dark mode toggle

To allow for the user to switch between dark and light mode without leaving the app, you must add the dark mode toggle to your templates, just before the closing body tag.

'use strict';
window.addEventListener('load', () => {
  let themeSwitchWrapper = document.getElementById('theme-switch-wrapper');
  let themeSwitch = document.createElement('label');
  themeSwitch.classList.add('form-switch');
  themeSwitch.innerHTML = `
  <input type="checkbox">
  <i class="form-icon"></i><span id="theme-switch-label">Dark mode</span>
  `;
  themeSwitchWrapper.appendChild(themeSwitch);
  let checkbox = themeSwitchWrapper.querySelector('input[type="checkbox"]');
  // set default
  if (window.getTheme() == 'dark') {
    checkbox.checked = true;
  } else {
    checkbox.checked = false;
  }
  checkbox.addEventListener('click', (e) => {
    window.setTheme(e.target.checked ? 'dark' : 'light');
  });
  window
    .matchMedia('(prefers-color-scheme: dark)')
    .addEventListener('change', (e) => {
      if (localStorage.getItem('userTheme') == null) {
        if (e.matches) {
          window.setTheme('dark');
        } else {
          window.setTheme('light');
        }
      }
    });
  });

Finally you must also place the the theme switch wrapper somewhere in your app.

<div id="theme-switch-wrapper">
  <noscript>
    Changing color scheme dynamically requires JavaScript.
  </noscript>
</div>

Note, the scripts provided here are to preferably be added inline to prevent flickering when loading.