github.com/gemaraproj/gemara@v0.23.0

docs/assets/js/theme-toggle.js raw

 1/**
 2 * Theme Toggle Functionality
 3 * Handles dark/light mode switching with system preference detection and localStorage persistence
 4 */
 5
 6(function() {
 7  'use strict';
 8
 9  // Get theme toggle button and icon elements
10  const themeToggle = document.getElementById('theme-toggle');
11  const themeIcon = document.getElementById('theme-icon');
12
13  // Function to get system preference
14  function getSystemPreference() {
15    return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
16      ? 'dark'
17      : 'light';
18  }
19
20  // Function to get stored theme or system preference
21  function getTheme() {
22    const stored = localStorage.getItem('theme');
23    if (stored === 'dark' || stored === 'light') {
24      return stored;
25    }
26    return getSystemPreference();
27  }
28
29  // Function to set theme
30  function setTheme(theme) {
31    const root = document.documentElement;
32    if (theme === 'dark') {
33      root.setAttribute('data-theme', 'dark');
34      localStorage.setItem('theme', 'dark');
35      if (themeIcon) {
36        themeIcon.className = 'fa-solid fa-sun';
37      }
38    } else {
39      root.removeAttribute('data-theme');
40      localStorage.setItem('theme', 'light');
41      if (themeIcon) {
42        themeIcon.className = 'fa-solid fa-moon';
43      }
44    }
45  }
46
47  // Function to toggle theme
48  function toggleTheme() {
49    const currentTheme = document.documentElement.getAttribute('data-theme');
50    const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
51    setTheme(newTheme);
52  }
53
54  // Initialize theme on page load
55  function initTheme() {
56    const theme = getTheme();
57    setTheme(theme);
58  }
59
60  // Set initial theme immediately to prevent flash
61  initTheme();
62
63  // Add click event listener to toggle button
64  if (themeToggle) {
65    themeToggle.addEventListener('click', toggleTheme);
66  }
67
68  // Listen for system preference changes
69  if (window.matchMedia) {
70    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
71    mediaQuery.addEventListener('change', function(e) {
72      // Only update if user hasn't manually set a preference
73      if (!localStorage.getItem('theme')) {
74        setTheme(e.matches ? 'dark' : 'light');
75      }
76    });
77  }
78})();
79