UNPKG

react-native-gesture-handler

Version:

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

94 lines (82 loc) 2.6 kB
import { Reanimated } from '../../../handlers/gestures/reanimatedWrapper'; import { tagMessage } from '../../../utils'; import type { AnyGesture, ComposedGesture, ComposedGestureConfig, ComposedGestureName, GestureHandlerEventWithHandlerData, } from '../../types'; import { containsDuplicates, isComposedGesture } from '../utils'; // TODO: Simplify repeated relations (Simultaneous with Simultaneous, Exclusive with Exclusive, etc.) export function useComposedGesture( type: ComposedGestureName, ...gestures: AnyGesture[] ): ComposedGesture { const handlerTags = gestures.flatMap((gesture) => isComposedGesture(gesture) ? gesture.handlerTags : [gesture.handlerTag] ); if (containsDuplicates(handlerTags)) { throw new Error( tagMessage( 'Each gesture can be used only once in the gesture composition.' ) ); } const config: ComposedGestureConfig = { shouldUseReanimatedDetector: gestures.some( (gesture) => gesture.config.shouldUseReanimatedDetector ), dispatchesAnimatedEvents: gestures.some( (gesture) => gesture.config.dispatchesAnimatedEvents ), }; if (config.shouldUseReanimatedDetector && config.dispatchesAnimatedEvents) { throw new Error( tagMessage( 'Composed gestures cannot use both Reanimated and Animated events at the same time.' ) ); } const jsEventHandler = ( event: GestureHandlerEventWithHandlerData<unknown, unknown> ) => { for (const gesture of gestures) { if (gesture.detectorCallbacks.jsEventHandler) { gesture.detectorCallbacks.jsEventHandler(event); } } }; const reanimatedEventHandler = Reanimated?.useComposedEventHandler( gestures.map( (gesture) => gesture.detectorCallbacks.reanimatedEventHandler || null ) ); let animatedEventHandler; const gesturesWithAnimatedEvent = gestures.filter( (gesture) => gesture.detectorCallbacks.animatedEventHandler !== undefined ); if (gesturesWithAnimatedEvent.length > 0) { animatedEventHandler = gesturesWithAnimatedEvent[0].detectorCallbacks.animatedEventHandler; if (__DEV__ && gesturesWithAnimatedEvent.length > 1) { console.warn( tagMessage( 'Composed gesture can handle only one Animated event. The first one will be used, others will be ignored.' ) ); } } return { handlerTags, type, config, detectorCallbacks: { jsEventHandler, reanimatedEventHandler, animatedEventHandler, }, externalSimultaneousHandlers: [], gestures, }; }