| class CustomModelSelector extends HTMLElement { | |
| connectedCallback() { | |
| this.attachShadow({ mode: 'open' }); | |
| this.render(); | |
| this.attachEvents(); | |
| } | |
| render() { | |
| this.shadowRoot.innerHTML = ` | |
| <style> | |
| :host { | |
| display: block; | |
| } | |
| .selector { | |
| position: relative; | |
| } | |
| .selector-btn { | |
| padding: 0.75rem 1.25rem; | |
| background: rgba(30, 41, 59, 0.6); | |
| border: 1px solid rgba(148, 163, 184, 0.2); | |
| border-radius: 12px; | |
| color: #e2e8f0; | |
| font-size: 0.875rem; | |
| cursor: pointer; | |
| transition: all 0.2s ease; | |
| display: flex; | |
| align-items: center; | |
| gap: 0.5rem; | |
| } | |
| .selector-btn:hover { | |
| background: rgba(30, 41, 59, 0.8); | |
| border-color: #0ea5e9; | |
| } | |
| .dropdown { | |
| position: absolute; | |
| top: 100%; | |
| right: 0; | |
| margin-top: 0.5rem; | |
| min-width: 280px; | |
| background: rgba(15, 23, 42, 0.95); | |
| backdrop-filter: blur(20px); | |
| border: 1px solid rgba(148, 163, 184, 0.2); | |
| border-radius: 16px; | |
| padding: 1rem; | |
| opacity: 0; | |
| visibility: hidden; | |
| transform: translateY(-10px); | |
| transition: all 0.2s ease; | |
| z-index: 100; | |
| } | |
| .dropdown.open { | |
| opacity: 1; | |
| visibility: visible; | |
| transform: translateY(0); | |
| } | |
| .dropdown-section { | |
| margin-bottom: 1rem; | |
| } | |
| .dropdown-section:last-child { | |
| margin-bottom: 0; | |
| } | |
| .section-title { | |
| font-size: 0.75rem; | |
| color: #64748b; | |
| text-transform: uppercase; | |
| letter-spacing: 0.05em; | |
| margin-bottom: 0.5rem; | |
| padding: 0 0.5rem; | |
| } | |
| .model-option { | |
| padding: 0.625rem 0.75rem; | |
| border-radius: 10px; | |
| cursor: pointer; | |
| transition: all 0.2s ease; | |
| display: flex; | |
| align-items: center; | |
| gap: 0.75rem; | |
| } | |
| .model-option:hover { | |
| background: rgba(30, 41, 59, 0.6); | |
| } | |
| .model-option.active { | |
| background: rgba(14, 165, 233, 0.1); | |
| } | |
| .model-dot { | |
| width: 8px; | |
| height: 8px; | |
| border-radius: 50%; | |
| background: #10b981; | |
| } | |
| .model-info { | |
| flex: 1; | |
| } | |
| .model-name { | |
| font-size: 0.875rem; | |
| color: #e2e8f0; | |
| } | |
| .model-desc { | |
| font-size: 0.75rem; | |
| color: #64748b; | |
| } | |
| .res-tag { | |
| padding: 0.25rem 0.5rem; | |
| background: rgba(14, 165, 233, 0.2); | |
| border-radius: 6px; | |
| font-size: 0.625rem; | |
| color: #7dd3fc; | |
| font-weight: 600; | |
| } | |
| </style> | |
| <div class="selector"> | |
| <button class="selector-btn" id="selector-toggle"> | |
| <i data-feather="sliders" style="width: 16px; height: 16px;"></i> | |
| Quality Filter | |
| <i data-feather="chevron-down" style="width: 14px; height: 14px;"></i> | |
| </button> | |
| <div class="dropdown" id="dropdown"> | |
| <div class="dropdown-section"> | |
| <div class="section-title">Resolution</div> | |
| <div class="model-option active" data-filter="all"> | |
| <span class="model-dot" style="background: #0ea5e9;"></span> | |
| <div class="model-info"> | |
| <div class="model-name">All Resolutions</div> | |
| </div> | |
| </div> | |
| <div class="model-option" data-filter="4k"> | |
| <span class="model-dot" style="background: #22c55e;"></span> | |
| <div class="model-info"> | |
| <div class="model-name">4K Ultra-HD</div> | |
| </div> | |
| <span class="res-tag">4K</span> | |
| </div> | |
| <div class="model-option" data-filter="8k"> | |
| <span class="model-dot" style="background: #a855f7;"></span> | |
| <div class="model-info"> | |
| <div class="model-name">8K Full Ultra</div> | |
| </div> | |
| <span class="res-tag">8K</span> | |
| </div> | |
| <div class="model-option" data-filter="16k"> | |
| <span class="model-dot" style="background: #f59e0b;"></span> | |
| <div class="model-info"> | |
| <div class="model-name">16K Cinema</div> | |
| </div> | |
| <span class="res-tag">16K</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| `; | |
| if (window.feather) { | |
| setTimeout(() => feather.replace(), 0); | |
| } | |
| } | |
| attachEvents() { | |
| const toggle = this.shadowRoot.getElementById('selector-toggle'); | |
| const dropdown = this.shadowRoot.getElementById('dropdown'); | |
| const options = this.shadowRoot.querySelectorAll('.model-option'); | |
| toggle.addEventListener('click', (e) => { | |
| e.stopPropagation(); | |
| dropdown.classList.toggle('open'); | |
| }); | |
| document.addEventListener('click', () => { | |
| dropdown.classList.remove('open'); | |
| }); | |
| options.forEach(opt => { | |
| opt.addEventListener('click', () => { | |
| options.forEach(o => o.classList.remove('active')); | |
| opt.classList.add('active'); | |
| dropdown.classList.remove('open'); | |
| document.dispatchEvent(new CustomEvent('galleryFilter', { | |
| detail: { filter: opt.dataset.filter } | |
| })); | |
| }); | |
| }); | |
| } | |
| } | |
| customElements.define('custom-model-selector', CustomModelSelector); |