summaryrefslogtreecommitdiff
path: root/themes/tabi-lean/static/js/themeSwitcher.js
diff options
context:
space:
mode:
Diffstat (limited to 'themes/tabi-lean/static/js/themeSwitcher.js')
-rw-r--r--themes/tabi-lean/static/js/themeSwitcher.js74
1 files changed, 74 insertions, 0 deletions
diff --git a/themes/tabi-lean/static/js/themeSwitcher.js b/themes/tabi-lean/static/js/themeSwitcher.js
new file mode 100644
index 0000000..c5ddf95
--- /dev/null
+++ b/themes/tabi-lean/static/js/themeSwitcher.js
@@ -0,0 +1,74 @@
+// Get the theme switcher button elements.
+const themeSwitcher = document.querySelector('.theme-switcher');
+const themeResetter = document.querySelector('.theme-resetter');
+const defaultTheme = document.documentElement.getAttribute('data-default-theme');
+
+function getSystemThemePreference() {
+ return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
+}
+
+// Determine the initial theme.
+let currentTheme =
+ localStorage.getItem('theme') ||
+ document.documentElement.getAttribute('data-theme') ||
+ getSystemThemePreference();
+
+function setTheme(theme, saveToLocalStorage = false) {
+ document.documentElement.setAttribute('data-theme', theme);
+ currentTheme = theme;
+ themeSwitcher.setAttribute('aria-pressed', theme === 'dark');
+
+ if (saveToLocalStorage) {
+ localStorage.setItem('theme', theme);
+ themeResetter.classList.add('has-custom-theme');
+ } else {
+ localStorage.removeItem('theme');
+ themeResetter.classList.remove('has-custom-theme');
+ }
+
+ // Dispatch a custom event for comment systems.
+ window.dispatchEvent(new CustomEvent('themeChanged', { detail: { theme } }));
+}
+
+function resetTheme() {
+ setTheme(defaultTheme || getSystemThemePreference());
+}
+
+// Function to switch between dark and light themes.
+function switchTheme() {
+ setTheme(currentTheme === 'dark' ? 'light' : 'dark', true);
+}
+
+// Initialize the theme switcher button.
+themeSwitcher.addEventListener('click', switchTheme);
+themeResetter.addEventListener('click', resetTheme);
+
+// Update the theme based on system preference if necessary.
+if (!defaultTheme) {
+ window
+ .matchMedia('(prefers-color-scheme: dark)')
+ .addEventListener('change', (e) => {
+ setTheme(e.matches ? 'dark' : 'light');
+ });
+}
+
+// Set initial ARIA attribute and custom theme class.
+themeSwitcher.setAttribute('aria-pressed', currentTheme === 'dark');
+if (localStorage.getItem('theme')) {
+ themeResetter.classList.add('has-custom-theme');
+}
+
+// Function to handle keydown event on theme toggler buttons.
+function handleThemeTogglerKeydown(event) {
+ if (event.key === 'Enter' || event.key === ' ') {
+ event.preventDefault();
+ if (event.target === themeSwitcher) {
+ switchTheme();
+ } else if (event.target === themeResetter) {
+ resetTheme();
+ }
+ }
+}
+
+themeSwitcher.addEventListener('keydown', handleThemeTogglerKeydown);
+themeResetter.addEventListener('keydown', handleThemeTogglerKeydown);