framer-motion
Version:
A simple and powerful React animation library
64 lines (61 loc) • 2.8 kB
JavaScript
import { useRef } from 'react';
import { isNodeOrChild } from './utils/is-node-or-child.mjs';
import { usePointerEvent, addPointerEvent } from '../events/use-pointer-event.mjs';
import { useUnmountEffect } from '../utils/use-unmount-effect.mjs';
import { pipe } from 'popmotion';
import { AnimationType } from '../render/utils/types.mjs';
import { isDragActive } from './drag/utils/lock.mjs';
/**
* @param handlers -
* @internal
*/
function useTapGesture(_a) {
var onTap = _a.onTap, onTapStart = _a.onTapStart, onTapCancel = _a.onTapCancel, whileTap = _a.whileTap, visualElement = _a.visualElement;
var hasPressListeners = onTap || onTapStart || onTapCancel || whileTap;
var isPressing = useRef(false);
var cancelPointerEndListeners = useRef(null);
function removePointerEndListener() {
var _a;
(_a = cancelPointerEndListeners.current) === null || _a === void 0 ? void 0 : _a.call(cancelPointerEndListeners);
cancelPointerEndListeners.current = null;
}
function checkPointerEnd() {
var _a;
removePointerEndListener();
isPressing.current = false;
(_a = visualElement.animationState) === null || _a === void 0 ? void 0 : _a.setActive(AnimationType.Tap, false);
return !isDragActive();
}
function onPointerUp(event, info) {
if (!checkPointerEnd())
return;
/**
* We only count this as a tap gesture if the event.target is the same
* as, or a child of, this component's element
*/
!isNodeOrChild(visualElement.getInstance(), event.target)
? onTapCancel === null || onTapCancel === void 0 ? void 0 : onTapCancel(event, info)
: onTap === null || onTap === void 0 ? void 0 : onTap(event, info);
}
function onPointerCancel(event, info) {
if (!checkPointerEnd())
return;
onTapCancel === null || onTapCancel === void 0 ? void 0 : onTapCancel(event, info);
}
function onPointerDown(event, info) {
var _a;
removePointerEndListener();
if (isPressing.current)
return;
isPressing.current = true;
cancelPointerEndListeners.current = pipe(addPointerEvent(window, "pointerup", onPointerUp), addPointerEvent(window, "pointercancel", onPointerCancel));
/**
* Ensure we trigger animations before firing event callback
*/
(_a = visualElement.animationState) === null || _a === void 0 ? void 0 : _a.setActive(AnimationType.Tap, true);
onTapStart === null || onTapStart === void 0 ? void 0 : onTapStart(event, info);
}
usePointerEvent(visualElement, "pointerdown", hasPressListeners ? onPointerDown : undefined);
useUnmountEffect(removePointerEndListener);
}
export { useTapGesture };