1import { Controller } from "@hotwired/stimulus" 2 3export default class extends Controller { 4 static targets = ["slide", "dot"] 5 static values = { 6 interval: { type: Number, default: 5000 } 7 } 8 9 connect() { 10 this.index = 0 11 this.reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches 12 this.element.classList.add("saas-promo-slider--ready") 13 this.show(this.index) 14 this.start() 15 } 16 17 disconnect() { 18 this.stop() 19 } 20 21 select(event) { 22 this.show(event.params.index) 23 this.restart() 24 } 25 26 pause() { 27 this.stop() 28 } 29 30 resume() { 31 this.start() 32 } 33 34 start() { 35 if (this.reducedMotion || this.slideTargets.length < 2 || this.timer) return 36 37 this.timer = window.setInterval(() => { 38 this.show((this.index + 1) % this.slideTargets.length) 39 }, this.intervalValue) 40 } 41 42 stop() { 43 if (!this.timer) return 44 45 window.clearInterval(this.timer) 46 this.timer = null 47 } 48 49 restart() { 50 this.stop() 51 this.start() 52 } 53 54 show(index) { 55 this.index = Number(index) 56 57 this.slideTargets.forEach((slide, slideIndex) => { 58 const active = slideIndex === this.index 59 slide.classList.toggle("is-active", active) 60 slide.setAttribute("aria-hidden", active ? "false" : "true") 61 }) 62 63 this.dotTargets.forEach((dot, dotIndex) => { 64 const active = dotIndex === this.index 65 dot.classList.toggle("is-active", active) 66 dot.setAttribute("aria-current", active ? "true" : "false") 67 }) 68 } 69}
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.