UNPKG

ahooks

Version:
227 lines (226 loc) 8.92 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 _useEffectWithTarget = _interopRequireDefault(require("../utils/useEffectWithTarget")); function useLongPress(onLongPress, target) { var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, _ref$delay = _ref.delay, delay = _ref$delay === void 0 ? 300 : _ref$delay, moveThreshold = _ref.moveThreshold, onClick = _ref.onClick, onLongPressEnd = _ref.onLongPressEnd; var onLongPressRef = (0, _useLatest["default"])(onLongPress); var onClickRef = (0, _useLatest["default"])(onClick); var onLongPressEndRef = (0, _useLatest["default"])(onLongPressEnd); var timerRef = (0, _react.useRef)(undefined); var isTriggeredRef = (0, _react.useRef)(false); var pervPositionRef = (0, _react.useRef)({ x: 0, y: 0 }); var activePointerIdRef = (0, _react.useRef)(undefined); var mousePressed = (0, _react.useRef)(false); var touchPressed = (0, _react.useRef)(false); 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 supportPointerEvent = typeof window !== 'undefined' && typeof window.PointerEvent === 'function'; var overThreshold = function overThreshold(event) { var _getClientPosition = getClientPosition(event), clientX = _getClientPosition.clientX, clientY = _getClientPosition.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 ('TouchEvent' in window && 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 }; } return { clientX: 0, clientY: 0 }; } var createTimer = function createTimer(event) { timerRef.current = setTimeout(function () { onLongPressRef.current(event); isTriggeredRef.current = true; }, delay); }; var clearTimer = function clearTimer() { if (timerRef.current) { clearTimeout(timerRef.current); timerRef.current = undefined; } }; var finishPress = function finishPress(event) { var triggerClick = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; var _a; clearTimer(); if (isTriggeredRef.current) { (_a = onLongPressEndRef.current) === null || _a === void 0 ? void 0 : _a.call(onLongPressEndRef, event); } else if (triggerClick && onClickRef.current) { onClickRef.current(event); } isTriggeredRef.current = false; }; var onPointerDown = function onPointerDown(event) { if (activePointerIdRef.current !== undefined || event.isPrimary === false) { return; } activePointerIdRef.current = event.pointerId; if (hasMoveThreshold) { pervPositionRef.current.x = event.clientX; pervPositionRef.current.y = event.clientY; } createTimer(event); }; var onPointerUp = function onPointerUp(event) { if (activePointerIdRef.current !== event.pointerId) { return; } activePointerIdRef.current = undefined; finishPress(event); }; var onPointerCancel = function onPointerCancel(event) { if (activePointerIdRef.current !== event.pointerId) { return; } activePointerIdRef.current = undefined; finishPress(event, false); }; var onPointerMove = function onPointerMove(event) { if (activePointerIdRef.current === event.pointerId) { onMove(event); } }; var onTouchStart = function onTouchStart(event) { if (touchPressed.current) { return; } touchPressed.current = true; if (hasMoveThreshold) { var _getClientPosition2 = getClientPosition(event), clientX = _getClientPosition2.clientX, clientY = _getClientPosition2.clientY; pervPositionRef.current.x = clientX; pervPositionRef.current.y = clientY; } createTimer(event); }; var onMouseDown = function onMouseDown(event) { var _a; if ((_a = event === null || event === void 0 ? void 0 : event.sourceCapabilities) === null || _a === void 0 ? void 0 : _a.firesTouchEvents) { return; } mousePressed.current = true; if (hasMoveThreshold) { pervPositionRef.current.x = event.clientX; pervPositionRef.current.y = event.clientY; } createTimer(event); }; var onMove = function onMove(event) { if (timerRef.current && overThreshold(event)) { clearTimer(); } }; var onTouchEnd = function onTouchEnd(event) { if (!touchPressed.current) { return; } touchPressed.current = false; finishPress(event); }; var onMouseUp = function onMouseUp(event) { var _a; if ((_a = event === null || event === void 0 ? void 0 : event.sourceCapabilities) === null || _a === void 0 ? void 0 : _a.firesTouchEvents) { return; } if (!mousePressed.current) { return; } mousePressed.current = false; finishPress(event); }; var onMouseLeave = function onMouseLeave(event) { if (!mousePressed.current) { return; } mousePressed.current = false; finishPress(event, false); }; if (supportPointerEvent) { targetElement.addEventListener('pointerdown', onPointerDown); targetElement.addEventListener('pointerup', onPointerUp); targetElement.addEventListener('pointerleave', onPointerCancel); targetElement.addEventListener('pointercancel', onPointerCancel); if (hasMoveThreshold) { targetElement.addEventListener('pointermove', onPointerMove); } return function () { clearTimer(); isTriggeredRef.current = false; activePointerIdRef.current = undefined; targetElement.removeEventListener('pointerdown', onPointerDown); targetElement.removeEventListener('pointerup', onPointerUp); targetElement.removeEventListener('pointerleave', onPointerCancel); targetElement.removeEventListener('pointercancel', onPointerCancel); if (hasMoveThreshold) { targetElement.removeEventListener('pointermove', onPointerMove); } }; } var onTouchCancel = function onTouchCancel(event) { if (!touchPressed.current) { return; } touchPressed.current = false; finishPress(event, false); }; targetElement.addEventListener('mousedown', onMouseDown); targetElement.addEventListener('mouseup', onMouseUp); targetElement.addEventListener('mouseleave', onMouseLeave); targetElement.addEventListener('touchstart', onTouchStart); targetElement.addEventListener('touchend', onTouchEnd); targetElement.addEventListener('touchcancel', onTouchCancel); if (hasMoveThreshold) { targetElement.addEventListener('mousemove', onMove); targetElement.addEventListener('touchmove', onMove); } return function () { clearTimer(); isTriggeredRef.current = false; targetElement.removeEventListener('mousedown', onMouseDown); targetElement.removeEventListener('mouseup', onMouseUp); targetElement.removeEventListener('mouseleave', onMouseLeave); targetElement.removeEventListener('touchstart', onTouchStart); targetElement.removeEventListener('touchend', onTouchEnd); targetElement.removeEventListener('touchcancel', onTouchCancel); if (hasMoveThreshold) { targetElement.removeEventListener('mousemove', onMove); targetElement.removeEventListener('touchmove', onMove); } }; }, [], target); } var _default = exports["default"] = useLongPress;