1// app/typescript/controllers/campus_carousel_controller.ts 2import { Controller } from "@hotwired/stimulus"; 3 4class campus_carousel_controller_default extends Controller { 5 static targets = ["stage", "slide", "dot"]; 6 index = 0; 7 animationFrame = null; 8 finishHeightTransition = (event) => { 9 if (event.propertyName === "height") 10 this.stageTarget.style.height = "auto"; 11 }; 12 connect() { 13 this.stageTarget.style.overflow = "hidden"; 14 this.stageTarget.style.transition = window.matchMedia("(prefers-reduced-motion: reduce)").matches ? "none" : "height 360ms cubic-bezier(0.65, 0, 0.35, 1)"; 15 this.stageTarget.addEventListener("transitionend", this.finishHeightTransition); 16 this.show(this.index, false); 17 } 18 disconnect() { 19 if (this.animationFrame !== null) 20 cancelAnimationFrame(this.animationFrame); 21 this.stageTarget.removeEventListener("transitionend", this.finishHeightTransition); 22 } 23 next(event) { 24 event.preventDefault(); 25 this.show((this.index + 1) % this.slideTargets.length); 26 } 27 previous(event) { 28 event.preventDefault(); 29 this.show((this.index - 1 + this.slideTargets.length) % this.slideTargets.length); 30 } 31 goTo(event) { 32 event.preventDefault(); 33 const dot = event.currentTarget; 34 const index = Number(dot.dataset.index); 35 if (!Number.isNaN(index)) 36 this.show(index); 37 } 38 show(index, animateHeight = true) { 39 if (this.animationFrame !== null) 40 cancelAnimationFrame(this.animationFrame); 41 const currentHeight = this.stageTarget.getBoundingClientRect().height; 42 if (animateHeight) 43 this.stageTarget.style.height = `${currentHeight}px`; 44 this.index = index; 45 this.slideTargets.forEach((slide, i) => { 46 const isActive = i === index; 47 slide.classList.toggle("hidden", !isActive); 48 slide.setAttribute("aria-hidden", String(!isActive)); 49 }); 50 this.dotTargets.forEach((dot, i) => { 51 const isActive = i === index; 52 dot.classList.toggle("bg-[#c9614a]", isActive); 53 dot.classList.toggle("bg-slate-300", !isActive); 54 dot.classList.toggle("w-4", isActive); 55 dot.classList.toggle("w-2", !isActive); 56 dot.setAttribute("aria-current", isActive ? "true" : "false"); 57 }); 58 if (!animateHeight) { 59 this.stageTarget.style.height = "auto"; 60 return; 61 } 62 const nextHeight = this.slideTargets[index].getBoundingClientRect().height; 63 this.animationFrame = requestAnimationFrame(() => { 64 this.stageTarget.style.height = `${Math.ceil(nextHeight)}px`; 65 this.animationFrame = null; 66 }); 67 } 68} 69export { 70 campus_carousel_controller_default as default 71};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.