aboutsummaryrefslogtreecommitdiffstats
path: root/pydis_site/static/js/base/themes.js
diff options
context:
space:
mode:
authorGravatar hedy <[email protected]>2024-01-05 20:55:34 +0800
committerGravatar hedy <[email protected]>2024-01-05 20:55:34 +0800
commit7559cb72da7e8b84dd81b33d54ba6c6abd156fd7 (patch)
tree00e8f955e33c0e91f4a465782a98829a08fa9824 /pydis_site/static/js/base/themes.js
parentDark: Revert some not so decent whitespace changes from previous PR (diff)
Dark: Name JS & CSS files according to their content
We have the CSS for the navbar in base.css, the relevant files only contain code for the theme toggle, so they should be named as such. If we ever implement CSS variables per-theme, they could then be done in `themes.css`.
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);
+ });
+});