diff --git a/packages/react-native-gesture-handler/src/__tests__/RelationsTraversal.test.tsx b/packages/react-native-gesture-handler/src/__tests__/RelationsTraversal.test.tsx index fb8128dbdd..dbb7001b15 100644 --- a/packages/react-native-gesture-handler/src/__tests__/RelationsTraversal.test.tsx +++ b/packages/react-native-gesture-handler/src/__tests__/RelationsTraversal.test.tsx @@ -1,7 +1,7 @@ import { tagMessage } from '../utils'; import { useExclusive, useRace, useSimultaneous } from '../v3/hooks/relations'; import { useGesture } from '../v3/hooks/useGesture'; -import { configureRelations } from '../v3/NativeDetector/utils'; +import { configureRelations } from '../v3/detectors/utils'; import { SingleGesture, SingleGestureName } from '../v3/types'; import { renderHook } from '@testing-library/react-native'; diff --git a/packages/react-native-gesture-handler/src/index.ts b/packages/react-native-gesture-handler/src/index.ts index 8c9d8b0ef3..2b374e64e1 100644 --- a/packages/react-native-gesture-handler/src/index.ts +++ b/packages/react-native-gesture-handler/src/index.ts @@ -162,10 +162,8 @@ export type { } from './components/DrawerLayout'; export { default as DrawerLayout } from './components/DrawerLayout'; -export type { NativeDetectorProps } from './v3/NativeDetector/NativeDetector'; -export { NativeDetector } from './v3/NativeDetector/NativeDetector'; +export * from './v3/detectors'; -export { LogicDetector } from './v3/LogicDetector'; export * from './v3/hooks/useGesture'; export * from './v3/hooks/relations'; diff --git a/packages/react-native-gesture-handler/src/v3/NativeDetector/HostGestureDetector.tsx b/packages/react-native-gesture-handler/src/v3/detectors/HostGestureDetector.tsx similarity index 100% rename from packages/react-native-gesture-handler/src/v3/NativeDetector/HostGestureDetector.tsx rename to packages/react-native-gesture-handler/src/v3/detectors/HostGestureDetector.tsx diff --git a/packages/react-native-gesture-handler/src/v3/NativeDetector/HostGestureDetector.web.tsx b/packages/react-native-gesture-handler/src/v3/detectors/HostGestureDetector.web.tsx similarity index 100% rename from packages/react-native-gesture-handler/src/v3/NativeDetector/HostGestureDetector.web.tsx rename to packages/react-native-gesture-handler/src/v3/detectors/HostGestureDetector.web.tsx diff --git a/packages/react-native-gesture-handler/src/v3/NativeDetector/NativeDetector.tsx b/packages/react-native-gesture-handler/src/v3/detectors/LogicDetector/DelegateDetector.tsx similarity index 77% rename from packages/react-native-gesture-handler/src/v3/NativeDetector/NativeDetector.tsx rename to packages/react-native-gesture-handler/src/v3/detectors/LogicDetector/DelegateDetector.tsx index 6bd6b3a120..dd370e9e04 100644 --- a/packages/react-native-gesture-handler/src/v3/NativeDetector/NativeDetector.tsx +++ b/packages/react-native-gesture-handler/src/v3/detectors/LogicDetector/DelegateDetector.tsx @@ -1,30 +1,18 @@ import React, { RefObject, useCallback, useRef, useState } from 'react'; -import { Animated, StyleSheet } from 'react-native'; -import HostGestureDetector from './HostGestureDetector'; -import { tagMessage } from '../../utils'; -import { - LogicChildren, - Gesture, - GestureEvents, - GestureHandlerEvent, -} from '../types'; +import HostGestureDetector from '../HostGestureDetector'; +import { LogicChildren, GestureEvents, GestureHandlerEvent } from '../../types'; import { DetectorContext } from './useDetectorContext'; -import { Reanimated } from '../../handlers/gestures/reanimatedWrapper'; -import { configureRelations } from './utils'; -import { isComposedGesture } from '../hooks/utils/relationUtils'; - -export interface NativeDetectorProps { - children?: React.ReactNode; - gesture: Gesture; -} - -const AnimatedNativeDetector = - Animated.createAnimatedComponent(HostGestureDetector); - -const ReanimatedNativeDetector = - Reanimated?.default.createAnimatedComponent(HostGestureDetector); +import { Reanimated } from '../../../handlers/gestures/reanimatedWrapper'; +import { configureRelations, ensureNativeDetectorComponent } from '../utils'; +import { isComposedGesture } from '../../hooks/utils/relationUtils'; +import { + AnimatedNativeDetector, + NativeDetectorProps, + nativeDetectorStyles, + ReanimatedNativeDetector, +} from '../common'; -export function NativeDetector({ +export function DelegateDetector({ gesture, children, }: NativeDetectorProps) { @@ -63,17 +51,6 @@ export function NativeDetector({ setLogicChildren((prev) => prev.filter((c) => c.viewTag !== childTag)); }, []); - // It might happen only with ReanimatedNativeDetector - if (!NativeDetectorComponent) { - throw new Error( - tagMessage( - 'Gesture expects to run on the UI thread, but failed to create the Reanimated NativeDetector.' - ) - ); - } - - configureRelations(gesture); - const handleGestureEvent = (key: keyof GestureEvents) => { return (e: GestureHandlerEvent) => { if (gesture.gestureEvents[key]) { @@ -125,6 +102,9 @@ export function NativeDetector({ getHandlers('onReanimatedTouchEvent') ); + ensureNativeDetectorComponent(NativeDetectorComponent); + configureRelations(gesture); + return ( ({ onGestureHandlerReanimatedTouchEvent={reanimatedTouchEventHandler} moduleId={globalThis._RNGH_MODULE_ID} handlerTags={isComposedGesture(gesture) ? gesture.tags : [gesture.tag]} - style={styles.detector} + style={nativeDetectorStyles.detector} logicChildren={logicChildren}> {children} ); } - -const styles = StyleSheet.create({ - detector: { - display: 'contents', - // TODO: remove, debug info only - backgroundColor: 'red', - }, -}); diff --git a/packages/react-native-gesture-handler/src/v3/LogicDetector.tsx b/packages/react-native-gesture-handler/src/v3/detectors/LogicDetector/LogicDetector.tsx similarity index 83% rename from packages/react-native-gesture-handler/src/v3/LogicDetector.tsx rename to packages/react-native-gesture-handler/src/v3/detectors/LogicDetector/LogicDetector.tsx index c24bdb9b00..87004dea6d 100644 --- a/packages/react-native-gesture-handler/src/v3/LogicDetector.tsx +++ b/packages/react-native-gesture-handler/src/v3/detectors/LogicDetector/LogicDetector.tsx @@ -1,10 +1,10 @@ import { RefObject, useCallback, useEffect, useRef, useState } from 'react'; -import { Wrap } from '../handlers/gestures/GestureDetector/Wrap'; +import { Wrap } from '../../../handlers/gestures/GestureDetector/Wrap'; import { findNodeHandle, Platform } from 'react-native'; -import { useDetectorContext } from './NativeDetector/useDetectorContext'; -import { NativeDetectorProps } from './NativeDetector/NativeDetector'; -import { isComposedGesture } from './hooks/utils/relationUtils'; -import { GestureEvents } from './types'; +import { useDetectorContext } from './useDetectorContext'; +import { isComposedGesture } from '../../hooks/utils/relationUtils'; +import { GestureEvents } from '../../types'; +import { NativeDetectorProps } from '../common'; export function LogicDetector( props: NativeDetectorProps diff --git a/packages/react-native-gesture-handler/src/v3/NativeDetector/useDetectorContext.ts b/packages/react-native-gesture-handler/src/v3/detectors/LogicDetector/useDetectorContext.ts similarity index 73% rename from packages/react-native-gesture-handler/src/v3/NativeDetector/useDetectorContext.ts rename to packages/react-native-gesture-handler/src/v3/detectors/LogicDetector/useDetectorContext.ts index 97c2c90dec..869c2a1904 100644 --- a/packages/react-native-gesture-handler/src/v3/NativeDetector/useDetectorContext.ts +++ b/packages/react-native-gesture-handler/src/v3/detectors/LogicDetector/useDetectorContext.ts @@ -1,5 +1,5 @@ import { createContext, RefObject, useContext } from 'react'; -import { GestureEvents, LogicChildren } from '../types'; +import { GestureEvents, LogicChildren } from '../../types'; type DetectorContextType = { register: ( @@ -14,7 +14,9 @@ export const DetectorContext = createContext(null); export function useDetectorContext() { const ctx = useContext(DetectorContext); if (!ctx) { - throw new Error('Logic detector must be a descendant of a Native Detector'); + throw new Error( + 'Logic detector must be a descendant of a delegate detector' + ); } return ctx; } diff --git a/packages/react-native-gesture-handler/src/v3/detectors/NativeDetector.tsx b/packages/react-native-gesture-handler/src/v3/detectors/NativeDetector.tsx new file mode 100644 index 0000000000..41e73c144a --- /dev/null +++ b/packages/react-native-gesture-handler/src/v3/detectors/NativeDetector.tsx @@ -0,0 +1,58 @@ +import React from 'react'; +import HostGestureDetector from './HostGestureDetector'; +import { configureRelations, ensureNativeDetectorComponent } from './utils'; +import { isComposedGesture } from '../hooks/utils/relationUtils'; +import { + AnimatedNativeDetector, + NativeDetectorProps, + nativeDetectorStyles, + ReanimatedNativeDetector, +} from './common'; + +export function NativeDetector({ + gesture, + children, +}: NativeDetectorProps) { + const NativeDetectorComponent = gesture.config.dispatchesAnimatedEvents + ? AnimatedNativeDetector + : gesture.config.shouldUseReanimated + ? ReanimatedNativeDetector + : HostGestureDetector; + + ensureNativeDetectorComponent(NativeDetectorComponent); + configureRelations(gesture); + + return ( + + {children} + + ); +} diff --git a/packages/react-native-gesture-handler/src/v3/detectors/common.ts b/packages/react-native-gesture-handler/src/v3/detectors/common.ts new file mode 100644 index 0000000000..f1543572f3 --- /dev/null +++ b/packages/react-native-gesture-handler/src/v3/detectors/common.ts @@ -0,0 +1,24 @@ +import React from 'react'; +import { Gesture } from '../types'; +import { Reanimated } from '../../handlers/gestures/reanimatedWrapper'; +import { Animated, StyleSheet } from 'react-native'; +import HostGestureDetector from './HostGestureDetector'; + +export interface NativeDetectorProps { + children?: React.ReactNode; + gesture: Gesture; +} + +export const AnimatedNativeDetector = + Animated.createAnimatedComponent(HostGestureDetector); + +export const ReanimatedNativeDetector = + Reanimated?.default.createAnimatedComponent(HostGestureDetector); + +export const nativeDetectorStyles = StyleSheet.create({ + detector: { + display: 'contents', + // TODO: remove, debug info only + backgroundColor: 'red', + }, +}); diff --git a/packages/react-native-gesture-handler/src/v3/detectors/index.ts b/packages/react-native-gesture-handler/src/v3/detectors/index.ts new file mode 100644 index 0000000000..1bac824c82 --- /dev/null +++ b/packages/react-native-gesture-handler/src/v3/detectors/index.ts @@ -0,0 +1,5 @@ +export type { NativeDetectorProps } from './common'; +export { NativeDetector } from './NativeDetector'; + +export { LogicDetector } from './LogicDetector/LogicDetector'; +export { DelegateDetector } from './LogicDetector/DelegateDetector'; diff --git a/packages/react-native-gesture-handler/src/v3/NativeDetector/utils.ts b/packages/react-native-gesture-handler/src/v3/detectors/utils.ts similarity index 94% rename from packages/react-native-gesture-handler/src/v3/NativeDetector/utils.ts rename to packages/react-native-gesture-handler/src/v3/detectors/utils.ts index d6abd31075..cdf442e592 100644 --- a/packages/react-native-gesture-handler/src/v3/NativeDetector/utils.ts +++ b/packages/react-native-gesture-handler/src/v3/detectors/utils.ts @@ -5,6 +5,7 @@ // For `simultaneousHandlers` we use Set as the order doesn't matter. import RNGestureHandlerModule from '../../RNGestureHandlerModule'; +import { tagMessage } from '../../utils'; import { isComposedGesture, prepareRelations, @@ -150,4 +151,16 @@ export function configureRelations( RNGestureHandlerModule.flushOperations(); } +export function ensureNativeDetectorComponent( + NativeDetectorComponent: unknown +): asserts NativeDetectorComponent { + if (!NativeDetectorComponent) { + throw new Error( + tagMessage( + 'Gesture expects to run on the UI thread, but failed to create the Reanimated NativeDetector.' + ) + ); + } +} + export const EMPTY_SET = new Set();