UNPKG

ahooks

Version:
132 lines (131 loc) 5.33 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _react = require("react"); var _useLatest = _interopRequireDefault(require("../useLatest")); var _domTarget = require("../utils/domTarget"); var _isBrowser = _interopRequireDefault(require("../utils/isBrowser")); var _useEffectWithTarget = _interopRequireDefault(require("../utils/useEffectWithTarget")); var touchSupported = _isBrowser["default"] && ( // @ts-ignore 'ontouchstart' in window || window.DocumentTouch && document instanceof DocumentTouch); function useLongPress(onLongPress, target, _a) { var _b = _a === void 0 ? {} : _a, _c = _b.delay, delay = _c === void 0 ? 300 : _c, moveThreshold = _b.moveThreshold, onClick = _b.onClick, onLongPressEnd = _b.onLongPressEnd; var onLongPressRef = (0, _useLatest["default"])(onLongPress); var onClickRef = (0, _useLatest["default"])(onClick); var onLongPressEndRef = (0, _useLatest["default"])(onLongPressEnd); var timerRef = (0, _react.useRef)(); var isTriggeredRef = (0, _react.useRef)(false); var pervPositionRef = (0, _react.useRef)({ x: 0, y: 0 }); var hasMoveThreshold = !!((moveThreshold === null || moveThreshold === void 0 ? void 0 : moveThreshold.x) && moveThreshold.x > 0 || (moveThreshold === null || moveThreshold === void 0 ? void 0 : moveThreshold.y) && moveThreshold.y > 0); (0, _useEffectWithTarget["default"])(function () { var targetElement = (0, _domTarget.getTargetElement)(target); if (!(targetElement === null || targetElement === void 0 ? void 0 : targetElement.addEventListener)) { return; } var overThreshold = function overThreshold(event) { var _a = getClientPosition(event), clientX = _a.clientX, clientY = _a.clientY; var offsetX = Math.abs(clientX - pervPositionRef.current.x); var offsetY = Math.abs(clientY - pervPositionRef.current.y); return !!((moveThreshold === null || moveThreshold === void 0 ? void 0 : moveThreshold.x) && offsetX > moveThreshold.x || (moveThreshold === null || moveThreshold === void 0 ? void 0 : moveThreshold.y) && offsetY > moveThreshold.y); }; function getClientPosition(event) { if (event instanceof TouchEvent) { return { clientX: event.touches[0].clientX, clientY: event.touches[0].clientY }; } if (event instanceof MouseEvent) { return { clientX: event.clientX, clientY: event.clientY }; } console.warn('Unsupported event type'); return { clientX: 0, clientY: 0 }; } var onStart = function onStart(event) { if (hasMoveThreshold) { var _a = getClientPosition(event), clientX = _a.clientX, clientY = _a.clientY; pervPositionRef.current.x = clientX; pervPositionRef.current.y = clientY; } timerRef.current = setTimeout(function () { onLongPressRef.current(event); isTriggeredRef.current = true; }, delay); }; var onMove = function onMove(event) { if (timerRef.current && overThreshold(event)) { clearTimeout(timerRef.current); timerRef.current = undefined; } }; var onEnd = function onEnd(event, shouldTriggerClick) { var _a; if (shouldTriggerClick === void 0) { shouldTriggerClick = false; } if (timerRef.current) { clearTimeout(timerRef.current); } if (isTriggeredRef.current) { (_a = onLongPressEndRef.current) === null || _a === void 0 ? void 0 : _a.call(onLongPressEndRef, event); } if (shouldTriggerClick && !isTriggeredRef.current && onClickRef.current) { onClickRef.current(event); } isTriggeredRef.current = false; }; var onEndWithClick = function onEndWithClick(event) { return onEnd(event, true); }; if (!touchSupported) { targetElement.addEventListener('mousedown', onStart); targetElement.addEventListener('mouseup', onEndWithClick); targetElement.addEventListener('mouseleave', onEnd); if (hasMoveThreshold) targetElement.addEventListener('mousemove', onMove); } else { targetElement.addEventListener('touchstart', onStart); targetElement.addEventListener('touchend', onEndWithClick); if (hasMoveThreshold) targetElement.addEventListener('touchmove', onMove); } return function () { if (timerRef.current) { clearTimeout(timerRef.current); isTriggeredRef.current = false; } if (!touchSupported) { targetElement.removeEventListener('mousedown', onStart); targetElement.removeEventListener('mouseup', onEndWithClick); targetElement.removeEventListener('mouseleave', onEnd); if (hasMoveThreshold) targetElement.removeEventListener('mousemove', onMove); } else { targetElement.removeEventListener('touchstart', onStart); targetElement.removeEventListener('touchend', onEndWithClick); if (hasMoveThreshold) targetElement.removeEventListener('touchmove', onMove); } }; }, [], target); } var _default = useLongPress; exports["default"] = _default;