summaryrefslogtreecommitdiff
path: root/site/themes/sine/static/js/switch-theme.js
blob: 433ace1fa7ed5b8538fc053a8b5ce03ca23e20e1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// Theme switcher

// Themes and icons

const themes = {
  "melatonin-dark": { icon: " ☽", name: "Melatonin Dark" },
  "melatonin-light": { icon: " ✧", name: "Melatonin Light" },
  // "oxocarbon-dark": { icon: " ☾", name: "Oxocarbon Dark" },
  // "oxocarbon-light": { icon: " ✧", name: "Oxocarbon Light" },
};

const themeOrder = Object.keys(themes);

// Default themes
const defaultDarkTheme = "melatonin-dark";
const defaultLightTheme = "melatonin-light";

// checks whether there is already a theme and if not, sets it to the user's default theme.
function calculateTheme({ localStorageTheme, systemSettingDark }) {
  if (localStorageTheme !== null && themeOrder.includes(localStorageTheme)) {
    return localStorageTheme;
  }

  if (systemSettingDark.matches) {
    return defaultDarkTheme;
  }

  return defaultLightTheme;
}

// Get next theme in list
function getNextTheme(current) {
  const index = themeOrder.indexOf(current);
  return themeOrder[(index + 1) % themeOrder.length];
}

// Utility function to update the button text and aria-label.
function updateButton(button, theme) {
  const nextTheme = getNextTheme(theme);

  button.innerText = themes[theme].icon;
  button.setAttribute(
    "aria-label",
    `Switch to ${themes[nextTheme].name} theme`
  );
}

// Utility function to update the theme setting on the html tag
function applyTheme(theme) {
  document.documentElement.setAttribute("data-theme", theme);
  localStorage.setItem("theme", theme);
}

// 1. Grab what we need from the DOM and system settings on page load
const button = document.querySelector("[data-theme-switcher]");
const localStorageTheme = localStorage.getItem("theme");
const systemSettingDark = window.matchMedia("(prefers-color-scheme: dark)");

// 2. Work out the current site settings
let currentTheme = calculateTheme({ localStorageTheme, systemSettingDark });

// 3. Update the theme setting and button text accoridng to current settings
updateButton( button, currentTheme);
applyTheme( currentTheme );

// 4. Add an event listener to toggle the theme
button.addEventListener("click", (event) => {
  const newTheme = getNextTheme(currentTheme);

  localStorage.setItem("theme", newTheme);
  updateButton( button, newTheme);
  applyTheme( newTheme );

  // console.log(themeOrder)

  currentTheme = newTheme;
});