1
0
Files
breadcrumb-the-shire/web/js/components/app-theme-toggle.js
2026-02-04 23:31:53 +01:00

58 lines
1.6 KiB
JavaScript

const setTheme = (theme) => {
const root = document.documentElement;
root.dataset.theme = theme;
};
const setIcon = (button, theme) => {
const icon = button.querySelector('i');
if (!icon) return;
icon.classList.remove('bi-sun-fill', 'bi-moon-stars-fill');
icon.classList.add(theme === 'dark' ? 'bi-moon-stars-fill' : 'bi-sun-fill');
};
const updateTheme = async (button, theme) => {
const url = button.dataset.themeUrl;
const csrfKey = button.dataset.csrfKey;
const csrfToken = button.dataset.csrfToken;
if (!url || !csrfKey || !csrfToken) {
return true;
}
const body = new URLSearchParams({ theme, [csrfKey]: csrfToken });
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json',
'X-Requested-With': 'fetch'
},
body
});
return response.ok;
};
const initThemeToggle = () => {
const button = document.querySelector('[data-theme-toggle]');
if (!button) return;
const root = document.documentElement;
const getCurrent = () => (root.dataset.theme === 'dark' ? 'dark' : 'light');
setIcon(button, getCurrent());
button.addEventListener('click', async () => {
const current = getCurrent();
const next = current === 'dark' ? 'light' : 'dark';
setTheme(next);
setIcon(button, next);
const ok = await updateTheme(button, next);
if (!ok) {
setTheme(current);
setIcon(button, current);
}
});
};
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initThemeToggle);
} else {
initThemeToggle();
}