PageSourceSearch

https://jamstack.org/js/color-theme.js

js jamstack.org collected 2026-10-01 07:16:24 UTC 2,626 bytes, 97 lines download raw bytes

1const htmlElement = document.documentElement;
2const colorThemeSelector = document.querySelector(
3  "[data-color-theme-selector]"
4);
5const colorThemeSelectorInput = colorThemeSelector.querySelector("select");
6const colorThemeSelectorInputIcon = colorThemeSelector.querySelector('.color-theme-selector-wrapper-icon');
7const colorThemeSelectorInputIconSrc = colorThemeSelectorInputIcon.querySelector('use');
8const storedTheme = localStorage.theme;
9
10function setInputIcon(type) {
11  if(type === 'dark') {
12    colorThemeSelectorInputIconSrc.setAttribute('xlink:href', '#icon-color-theme-dark');
13  } else if(type === 'light') {
14    colorThemeSelectorInputIconSrc.setAttribute('xlink:href', '#icon-color-theme-light');
15  } else {
16    colorThemeSelectorInputIconSrc.setAttribute('xlink:href', '#icon-color-theme-system');
17  } 
18}
19
20function setInputState(storedTheme) {
21  if (!!storedTheme) {
22    colorThemeSelectorInput.querySelector(
23      `[value="${storedTheme}"]`
24    ).selected = true;
25
26    setInputIcon(storedTheme);
27
28    htmlElement.classList.add(storedTheme);
29  }
30}
31
32function displayThemeSelector() {
33  colorThemeSelector.style.visibility = 'visible';
34}
35
36function toggleThemeClass(type) {
37  if (type === "dark") {
38    if (htmlElement.classList.contains("light")) {
39      htmlElement.classList.remove("light");
40    }
41
42    htmlElement.classList.add("dark");
43  } else if (type == "light") {
44    if (htmlElement.classList.contains("dark")) {
45      htmlElement.classList.remove("dark");
46    }
47
48    htmlElement.classList.add("light");
49  } else {
50    // "System" mode - blanket remove all theme classes from the root <html> element
51    if (htmlElement.classList.contains("dark")) {
52      htmlElement.classList.remove("dark");
53    }
54
55    if (htmlElement.classList.contains("light")) {
56      htmlElement.classList.remove("light");
57    }
58
59    // If the current system color scheme preference is dark, apply the .dark class
60    if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
61      htmlElement.classList.add("dark");
62    }
63  }
64}
65
66function updateTheme(type) {
67  switch (type) {
68    case "dark":
69      toggleThemeClass("dark");
70
71      setInputIcon('dark');
72
73      localStorage.theme = "dark";
74      break;
75    case "light":
76      toggleThemeClass("light");
77
78      setInputIcon('light');
79
80      localStorage.theme = "light";
81      break;
82    default:
83      toggleThemeClass("system");
84
85      setInputIcon('system');
86
87      localStorage.removeItem("theme");
88      break;
89  }
90}
91
92setInputState(storedTheme);
93displayThemeSelector();
94
95colorThemeSelectorInput.addEventListener("change", (e) => {
96  updateTheme(e.target.value);
97});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.