templates/vitekit/__/vite-frontend-starter-main/public/data-theme.js
2026-04-12 21:03:18 +03:00

97 lines
2.5 KiB
JavaScript

const DATA_THEME = {
body_attribute_key: 'data-theme',
storage_key: 'data-theme',
value_default: 'light',
value_dark: 'dark',
getCurrentTheme: () => localStorage.getItem(DATA_THEME.storage_key) || document.documentElement.getAttribute(DATA_THEME.body_attribute_key),
setTheme: (theme = null, storage = true) => {
if (theme !== DATA_THEME.value_default && theme !== DATA_THEME.value_dark) {
theme = DATA_THEME.value_default;
}
document.documentElement.setAttribute(DATA_THEME.body_attribute_key, theme);
if (storage) {
localStorage.setItem(DATA_THEME.storage_key, theme);
}
DATA_THEME.dataSrcDark();
return true;
},
toggleTheme: () => {
let theme = DATA_THEME.getCurrentTheme();
if (theme === DATA_THEME.value_default) {
theme = DATA_THEME.value_dark;
} else {
theme = DATA_THEME.value_default;
}
DATA_THEME.setTheme(theme);
return true;
},
dataSrcDark: () => {
const currentTheme = DATA_THEME.getCurrentTheme();
document.querySelectorAll('[data-src-dark]').forEach((item) => {
if (!item.srcLight) {
item.srcLight = item.src;
}
const { srcLight } = item;
const srcDark = item.srcDark || item.getAttribute('data-src-dark') || srcLight;
item.src = DATA_THEME.value_dark === currentTheme ? srcDark : srcLight;
});
return true;
},
};
const initialTheme = DATA_THEME.getCurrentTheme();
if (initialTheme) {
DATA_THEME.setTheme(initialTheme);
} else {
let theme = DATA_THEME.value_default;
if (window.matchMedia) {
theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? DATA_THEME.value_dark : DATA_THEME.value_default;
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (event) => {
const t = event.matches ? DATA_THEME.value_dark : DATA_THEME.value_default;
DATA_THEME.setTheme(t, false);
});
}
DATA_THEME.setTheme(theme, false);
}
document.addEventListener('click', (event) => {
const themeSwitcher = event.target.closest('[data-theme-set]');
const themeToggler = event.target.closest('[data-theme-toggle]');
if (!themeSwitcher && !themeToggler) {
return false;
}
event.preventDefault();
if (themeSwitcher) {
const theme = themeSwitcher.getAttribute('data-theme-set');
DATA_THEME.setTheme(theme);
} else if (themeToggler) {
DATA_THEME.toggleTheme();
}
});
document.addEventListener('DOMContentLoaded', () => {
DATA_THEME.dataSrcDark();
});