diff options
| author | Danilo M. <danix@danix.xyz> | 2026-04-05 08:40:09 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-04-05 08:40:09 +0200 |
| commit | dcf54cad8529526fd7f8d9d4b84b63ccb3fa9630 (patch) | |
| tree | ddd752bb91a333eb7f8f3f7bcf41a4f75c8cd460 /assets/js/theme-toggle.js | |
| parent | b1d3e5315bf92b925a1ca0603c2e476ae8c3d306 (diff) | |
| download | danixxyz-theme-dcf54cad8529526fd7f8d9d4b84b63ccb3fa9630.tar.gz danixxyz-theme-dcf54cad8529526fd7f8d9d4b84b63ccb3fa9630.zip | |
feat: add JavaScript modules (theme toggle, matrix rain, progress tracking, copy-to-clipboard)
Implement all 4 JavaScript modules:
- theme-toggle.js: Theme switching with localStorage persistence
- matrix-rain.js: Animated matrix-style rain effect on canvas
- progress-bar.js: Reading progress tracking during scroll
- copy-code.js: Copy-to-clipboard functionality for code blocks
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Diffstat (limited to 'assets/js/theme-toggle.js')
| -rw-r--r-- | assets/js/theme-toggle.js | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/assets/js/theme-toggle.js b/assets/js/theme-toggle.js new file mode 100644 index 0000000..9f0fd5a --- /dev/null +++ b/assets/js/theme-toggle.js @@ -0,0 +1,83 @@ +// theme-toggle.js +(function() { + const STORAGE_KEY = 'danix-theme'; + const DARK_CLASS = 'theme-dark'; + const LIGHT_CLASS = 'theme-light'; + + // Initialize theme on page load + function init() { + const saved = localStorage.getItem(STORAGE_KEY); + const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; + const isDark = saved === null ? prefersDark : saved === 'dark'; + + applyTheme(isDark ? 'dark' : 'light'); + } + + // Apply theme to document + function applyTheme(theme) { + const html = document.documentElement; + + html.classList.remove(DARK_CLASS, LIGHT_CLASS); + + if (theme === 'dark') { + html.classList.remove(LIGHT_CLASS); + localStorage.setItem(STORAGE_KEY, 'dark'); + } else { + html.classList.add(LIGHT_CLASS); + localStorage.setItem(STORAGE_KEY, 'light'); + } + } + + // Get current theme + function getCurrentTheme() { + return document.documentElement.classList.contains(LIGHT_CLASS) ? 'light' : 'dark'; + } + + // Toggle theme + function toggleTheme() { + const current = getCurrentTheme(); + const next = current === 'dark' ? 'light' : 'dark'; + applyTheme(next); + + // Dispatch custom event for other scripts to listen + window.dispatchEvent(new CustomEvent('theme-changed', { detail: { theme: next } })); + } + + // Setup toggle button + function setupToggleButton() { + const btn = document.getElementById('theme-toggle-btn'); + if (btn) { + btn.addEventListener('click', toggleTheme); + updateToggleButtonLabel(); + + // Listen for theme changes to update button label + window.addEventListener('theme-changed', updateToggleButtonLabel); + } + } + + function updateToggleButtonLabel() { + const btn = document.getElementById('theme-toggle-btn'); + if (btn) { + const current = getCurrentTheme(); + btn.textContent = current === 'dark' ? '☀️ light' : '🌙 dark'; + } + } + + // Initialize on DOMContentLoaded + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', function() { + init(); + setupToggleButton(); + }); + } else { + init(); + setupToggleButton(); + } + + // Expose to global scope for testing + window.ThemeToggle = { + toggle: toggleTheme, + set: applyTheme, + get: getCurrentTheme, + }; +})(); |
