summaryrefslogtreecommitdiff
path: root/sysret.org/themes/tabi-lean/static/js/themeSwitcher.js
blob: c5ddf952af46bf813b27cddcdb68ee0870969970 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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);