fix: carousel image lightbox
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
"use client";
|
||||
|
||||
/**
|
||||
* useTapGuard — tells a genuine tap apart from a swipe on a natively-scrolling
|
||||
* strip (CSS scroll-snap carousels).
|
||||
*
|
||||
* Browsers still fire a `click` after some swipe gestures, so a plain onClick
|
||||
* on a slide would trigger mid-swipe. Snapshot the pointer position AND the
|
||||
* scroller's offset on pointerdown, then check both when the click arrives:
|
||||
*
|
||||
* • pointer travel — catches a drag that didn't scroll (e.g. hit the end)
|
||||
* • scroll movement — catches an inertial swipe, where the pointer barely
|
||||
* moves before `click` fires but the strip is already gliding
|
||||
*
|
||||
* Either signal alone misses cases, hence both. No staleness risk: a click is
|
||||
* always immediately preceded by a pointerdown on the same element.
|
||||
*/
|
||||
|
||||
import { useRef, type RefObject } from "react";
|
||||
|
||||
/** Pointer travel (px) still considered a tap rather than a drag. */
|
||||
const MOVE_TOLERANCE = 8;
|
||||
/** Scroll movement (px) still considered "didn't scroll". */
|
||||
const SCROLL_TOLERANCE = 4;
|
||||
|
||||
type PointerLike = { clientX: number; clientY: number };
|
||||
|
||||
export function useTapGuard(scrollerRef: RefObject<HTMLElement | null>) {
|
||||
const start = useRef({ x: 0, y: 0, scrollLeft: 0 });
|
||||
|
||||
function onPointerDown(e: PointerLike) {
|
||||
start.current = {
|
||||
x: e.clientX,
|
||||
y: e.clientY,
|
||||
scrollLeft: scrollerRef.current?.scrollLeft ?? 0,
|
||||
};
|
||||
}
|
||||
|
||||
function wasTap(e: PointerLike) {
|
||||
const moved =
|
||||
Math.abs(e.clientX - start.current.x) > MOVE_TOLERANCE ||
|
||||
Math.abs(e.clientY - start.current.y) > MOVE_TOLERANCE;
|
||||
const scrolled =
|
||||
Math.abs(
|
||||
(scrollerRef.current?.scrollLeft ?? 0) - start.current.scrollLeft,
|
||||
) > SCROLL_TOLERANCE;
|
||||
return !moved && !scrolled;
|
||||
}
|
||||
|
||||
return { onPointerDown, wasTap };
|
||||
}
|
||||
Reference in New Issue
Block a user