theme.js 1.5 KB

1234567891011121314151617181920212223242526272829
  1. /* Apply the palette before paint; keep the control and browser chrome in sync. */
  2. (() => {
  3. const systemTheme = matchMedia('(prefers-color-scheme: dark)');
  4. let selectedTheme;
  5. try { selectedTheme = localStorage.getItem('zke-theme'); } catch { /* Use system preference. */ }
  6. const isTheme = value => value === 'light' || value === 'dark';
  7. function applyTheme(theme) {
  8. document.documentElement.dataset.theme = theme;
  9. document.querySelector('meta[name="theme-color"]').content = theme === 'dark' ? '#171a18' : '#f4f4ef';
  10. const button = document.querySelector('#themeButton');
  11. if (!button) return;
  12. const label = theme === 'dark' ? 'Включить светлую тему' : 'Включить тёмную тему';
  13. button.setAttribute('aria-label', label);
  14. button.setAttribute('title', label);
  15. button.setAttribute('aria-pressed', String(theme === 'dark'));
  16. }
  17. applyTheme(isTheme(selectedTheme) ? selectedTheme : systemTheme.matches ? 'dark' : 'light');
  18. document.addEventListener('DOMContentLoaded', () => {
  19. applyTheme(document.documentElement.dataset.theme);
  20. document.querySelector('#themeButton').addEventListener('click', () => {
  21. selectedTheme = document.documentElement.dataset.theme === 'dark' ? 'light' : 'dark';
  22. applyTheme(selectedTheme);
  23. try { localStorage.setItem('zke-theme', selectedTheme); } catch { /* Theme remains active for this session. */ }
  24. });
  25. });
  26. systemTheme.addEventListener('change', event => {
  27. if (!isTheme(selectedTheme)) applyTheme(event.matches ? 'dark' : 'light');
  28. });
  29. })();