{"version":3,"sources":["../../src/use-long-press/index.ts"],"sourcesContent":["import { useRef } from 'react'\nimport { useEventListener } from '../use-event-listener'\nimport { useLatest } from '../use-latest'\nimport { useSetState } from '../use-set-state'\nimport { useStableFn } from '../use-stable-fn'\nimport { useTargetElement } from '../use-target-element'\n\nimport type { ElementTarget } from '../use-target-element'\nimport type { Position, SetTimeoutReturn } from '../utils/basic'\n\nconst DEFAULT_DELAY = 500\nconst DEFAULT_THRESHOLD = 10\n\nexport interface UseLongPressModifiers {\n  /**\n   * Whether to prevent the default behavior of the event\n   */\n  preventDefault?: boolean\n  /**\n   * Whether to stop the propagation of the event\n   */\n  stopPropagation?: boolean\n  /**\n   * Whether to only trigger the event once\n   */\n  once?: boolean\n  /**\n   * Whether to capture the event\n   */\n  capture?: boolean\n  /**\n   * Whether to only trigger the event on the target element itself\n   */\n  self?: boolean\n}\n\nexport interface UseLongPressOptions {\n  /**\n   * Time in ms till `longpress` gets called\n   *\n   * @defaultValue 500\n   */\n  delay?: number\n  /**\n   * Event modifiers\n   */\n  modifiers?: UseLongPressModifiers\n  /**\n   * Allowance of moving distance in pixels,\n   * The action will get canceled When moving too far from the pointerdown position.\n   *\n   * @defaultValue 10\n   */\n  distanceThreshold?: number | false\n}\n\nconst defaultFalsyState: Pick<UseLongPressReturns, 'isPressed' | 'isLongPressed' | 'isMeetThreshold'> = {\n  isPressed: false,\n  isLongPressed: false,\n  isMeetThreshold: false,\n}\n\nexport type UseLongPressHandler = (evt: PointerEvent) => void\n\nexport interface UseLongPressReturns {\n  /**\n   * Whether the element is pressed\n   */\n  isPressed: boolean\n  /**\n   * Whether the element is long pressed\n   */\n  isLongPressed: boolean\n  /**\n   * Whether the element is meet the threshold\n   */\n  isMeetThreshold: boolean\n  /**\n   * Stop the long press event\n   */\n  stop(): void\n}\n\n/**\n * A React Hook that helps to handle long press events.\n */\nexport function useLongPress(\n  target: ElementTarget,\n  handler?: UseLongPressHandler,\n  options?: UseLongPressOptions,\n): UseLongPressReturns {\n  const el = useTargetElement(target)\n  const timeout = useRef<SetTimeoutReturn | null>(null)\n  const posStart = useRef<Position | undefined>(undefined)\n  const [state, setState] = useSetState({ ...defaultFalsyState }, { deep: true })\n\n  const latest = useLatest({\n    handler: (e: PointerEvent) => {\n      handler?.(e)\n      setState({ isLongPressed: true })\n    },\n  })\n\n  function clearTimer() {\n    if (timeout.current) {\n      clearTimeout(timeout.current)\n      timeout.current = null\n    }\n    posStart.current = undefined\n  }\n\n  function reset() {\n    clearTimer()\n    setState({ ...defaultFalsyState })\n  }\n\n  function onDown(ev: PointerEvent) {\n    if (options?.modifiers?.self && ev.target !== el.current) return\n\n    clearTimer()\n\n    if (options?.modifiers?.preventDefault) ev.preventDefault()\n    if (options?.modifiers?.stopPropagation) ev.stopPropagation()\n\n    setState({ isPressed: true })\n\n    posStart.current = { x: ev.x, y: ev.y }\n    timeout.current = setTimeout(() => latest.current.handler(ev), options?.delay ?? DEFAULT_DELAY)\n  }\n\n  function onMove(ev: PointerEvent) {\n    if (options?.modifiers?.self && ev.target !== el.current) return\n    if (!posStart.current || options?.distanceThreshold === false) return\n    if (options?.modifiers?.preventDefault) ev.preventDefault()\n    if (options?.modifiers?.stopPropagation) ev.stopPropagation()\n\n    const dx = ev.x - posStart.current?.x\n    const dy = ev.y - posStart.current?.y\n    const distance = Math.sqrt(dx * dx + dy * dy)\n\n    if (distance >= (options?.distanceThreshold ?? DEFAULT_THRESHOLD)) {\n      clearTimer()\n      setState({ isMeetThreshold: true })\n    } else {\n      setState({ isMeetThreshold: false })\n    }\n  }\n\n  const evtOptions = {\n    capture: options?.modifiers?.capture,\n    once: options?.modifiers?.once,\n  }\n\n  const cleanups = useLatest([\n    useEventListener(el, ['pointerup', 'pointerleave'], reset, evtOptions),\n    useEventListener(el, 'pointerdown', onDown, evtOptions),\n    useEventListener(el, 'pointermove', onMove, evtOptions),\n  ])\n\n  const stop = useStableFn(() => {\n    for (const cleanup of cleanups.current) cleanup()\n  })\n\n  return {\n    ...state,\n    stop,\n  }\n}\n"],"names":["useLongPress","DEFAULT_DELAY","DEFAULT_THRESHOLD","defaultFalsyState","isPressed","isLongPressed","isMeetThreshold","target","handler","options","el","useTargetElement","timeout","useRef","posStart","undefined","useSetState","deep","state","setState","latest","useLatest","e","clearTimer","current","clearTimeout","reset","onDown","ev","modifiers","self","preventDefault","stopPropagation","x","y","setTimeout","delay","onMove","distanceThreshold","dx","dy","distance","Math","sqrt","evtOptions","capture","once","cleanups","useEventListener","stop","useStableFn","cleanup"],"mappings":"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"}