prop/assets/js/rover_slider_hook.ts

42 lines
1.1 KiB
TypeScript

import type { ViewHook } from "phoenix_live_view"
interface RoverSliderHook extends ViewHook {
labelEl: HTMLElement | null
formatter: (v: number) => string
inputHandler: () => void
}
const formatters: Record<string, (v: number) => string> = {
forecast: (v) => `+${v}h`,
drive: (v) => {
const hours = Math.round((v / 60) * 10) / 10
return `${hours}h`
}
}
export const RoverSlider: Partial<RoverSliderHook> = {
mounted(this: RoverSliderHook) {
const labelId = this.el.dataset.labelId || ""
const format = this.el.dataset.format || "forecast"
this.formatter = formatters[format] || formatters.forecast
this.labelEl = document.getElementById(labelId)
this.inputHandler = () => {
if (this.labelEl) {
this.labelEl.textContent = this.formatter(Number((this.el as HTMLInputElement).value))
}
}
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)
}
}