MoShow's picture
I need this app to deliver High resolution products, HD, Ulte-HD, 40K stats
2f9cc52 verified
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);