76 lines
1.8 KiB
TypeScript
76 lines
1.8 KiB
TypeScript
// Path: Frontend/src/helper/createLongPressGesture.ts
|
|
|
|
import type { JSX } from "solid-js";
|
|
|
|
type PointerHandler = NonNullable<JSX.DOMAttributes<Element>["onPointerDown"]>;
|
|
|
|
type LongPressGestureOptions = {
|
|
onLongPress: () => void;
|
|
delay?: number;
|
|
movementThreshold?: number;
|
|
};
|
|
|
|
type LongPressGestureHandlers = {
|
|
onPointerDown: PointerHandler;
|
|
onPointerMove: PointerHandler;
|
|
onPointerUp: PointerHandler;
|
|
onPointerCancel: PointerHandler;
|
|
onPointerLeave: PointerHandler;
|
|
};
|
|
|
|
export const createLongPressGesture = (options: LongPressGestureOptions): LongPressGestureHandlers => {
|
|
let timeoutId: number | undefined;
|
|
let originX = 0;
|
|
let originY = 0;
|
|
|
|
const delay = options.delay ?? 420;
|
|
const movementThreshold = options.movementThreshold ?? 10;
|
|
|
|
const clearPendingLongPress = (): void => {
|
|
if (typeof timeoutId === "number") {
|
|
window.clearTimeout(timeoutId);
|
|
timeoutId = undefined;
|
|
}
|
|
};
|
|
|
|
const onPointerDown: PointerHandler = (event): void => {
|
|
// Mobile long-press should only respond to the primary touch/pen pointer.
|
|
if (event.pointerType === "mouse" || !event.isPrimary) {
|
|
return;
|
|
}
|
|
|
|
originX = event.clientX;
|
|
originY = event.clientY;
|
|
clearPendingLongPress();
|
|
timeoutId = window.setTimeout(() => {
|
|
timeoutId = undefined;
|
|
options.onLongPress();
|
|
}, delay);
|
|
};
|
|
|
|
const onPointerMove: PointerHandler = (event): void => {
|
|
if (typeof timeoutId !== "number") {
|
|
return;
|
|
}
|
|
|
|
const deltaX = Math.abs(event.clientX - originX);
|
|
const deltaY = Math.abs(event.clientY - originY);
|
|
|
|
if (deltaX > movementThreshold || deltaY > movementThreshold) {
|
|
clearPendingLongPress();
|
|
}
|
|
};
|
|
|
|
const onPointerUp: PointerHandler = (): void => {
|
|
clearPendingLongPress();
|
|
};
|
|
|
|
return {
|
|
onPointerDown,
|
|
onPointerMove,
|
|
onPointerUp,
|
|
onPointerCancel: onPointerUp,
|
|
onPointerLeave: onPointerUp,
|
|
};
|
|
};
|