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.js94
1 files changed, 94 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..46dba7b9
--- /dev/null
+++ b/pydis_site/static/js/base/themes.js
@@ -0,0 +1,94 @@
+"use strict";
+
+const defaultTheme = "light";
+const stylesheet = document.getElementById("bulma-css");
+const htmlTag = document.querySelector("html");
+
+// We include the dark stylesheet in base template to include the rel="preload",
+// but remove the actual rel="stylesheet" element here because we won't need it.
+document.getElementById("bulma-css-dark").remove();
+
+// 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":
+ stylesheet.href = "/static/css/bulma.css";
+ break;
+ case "dark":
+ stylesheet.href = "/static/css/dark_bulma.css";
+ break;
+ }
+
+ htmlTag.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;
+ }
+}
+
+let theme;
+const systemPrefersDark = window.matchMedia("(prefers-color-scheme: dark)");
+
+if (systemPrefersDark.matches)
+ theme = getCurrentTheme("dark");
+else
+ theme = getCurrentTheme();
+
+setStyleSheets(theme);
+
+// Executed when the page has finished loading.
+document.addEventListener("DOMContentLoaded", () => {
+ 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 = htmlTag.getAttribute("data-theme") === "light" ? "dark" : "light";
+ localStorage.setItem("theme", newTheme);
+ setStyleSheets(newTheme);
+ toggleThemeSwitch(newTheme);
+ });
+});