import { Controller } from "@hotwired/stimulus" export default class extends Controller { static targets = ["carousel", "marker"] connect() { this.boundUpdate = this.update.bind(this) this.boundEqualizeHeights = this.equalizeHeights.bind(this) this.carouselTarget.addEventListener("scroll", this.boundUpdate, { passive: true }) window.addEventListener("resize", this.boundEqualizeHeights) this.equalizeHeights() this.update() } disconnect() { this.carouselTarget.removeEventListener("scroll", this.boundUpdate) window.removeEventListener("resize", this.boundEqualizeHeights) } equalizeHeights() { const articles = this.carouselTarget.querySelectorAll(":scope > li > article") articles.forEach((article) => (article.style.height = "auto")) const tallest = Array.from(articles).reduce((max, article) => Math.max(max, article.offsetHeight), 0) articles.forEach((article) => (article.style.height = `${tallest}px`)) } update() { const slides = Array.from(this.carouselTarget.children) const center = this.carouselTarget.scrollLeft + this.carouselTarget.clientWidth / 2 let activeIndex = 0 let closest = Infinity slides.forEach((slide, i) => { const slideCenter = slide.offsetLeft + slide.offsetWidth / 2 const distance = Math.abs(slideCenter - center) if (distance < closest) { closest = distance activeIndex = i } }) this.markerTargets.forEach((marker, i) => { marker.classList.toggle("current", i === activeIndex) }) } goto(event) { const index = parseInt(event.currentTarget.dataset.index, 10) const slide = this.carouselTarget.children[index] if (slide) { this.carouselTarget.scrollTo({ left: slide.offsetLeft, behavior: "smooth" }) } } }