UNPKG

@mantine/hooks

Version:

A collection of 50+ hooks for state and UI management

96 lines (95 loc) 3.13 kB
"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