aboutsummaryrefslogtreecommitdiffstats
path: root/pydis_site/static/js/base/themes.js
diff options
context:
space:
mode:
Diffstat (limited to 'pydis_site/static/js/base/themes.js')
-rw-r--r--pydis_site/static/js/base/themes.js91
1 files changed, 91 insertions, 0 deletions
diff --git a/pydis_site/static/js/base/themes.js b/pydis_site/static/js/base/themes.js
new file mode 100644
index 00000000..2a57cad4
--- /dev/null
+++ b/pydis_site/static/js/base/themes.js
@@ -0,0 +1,91 @@
+"use strict";
+
+const defaultTheme = "light";
+const lightStylesheet = document.getElementById("bulma-css");
+const darkStylesheet = document.getElementById("bulma-css-dark");
+
+// Get saved preference for the site in local storage, optionally accounting
+// for system preference used when a page loads.
+function getCurrentTheme(systemPrefers) {
+ const theme = localStorage.getItem("theme");
+
+ if (theme !== null && theme !== "")
+ return theme;
+
+ if (systemPrefers !== undefined)
+ return systemPrefers;
+
+ return defaultTheme;
+}
+
+// Disable & enable the correct CSS stylesheets based on chosen theme.
+function setStyleSheets(newTheme) {
+ switch (newTheme) {
+ case "light":
+ lightStylesheet.disabled = false;
+ darkStylesheet.disabled = true;
+ break;
+ case "dark":
+ lightStylesheet.disabled = true;
+ darkStylesheet.disabled = false;
+ break;
+ }
+
+ document.querySelector("html").setAttribute("data-theme", newTheme);
+}
+
+// Reflect chosen theme on the switch toggle.
+function toggleThemeSwitch(newTheme) {
+ const switchToggle = document.getElementById("theme-switch");
+ const knob = document.getElementById("theme-knob");
+
+ switch (newTheme) {
+ case "light":
+ knob.classList.remove("dark");
+ knob.classList.add("light");
+ setTimeout(function() {
+ switchToggle.classList.remove("dark");
+ switchToggle.classList.add("light");
+ }, 100);
+ break;
+ case "dark":
+ knob.classList.remove("light");
+ knob.classList.add("dark");
+ setTimeout(function() {
+ switchToggle.classList.remove("light");
+ switchToggle.classList.add("dark");
+ }, 100);
+ break;
+ }
+}
+
+// Executed when the page has finished loading.
+document.addEventListener("DOMContentLoaded", () => {
+ let theme;
+ const systemPrefersDark = window.matchMedia("(prefers-color-scheme: dark)");
+
+ if (systemPrefersDark.matches)
+ theme = getCurrentTheme("dark");
+ else
+ theme = getCurrentTheme();
+
+ setStyleSheets(theme);
+ toggleThemeSwitch(theme);
+
+ systemPrefersDark.addEventListener("change", ({matches: isDark}) => {
+ const newTheme = isDark ? "dark" : "light";
+ // Let the new system preference take precedence over toggle preference
+ // on page reloads.
+ localStorage.removeItem("theme");
+ setStyleSheets(newTheme);
+ toggleThemeSwitch(newTheme);
+ })
+
+ const switchToggle = document.getElementById("theme-switch");
+ switchToggle.addEventListener("click", () => {
+ const newTheme = getCurrentTheme() === "light" ? "dark" : "light";
+ localStorage.setItem("theme", newTheme);
+ setStyleSheets(newTheme);
+ toggleThemeSwitch(newTheme);
+ });
+});