/** * Image Gallery Web Component * Displays a gallery of pharmaceutical products with lightbox functionality */ class ImageGallery extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); this.images = []; this.currentIndex = 0; } connectedCallback() { // Parse images from data attribute or children const imagesData = this.getAttribute('data-images'); if (imagesData) { try { this.images = JSON.parse(imagesData); } catch (e) { console.error('Failed to parse images data', e); } } // If no images data attribute, look for child elements if (this.images.length === 0) { this.querySelectorAll('img').forEach(img => { this.images.push({ src: img.src, alt: img.alt, title: img.title || img.alt }); }); } this.render(); } render() { const columns = this.getAttribute('columns') || '4'; const gap = this.getAttribute('gap') || '4'; const showCaptions = this.hasAttribute('show-captions'); this.shadowRoot.innerHTML = ` `; // Add event listeners this.addEventListeners(); } addEventListeners() { const lightbox = this.shadowRoot.querySelector('.lightbox'); const lightboxImage = this.shadowRoot.querySelector('.lightbox-image'); const lightboxCaption = this.shadowRoot.querySelector('.lightbox-caption'); const closeBtn = this.shadowRoot.querySelector('.lightbox-close'); const prevBtn = this.shadowRoot.querySelector('.lightbox-prev'); const nextBtn = this.shadowRoot.querySelector('.lightbox-next'); const galleryItems = this.shadowRoot.querySelectorAll('.gallery-item'); // Open lightbox on image click galleryItems.forEach(item => { item.addEventListener('click', () => { this.currentIndex = parseInt(item.dataset.index); this.updateLightbox(); lightbox.classList.add('active'); document.body.style.overflow = 'hidden'; }); }); // Close lightbox closeBtn.addEventListener('click', () => { lightbox.classList.remove('active'); document.body.style.overflow = 'auto'; }); // Lightbox navigation prevBtn.addEventListener('click', () => { this.currentIndex = (this.currentIndex - 1 + this.images.length) % this.images.length; this.updateLightbox(); }); nextBtn.addEventListener('click', () => { this.currentIndex = (this.currentIndex + 1) % this.images.length; this.updateLightbox(); }); // Keyboard navigation document.addEventListener('keydown', (e) => { if (!lightbox.classList.contains('active')) return; switch (e.key) { case 'Escape': lightbox.classList.remove('active'); document.body.style.overflow = 'auto'; break; case 'ArrowLeft': this.currentIndex = (this.currentIndex - 1 + this.images.length) % this.images.length; this.updateLightbox(); break; case 'ArrowRight': this.currentIndex = (this.currentIndex + 1) % this.images.length; this.updateLightbox(); break; } }); // Close on background click lightbox.addEventListener('click', (e) => { if (e.target === lightbox) { lightbox.classList.remove('active'); document.body.style.overflow = 'auto'; } }); } updateLightbox() { const lightboxImage = this.shadowRoot.querySelector('.lightbox-image'); const lightboxCaption = this.shadowRoot.querySelector('.lightbox-caption'); const image = this.images[this.currentIndex]; lightboxImage.src = image.src; lightboxImage.alt = image.alt; lightboxCaption.textContent = image.title || image.alt; } } customElements.define('image-gallery', ImageGallery);