REACT

useLongPress Hook

A custom React Hook to detect long press events on elements with TypeScript support

ReactHooksTouchEventsUI

Code

import { useCallback, useRef, useState } from 'react';

type LongPressOptions = {
  delay?: number;
  onLongPress: (e: React.MouseEvent | React.TouchEvent) => void;
  onClick?: (e: React.MouseEvent | React.TouchEvent) => void;
};

function useLongPress({ delay = 500, onLongPress, onClick }: LongPressOptions) {
  const [isPressing, setIsPressing] = useState(false);
  const timerRef = useRef<NodeJS.Timeout | null>(null);
  const eventRef = useRef<React.MouseEvent | React.TouchEvent | null>(null);

  const startPress = useCallback((e: React.MouseEvent | React.TouchEvent) => {
    e.preventDefault();
    eventRef.current = e;
    setIsPressing(true);
    timerRef.current = setTimeout(() => {
      onLongPress(e);
      setIsPressing(false);
    }, delay);
  }, [delay, onLongPress]);

  const endPress = useCallback((e: React.MouseEvent | React.TouchEvent) => {
    e.preventDefault();
    __TOKEN_17__ (timerRef.current) clearTimeout(timerRef.current);
    __TOKEN_18__ (isPressing && onClick && eventRef.current) {
      onClick(eventRef.current);
    }
    setIsPressing(false);
    eventRef.current = null;
  }, [isPressing, onClick]);

  const cancelPress = useCallback(() => {
    __TOKEN_20__ (timerRef.current) clearTimeout(timerRef.current);
    setIsPressing(false);
    eventRef.current = null;
  }, []);

  return {
    onMouseDown: startPress,
    onMouseUp: endPress,
    onMouseLeave: cancelPress,
    onTouchStart: startPress,
    onTouchEnd: endPress,
    onTouchCancel: cancelPress,
  };
}

// Usage example
// const longPressHandlers = useLongPress({
//   onLongPress: () => console.log('Long press!'),
//   onClick: () => console.log('Click!'),
//   delay: 600
// });
// <button {...longPressHandlers}>Long Press Me</button>