prop/assets/js/horizontal_wheel_scroll_hook.ts

29 lines
1.1 KiB
TypeScript

// Translates a vertical mouse-wheel into horizontal scroll on this
// element so users on a desktop without a horizontal trackpad can
// still scroll a horizontal carousel by using the wheel over it.
import type { ViewHook } from "phoenix_live_view"
interface HorizontalWheelScrollHook extends ViewHook {
wheelHandler?: (e: WheelEvent) => void
}
export const HorizontalWheelScroll: Partial<HorizontalWheelScrollHook> = {
mounted(this: HorizontalWheelScrollHook) {
this.wheelHandler = (e: WheelEvent) => {
// Only convert dominant-vertical wheels; leave true horizontal
// gestures alone so trackpads still feel native.
if (Math.abs(e.deltaY) <= Math.abs(e.deltaX)) return
const el = this.el as HTMLElement
if (el.scrollWidth <= el.clientWidth) return
e.preventDefault()
el.scrollLeft += e.deltaY
}
this.el.addEventListener("wheel", this.wheelHandler, { passive: false })
},
destroyed(this: HorizontalWheelScrollHook) {
if (this.wheelHandler) {
this.el.removeEventListener("wheel", this.wheelHandler)
}
}
}