Spaces:
Running
Running
| class LanguageSwitcher extends HTMLElement { | |
| connectedCallback() { | |
| this.attachShadow({ mode: 'open' }); | |
| this.shadowRoot.innerHTML = ` | |
| <style> | |
| :host { | |
| display: inline-block; | |
| position: relative; | |
| } | |
| .language-btn { | |
| display: flex; | |
| align-items: center; | |
| gap: 0.5rem; | |
| background: rgba(255, 255, 255, 0.1); | |
| border: 1px solid rgba(255, 255, 255, 0.2); | |
| border-radius: 9999px; | |
| padding: 0.5rem 1rem; | |
| color: white; | |
| cursor: pointer; | |
| transition: all 0.3s ease; | |
| } | |
| .language-btn:hover { | |
| background: rgba(255, 255, 255, 0.2); | |
| } | |
| .dropdown { | |
| position: absolute; | |
| right: 0; | |
| top: calc(100% + 0.5rem); | |
| background: rgba(30, 41, 59, 0.95); | |
| border-radius: 0.75rem; | |
| padding: 0.5rem 0; | |
| min-width: 160px; | |
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); | |
| backdrop-filter: blur(16px); | |
| -webkit-backdrop-filter: blur(16px); | |
| opacity: 0; | |
| visibility: hidden; | |
| transform: translateY(10px); | |
| transition: all 0.3s ease; | |
| z-index: 100; | |
| } | |
| :host([open]) .dropdown { | |
| opacity: 1; | |
| visibility: visible; | |
| transform: translateY(0); | |
| } | |
| .language-option { | |
| display: flex; | |
| align-items: center; | |
| gap: 0.75rem; | |
| padding: 0.75rem 1.5rem; | |
| color: rgba(255, 255, 255, 0.8); | |
| cursor: pointer; | |
| transition: all 0.2s ease; | |
| } | |
| .language-option:hover { | |
| background: rgba(79, 70, 229, 0.2); | |
| color: white; | |
| } | |
| .language-flag { | |
| width: 20px; | |
| height: 20px; | |
| border-radius: 50%; | |
| object-fit: cover; | |
| } | |
| </style> | |
| <div class="language-btn" id="toggleBtn"> | |
| <img src="/flags/${this.getAttribute('current')}.svg" class="language-flag" alt="Current language"> | |
| <span>${this.getAttribute('current').toUpperCase()}</span> | |
| <i data-feather="chevron-down" width="16" height="16"></i> | |
| </div> | |
| <div class="dropdown"> | |
| <div class="language-option" data-lang="en"> | |
| <img src="/flags/en.svg" class="language-flag" alt="English"> | |
| <span>English</span> | |
| </div> | |
| <div class="language-option" data-lang="de"> | |
| <img src="/flags/de.svg" class="language-flag" alt="Deutsch"> | |
| <span>Deutsch</span> | |
| </div> | |
| <div class="language-option" data-lang="fa"> | |
| <img src="/flags/fa.svg" class="language-flag" alt="فارسی"> | |
| <span>فارسی</span> | |
| </div> | |
| </div> | |
| `; | |
| const toggleBtn = this.shadowRoot.getElementById('toggleBtn'); | |
| toggleBtn.addEventListener('click', () => { | |
| this.toggleAttribute('open'); | |
| }); | |
| const options = this.shadowRoot.querySelectorAll('.language-option'); | |
| options.forEach(option => { | |
| option.addEventListener('click', () => { | |
| const lang = option.getAttribute('data-lang'); | |
| this.setAttribute('current', lang); | |
| this.removeAttribute('open'); | |
| this.dispatchEvent(new CustomEvent('language-change', { | |
| detail: { language: lang }, | |
| bubbles: true, | |
| composed: true | |
| })); | |
| }); | |
| }); | |
| } | |
| } | |
| customElements.define('language-switcher', LanguageSwitcher); |