Skip to content

Instantly share code, notes, and snippets.

@GalindoSVQ
Created January 11, 2024 21:35
Show Gist options
  • Save GalindoSVQ/cedbf208797b4185998cdac5965b1470 to your computer and use it in GitHub Desktop.
Save GalindoSVQ/cedbf208797b4185998cdac5965b1470 to your computer and use it in GitHub Desktop.
import * as React from "react";
export function isTouchEvent({ nativeEvent }) {
return window.TouchEvent
? nativeEvent instanceof TouchEvent
: "touches" in nativeEvent;
}
export function isMouseEvent(event) {
return event.nativeEvent instanceof MouseEvent;
}
export default function useLongPress(callback, options = {}) {
const { threshold = 400, onStart, onFinish, onCancel } = options;
const isLongPressActive = React.useRef(false);
const isPressed = React.useRef(false);
const timerId = React.useRef();
return React.useMemo(() => {
if (typeof callback !== "function") {
return {};
}
const start = (event) => {
if (!isMouseEvent(event) && !isTouchEvent(event)) return;
if (onStart) {
onStart(event);
}
isPressed.current = true;
timerId.current = setTimeout(() => {
callback(event);
isLongPressActive.current = true;
}, threshold);
};
const cancel = (event) => {
if (!isMouseEvent(event) && !isTouchEvent(event)) return;
if (isLongPressActive.current) {
if (onFinish) {
onFinish(event);
}
} else if (isPressed.current) {
if (onCancel) {
onCancel(event);
}
}
isLongPressActive.current = false;
isPressed.current = false;
if (timerId.current) {
window.clearTimeout(timerId.current);
}
};
const mouseHandlers = {
onMouseDown: start,
onMouseUp: cancel,
onMouseLeave: cancel
};
const touchHandlers = {
onTouchStart: start,
onTouchEnd: cancel
};
return {
...mouseHandlers,
...touchHandlers
};
}, [callback, threshold, onCancel, onFinish, onStart]);
}
@GalindoSVQ
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment