All files / hooks/use-long-press/src utils.ts

100% Statements 12/12
100% Branches 6/6
100% Functions 4/4
100% Lines 12/12

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67        1x     1x                 1x                             29x                       27x 11x 11x   16x             5x 5x 5x               28x    
import type { MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent } from "react";
import type { LongPressEvent } from "./types";
 
/** Default press-and-hold threshold in milliseconds. */
export const DEFAULT_THRESHOLD = 400;
 
/** Default movement-cancellation distance in pixels. */
export const DEFAULT_MOVE_THRESHOLD = 10;
 
/**
 * How long, in milliseconds, after a touch event any `mouse*` handler is treated
 * as a browser-emitted *synthetic* mouse event and ignored. Browsers fire
 * `mousedown`/`mouseup`/`click` shortly after `touchend`; without this guard a
 * single touch long-press would also start a second gesture through the mouse
 * handlers.
 */
export const TOUCH_MOUSE_GUARD_MS = 500;
 
/** A pointer position in client coordinates. */
export interface Position {
  x: number;
  y: number;
}
 
/**
 * Type guard: is this a React touch event (as opposed to a mouse event)? Touch
 * events expose a `touches` list; mouse events do not.
 */
export function isTouchEvent(
  event: LongPressEvent
): event is ReactTouchEvent {
  return "touches" in event;
}
 
/**
 * Extract the client `{ x, y }` position from a mouse or touch event, or `null`
 * if it cannot be determined (e.g. a touch event with no active touches).
 *
 * For touch events it prefers the first active touch (`touches[0]`, available on
 * `touchstart`/`touchmove`) and falls back to the first changed touch
 * (`changedTouches[0]`, the one available on `touchend`).
 */
export function getPositionFromEvent(event: LongPressEvent): Position | null {
  if (isTouchEvent(event)) {
    const touch = event.touches[0] ?? event.changedTouches[0];
    return touch ? { x: touch.clientX, y: touch.clientY } : null;
  }
  return { x: event.clientX, y: event.clientY };
}
 
/**
 * Straight-line (Euclidean) distance in pixels between two positions.
 */
export function getDistance(a: Position, b: Position): number {
  const dx = a.x - b.x;
  const dy = a.y - b.y;
  return Math.sqrt(dx * dx + dy * dy);
}
 
/**
 * Current timestamp in milliseconds. Uses `Date.now()` so it is deterministic
 * under fake timers and available in every environment (no `window`/SSR access).
 */
export function now(): number {
  return Date.now();
}