diff --git a/__typetests__/common/useComposedEventHandlerTest.tsx b/__typetests__/common/useComposedEventHandlerTest.tsx new file mode 100644 index 00000000000..20dc975bc89 --- /dev/null +++ b/__typetests__/common/useComposedEventHandlerTest.tsx @@ -0,0 +1,92 @@ +/* eslint-disable no-unused-expressions */ +/* eslint-disable @typescript-eslint/no-empty-function */ +/* eslint-disable @typescript-eslint/ban-ts-comment */ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import React from 'react'; +import Animated, { + useAnimatedScrollHandler, + useComposedEventHandler, + useEvent, +} from '../..'; +import { Text } from 'react-native'; +import type { ReanimatedEvent } from '../..'; + +function useComposedEventHandlerTest() { + function useComposedEventHandlerTestDifferentHandlers() { + function useCustomScrollHandler( + handler: (event: ReanimatedEvent) => void + ) { + return useEvent( + (event) => { + 'worklet'; + handler(event); + }, + ['onScroll'] + ); + } + + const onScrollCustomHandler = useCustomScrollHandler((e) => { + 'worklet'; + console.log(`custom scroll handler invoked on ${e.eventName}`); + }); + + const onScrollHandler = useAnimatedScrollHandler((e) => { + console.log(`scroll handler invoked on ${e.eventName}`); + }); + + const composedHandler = useComposedEventHandler([ + onScrollHandler, + onScrollCustomHandler, + ]); + + return ( + <> + + {[...new Array(20)].map((_each, index) => ( + {index} + ))} + + + ); + } + + function useComposedEventHandlerTestDifferentProps() { + const onDragBeginHandler = useAnimatedScrollHandler({ + onBeginDrag(e) { + 'worklet'; + console.log('Drag begin'); + }, + }); + + const onDragEndHandler = useAnimatedScrollHandler({ + onEndDrag(e) { + 'worklet'; + console.log('Drag end'); + }, + }); + + const composedHandler1 = useComposedEventHandler([ + onDragBeginHandler, + onDragEndHandler, + ]); + + const composedHandler2 = useComposedEventHandler([ + onDragBeginHandler, + onDragEndHandler, + ]); + + return ( + <> + + {[...new Array(20)].map((_each, index) => ( + {index} + ))} + + + ); + } +} diff --git a/app/src/examples/ComposedHandlerConditionalExample.tsx b/app/src/examples/ComposedHandlerConditionalExample.tsx new file mode 100644 index 00000000000..f8c8e030bd8 --- /dev/null +++ b/app/src/examples/ComposedHandlerConditionalExample.tsx @@ -0,0 +1,147 @@ +import React from 'react'; +import { Text, View, StyleSheet, Button } from 'react-native'; +import Animated, { + useAnimatedScrollHandler, + useComposedEventHandler, +} from 'react-native-reanimated'; + +export default function ComposedHandlerConditionalExample() { + const [toggleFirst, setToggleFirst] = React.useState(true); + const [toggleSecond, setToggleSecond] = React.useState(true); + const [toggleThird, setToggleThird] = React.useState(true); + + const handlerFunc = React.useCallback( + (handlerName: string, eventName: string) => { + 'worklet'; + console.log(`${handlerName} handler: ${eventName}`); + }, + [] + ); + + const firstHandler = useAnimatedScrollHandler({ + onScroll(e) { + handlerFunc('first', e.eventName); + }, + }); + + const secondHandler = useAnimatedScrollHandler({ + onScroll(e) { + handlerFunc('second', e.eventName); + }, + }); + + const thirdHandler = useAnimatedScrollHandler({ + onScroll(e) { + handlerFunc('third', e.eventName); + }, + }); + + const composedHandler = useComposedEventHandler([ + toggleFirst ? firstHandler : null, + toggleSecond ? secondHandler : null, + toggleThird ? thirdHandler : null, + ]); + + return ( + + Check console logs! + setToggleFirst(!toggleFirst)} + /> + setToggleSecond(!toggleSecond)} + /> + setToggleThird(!toggleThird)} + /> + } + keyExtractor={(item) => `A:${item.title}`} + /> + + ); +} + +type ToggleProps = { + name: string; + isToggled: boolean; + onPressFunc: () => void; +}; +const ToggleButton = ({ name, isToggled, onPressFunc }: ToggleProps) => ( + + +