import { Carousel, type CarouselItem, type CarouselInterface, type CarouselOptions, type IndicatorItem, Modal, type ModalInterface, } from 'flowbite'; class CustomCarousel extends HTMLElement { _slide: boolean; _items: CarouselItem[]; _options: CarouselOptions; _carousel: CarouselInterface; _modalEl: HTMLElement; _modal: ModalInterface; constructor() { super(); this._slide = this.getAttribute('data-custom-carousel') === 'slide'; this._items = this._getItems(); this._options = this._getOptions(); this._carousel = new Carousel(this, this._items, this._options); if (this._slide && this._items.length > 0) this._carousel.cycle(); this._modalEl = this.querySelector('[data-custom-carousel-modal]') as HTMLElement || undefined; this._modal = new Modal(this._modalEl); window.addEventListener("load", this._attachHandlers); } _getItems = (): CarouselItem[] => { let customItems = this.querySelectorAll('[data-custom-carousel-item]') || []; return Array.from(customItems).map( (item): CarouselItem => { return { el: item as HTMLElement, position: Number(item.getAttribute("data-custom-carousel-item")) } } ) } _getOptions = (): CarouselOptions => { let customIndicators = this.querySelectorAll('[data-custom-carousel-slide-to]') || []; return { defaultPosition: 0, interval: this.dataset.customCarouselInterval ? Number(this.dataset.customCarouselInterval) : 8000, indicators: { activeClasses: 'border-2 border-caperren-green bg-black', inactiveClasses: 'bg-caperren-green/40 hover:bg-caperren-green-light', items: Array.from(customIndicators).map( (item, index): IndicatorItem => { return { el: item as HTMLElement, position: Number(item.getAttribute('data-custom-carousel-slide-to')) } } ) } } } _attachHandlers = (): void => { // Carousel controls this.querySelector( '[data-custom-carousel-next]' )?.addEventListener('click', () => this._carousel.next()); this.querySelector( '[data-custom-carousel-prev]' )?.addEventListener('click', () => this._carousel.prev()); // Close fullscreen modal this._modalEl.querySelector('[data-custom-carousel-modal-hide]')?.addEventListener('click', () => this._modal.hide()) // Click to open fullscreen modal this._items.forEach((item) => { item.el.addEventListener('click', () => { const imgCloned = item.el.querySelector('img')?.cloneNode() as Node; const imageDiv = this._modalEl.querySelector('[data-custom-carousel-modal-image]') as HTMLElement || undefined; imageDiv.innerHTML = ''; imageDiv?.appendChild(imgCloned); this._modal.show(); }) }) } } customElements.define('custom-carousel', CustomCarousel)