useLongPress Hook
A custom React Hook to detect long press events on elements with TypeScript support
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>