@mantine/hooks
Version:
A collection of 50+ hooks for state and UI management
96 lines (95 loc) • 3.13 kB
JavaScript
"use client";
let react = require("react");
//#region packages/@mantine/hooks/src/use-long-press/use-long-press.ts
const DEFAULT_EVENTS = ["mouse", "touch"];
const DEFAULT_MOVE_THRESHOLD = 10;
function useLongPress(onLongPress, options = {}) {
const { threshold = 400, events = DEFAULT_EVENTS, cancelOnMove = false, onStart, onFinish, onCancel } = options;
const isLongPressActive = (0, react.useRef)(false);
const isPressed = (0, react.useRef)(false);
const timeout = (0, react.useRef)(-1);
const startPosition = (0, react.useRef)(null);
(0, react.useEffect)(() => () => window.clearTimeout(timeout.current), []);
return (0, react.useMemo)(() => {
if (typeof onLongPress !== "function") return {};
const moveEnabled = cancelOnMove !== false;
const moveThreshold = cancelOnMove === true ? DEFAULT_MOVE_THRESHOLD : cancelOnMove === false ? 0 : cancelOnMove;
const start = (event) => {
if (!isMouseEvent(event) && !isTouchEvent(event)) return;
if (onStart) onStart(event);
startPosition.current = getEventPosition(event);
isPressed.current = true;
timeout.current = window.setTimeout(() => {
onLongPress(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;
startPosition.current = null;
if (timeout.current !== -1) {
window.clearTimeout(timeout.current);
timeout.current = -1;
}
};
const move = (event) => {
if (!moveEnabled || !isPressed.current || isLongPressActive.current) return;
const position = getEventPosition(event);
if (!position || !startPosition.current) return;
const dx = position.x - startPosition.current.x;
const dy = position.y - startPosition.current.y;
if (Math.sqrt(dx * dx + dy * dy) > moveThreshold) cancel(event);
};
const handlers = {};
if (events.includes("mouse")) {
handlers.onMouseDown = start;
handlers.onMouseUp = cancel;
handlers.onMouseLeave = cancel;
if (moveEnabled) handlers.onMouseMove = move;
}
if (events.includes("touch")) {
handlers.onTouchStart = start;
handlers.onTouchEnd = cancel;
handlers.onTouchCancel = cancel;
if (moveEnabled) handlers.onTouchMove = move;
}
return handlers;
}, [
onLongPress,
threshold,
onCancel,
onFinish,
onStart,
cancelOnMove,
events.join(",")
]);
}
function getEventPosition(event) {
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
};
}
function isTouchEvent(event) {
return window.TouchEvent ? event.nativeEvent instanceof TouchEvent : "touches" in event.nativeEvent;
}
function isMouseEvent(event) {
return event.nativeEvent instanceof MouseEvent;
}
//#endregion
exports.useLongPress = useLongPress;
//# sourceMappingURL=use-long-press.cjs.map