/**
* 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 = `
${this.images.map((image, index) => `
${showCaptions ? `
${image.title || image.alt}
` : ''}
`).join('')}
`;
// 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);