UNPKG

react-native-gesture-handler

Version:

Declarative API exposing native platform touch and gesture system to React Native

75 lines (73 loc) 3.03 kB
"use strict"; import { useCallback, useEffect, useRef, useState } from 'react'; import { findNodeHandle, Platform } from 'react-native'; import { Wrap } from '../../../handlers/gestures/GestureDetector/Wrap'; import { tagMessage } from '../../../utils'; import { isComposedGesture } from '../../hooks/utils/relationUtils'; import { useGestureRelationsUpdater } from '../useGestureRelationsUpdater'; import { useNativeGestureRole } from '../useNativeGestureRole'; import { InterceptingDetectorMode, useInterceptingDetectorContext } from './useInterceptingDetectorContext'; import { jsx as _jsx } from "react/jsx-runtime"; function useRequiredInterceptingDetectorContext() { const context = useInterceptingDetectorContext(); if (!context) { throw new Error(tagMessage('VirtualGestureDetector must be a descendant of an InterceptingGestureDetector')); } return context; } export function VirtualDetector(props) { // Don't memoize virtual detectors to be able to listen to changes in children // TODO: replace with MutationObserver when it rolls out in React Native 'use no memo'; const { register, unregister, setMode } = useRequiredInterceptingDetectorContext(); const viewRef = useRef(null); const [viewTag, setViewTag] = useState(-1); const handleRef = useCallback(node => { viewRef.current = node; if (node) { const tag = Platform.OS === 'web' ? node : findNodeHandle(node); setViewTag(tag ?? -1); } else { setViewTag(-1); } }, // Invalid dependency array to change the function when children change // eslint-disable-next-line react-hooks/exhaustive-deps [props.children]); useNativeGestureRole(viewRef, props.children); useEffect(() => { if (viewTag === -1) { return; } const handlerTags = isComposedGesture(props.gesture) ? props.gesture.handlerTags : [props.gesture.handlerTag]; if (props.gesture.config.dispatchesAnimatedEvents) { throw new Error(tagMessage('VirtualGestureDetector cannot handle Animated events with native driver when used inside InterceptingGestureDetector. Use Reanimated or Animated events without native driver instead.')); } else if (props.gesture.config.shouldUseReanimatedDetector) { setMode(InterceptingDetectorMode.REANIMATED); } const virtualChild = { viewTag, handlerTags, methods: props.gesture.detectorCallbacks, // used by HostGestureDetector on web viewRef: Platform.OS === 'web' ? viewRef : undefined, userSelect: props.userSelect, touchAction: props.touchAction, enableContextMenu: props.enableContextMenu }; register(virtualChild); return () => { unregister(virtualChild); }; }, [viewTag, props.gesture, props.userSelect, props.touchAction, props.enableContextMenu, register, unregister, setMode]); useGestureRelationsUpdater(props.gesture); return /*#__PURE__*/_jsx(Wrap, { ref: handleRef, children: props.children }); } //# sourceMappingURL=VirtualDetector.js.map