feat(rover): make candidate strip scroll horizontally + wheel-to-h-scroll
This commit is contained in:
parent
12e0106b7b
commit
3b1a13b0f7
3 changed files with 37 additions and 3 deletions
|
|
@ -21,6 +21,7 @@ import {WeatherMap} from "./weather_map_hook"
|
|||
import {LocateMe, CopyLink} from "./locate_me_hook"
|
||||
import {RoverMap} from "./rover_map_hook"
|
||||
import {RoverSlider} from "./rover_slider_hook"
|
||||
import {HorizontalWheelScroll} from "./horizontal_wheel_scroll_hook"
|
||||
import {BeaconMap} from "./beacon_map_hook"
|
||||
import {BeaconsListMap} from "./beacons_list_map_hook"
|
||||
|
||||
|
|
@ -312,7 +313,7 @@ const csrfToken = document.querySelector("meta[name='csrf-token']")!.getAttribut
|
|||
const liveSocket = new LiveSocket("/live", Socket, {
|
||||
longPollFallbackMs: 2500,
|
||||
params: initLiveStash({_csrf_token: csrfToken}),
|
||||
hooks: {...colocatedHooks, PropagationMap, PathForecast, UtcClock, ContactMap, ContactsMap, ElevationProfile, WeatherMap, LocateMe, CopyLink, RoverMap, RoverSlider, BeaconMap, BeaconsListMap, CommaNumber, ImportConfetti, EmeGlobe, Skewt},
|
||||
hooks: {...colocatedHooks, PropagationMap, PathForecast, UtcClock, ContactMap, ContactsMap, ElevationProfile, WeatherMap, LocateMe, CopyLink, RoverMap, RoverSlider, HorizontalWheelScroll, BeaconMap, BeaconsListMap, CommaNumber, ImportConfetti, EmeGlobe, Skewt},
|
||||
})
|
||||
|
||||
// live_table rows are dead on their own — wire up whole-row clicks to
|
||||
|
|
|
|||
29
assets/js/horizontal_wheel_scroll_hook.ts
Normal file
29
assets/js/horizontal_wheel_scroll_hook.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
// 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -883,10 +883,14 @@ defmodule MicrowavepropWeb.RoverLive do
|
|||
<div class="px-3 pt-1 text-[10px] uppercase tracking-wider text-base-content/60 font-semibold">
|
||||
Ideal locations
|
||||
</div>
|
||||
<div class="carousel carousel-start gap-3 px-3 pb-3 pt-1 h-[110px] overflow-x-auto">
|
||||
<div
|
||||
id="rover-candidates-strip"
|
||||
phx-hook="HorizontalWheelScroll"
|
||||
class="flex flex-row flex-nowrap gap-3 px-3 pb-3 pt-1 h-[110px] overflow-x-auto overflow-y-hidden overscroll-x-contain"
|
||||
>
|
||||
<div
|
||||
:for={c <- @top_candidates}
|
||||
class="carousel-item w-[280px] card bg-base-200 shadow-sm cursor-pointer"
|
||||
class="shrink-0 w-[280px] card bg-base-200 shadow-sm cursor-pointer"
|
||||
phx-click="select_candidate"
|
||||
phx-value-grid={c.grid}
|
||||
>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue