Spaces:
Running
Running
| class ThemeToggle extends HTMLElement { | |
| connectedCallback() { | |
| this.attachShadow({ mode: 'open' }); | |
| this.shadowRoot.innerHTML = ` | |
| <style> | |
| .toggle-container { | |
| display: inline-flex; | |
| align-items: center; | |
| cursor: pointer; | |
| } | |
| .toggle { | |
| position: relative; | |
| width: 44px; | |
| height: 24px; | |
| background-color: #e2e8f0; | |
| border-radius: 12px; | |
| margin: 0 8px; | |
| transition: background-color 0.3s; | |
| } | |
| .toggle.dark { | |
| background-color: #4a5568; | |
| } | |
| .slider { | |
| position: absolute; | |
| width: 20px; | |
| height: 20px; | |
| background-color: white; | |
| border-radius: 50%; | |
| top: 2px; | |
| left: 2px; | |
| transition: transform 0.3s; | |
| } | |
| .dark .slider { | |
| transform: translateX(20px); | |
| } | |
| .icon { | |
| width: 16px; | |
| height: 16px; | |
| } | |
| .light-icon { | |
| color: #f59e0b; | |
| } | |
| .dark-icon { | |
| color: #a0aec0; | |
| } | |
| </style> | |
| <div class="toggle-container"> | |
| <i data-feather="sun" class="icon light-icon"></i> | |
| <div class="toggle"> | |
| <div class="slider"></div> | |
| </div> | |
| <i data-feather="moon" class="icon dark-icon"></i> | |
| </div> | |
| `; | |
| const toggle = this.shadowRoot.querySelector('.toggle'); | |
| const slider = this.shadowRoot.querySelector('.slider'); | |
| // Check for saved theme preference or use system preference | |
| const savedTheme = localStorage.getItem('darkMode'); | |
| const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches; | |
| if (savedTheme === null ? systemDark : savedTheme === 'true') { | |
| document.documentElement.classList.add('dark'); | |
| toggle.classList.add('dark'); | |
| slider.classList.add('dark'); | |
| } | |
| // Add click event listener | |
| this.shadowRoot.querySelector('.toggle-container').addEventListener('click', () => { | |
| const isDark = document.documentElement.classList.toggle('dark'); | |
| toggle.classList.toggle('dark'); | |
| slider.classList.toggle('dark'); | |
| localStorage.setItem('darkMode', isDark); | |
| // Dispatch event for other components to listen to | |
| document.dispatchEvent(new CustomEvent('themeChanged', { detail: { isDark } })); | |
| }); | |
| // Initialize feather icons | |
| feather.replace(); | |
| } | |
| } | |
| customElements.define('theme-toggle', ThemeToggle); |