UNPKG

react-native-reanimated

Version:

More powerful alternative to Animated library for React Native.

99 lines (91 loc) 3.47 kB
import type { RefObject } from 'react'; import type { NativeScrollEvent, NativeSyntheticEvent } from 'react-native'; import type { Context, NativeEvent, WorkletFunction } from '../commonTypes'; import type WorkletEventHandler from '../WorkletEventHandler'; import type { DependencyList } from './commonTypes'; import { useEvent, useHandler } from './Hooks'; export interface ScrollHandler<TContext extends Context> extends WorkletFunction { (event: NativeScrollEvent, context?: TContext): void; } export interface ScrollEvent extends NativeScrollEvent, NativeEvent<ScrollEvent> { eventName: string; } export interface ScrollHandlers<TContext extends Context> { [key: string]: ScrollHandler<TContext> | undefined; onScroll?: ScrollHandler<TContext>; onBeginDrag?: ScrollHandler<TContext>; onEndDrag?: ScrollHandler<TContext>; onMomentumBegin?: ScrollHandler<TContext>; onMomentumEnd?: ScrollHandler<TContext>; } // TODO TYPESCRIPT This is a temporary type to get rid of .d.ts file. type OnScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => void; // TODO TYPESCRIPT This is a temporary type to get rid of .d.ts file. export type useAnimatedScrollHandler = < TContext extends Context = Record<string, never> >( handlers: ScrollHandlers<TContext> | ScrollHandler<TContext>, deps?: DependencyList ) => OnScroll; export const useAnimatedScrollHandler = function <TContext extends Context>( handlers: ScrollHandlers<TContext> | ScrollHandler<TContext>, dependencies?: DependencyList ): RefObject<WorkletEventHandler<ScrollEvent>> { // case when handlers is a function const scrollHandlers: ScrollHandlers<TContext> = typeof handlers === 'function' ? { onScroll: handlers } : handlers; const { context, doDependenciesDiffer } = useHandler<ScrollEvent, TContext>( scrollHandlers, dependencies ); // build event subscription array const subscribeForEvents = ['onScroll']; if (scrollHandlers.onBeginDrag !== undefined) { subscribeForEvents.push('onScrollBeginDrag'); } if (scrollHandlers.onEndDrag !== undefined) { subscribeForEvents.push('onScrollEndDrag'); } if (scrollHandlers.onMomentumBegin !== undefined) { subscribeForEvents.push('onMomentumScrollBegin'); } if (scrollHandlers.onMomentumEnd !== undefined) { subscribeForEvents.push('onMomentumScrollEnd'); } return useEvent<ScrollEvent>( (event: ScrollEvent) => { 'worklet'; const { onScroll, onBeginDrag, onEndDrag, onMomentumBegin, onMomentumEnd, } = scrollHandlers; if (onScroll && event.eventName.endsWith('onScroll')) { onScroll(event, context); } else if (onBeginDrag && event.eventName.endsWith('onScrollBeginDrag')) { onBeginDrag(event, context); } else if (onEndDrag && event.eventName.endsWith('onScrollEndDrag')) { onEndDrag(event, context); } else if ( onMomentumBegin && event.eventName.endsWith('onMomentumScrollBegin') ) { onMomentumBegin(event, context); } else if ( onMomentumEnd && event.eventName.endsWith('onMomentumScrollEnd') ) { onMomentumEnd(event, context); } }, subscribeForEvents, doDependenciesDiffer // TODO TYPESCRIPT This temporary cast is to get rid of .d.ts file. ) as any; // TODO TYPESCRIPT This temporary cast is to get rid of .d.ts file. } as unknown as useAnimatedScrollHandler;