import type { ViewHook } from "phoenix_live_view" interface RoverSliderHook extends ViewHook { labelEl: HTMLElement | null formatter: (v: number) => string format: string inputHandler: () => void } const KM_PER_MI = 1.609344 const formatters: Record string> = { forecast: (v) => `+${v}h`, distance: (v) => `${v} mi` } export const RoverSlider: Partial = { mounted(this: RoverSliderHook) { const labelId = this.el.dataset.labelId || "" this.format = this.el.dataset.format || "forecast" this.formatter = formatters[this.format] || formatters.forecast this.labelEl = document.getElementById(labelId) this.inputHandler = () => { const value = Number((this.el as HTMLInputElement).value) if (this.labelEl) this.labelEl.textContent = this.formatter(value) if (this.format === "distance") { const km = value * KM_PER_MI window.dispatchEvent(new CustomEvent("rover:drive-radius", { detail: { km } })) } } this.el.addEventListener("input", this.inputHandler) this.inputHandler() }, updated(this: RoverSliderHook) { if (this.inputHandler) this.inputHandler() }, destroyed(this: RoverSliderHook) { if (this.inputHandler) this.el.removeEventListener("input", this.inputHandler) } }