Repository navigation
[General] Allow explicit opt-in for the Animated codepaths when not using native driver #3824
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
adf6547
5e2c134
39706b9
1f8f7fd
e791e9d
0d0c505
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -126,13 +126,15 @@ export function InterceptingGestureDetector<THandlerData, TConfig>({ | |
| const createGestureEventHandler = useCallback( | ||
| (key: keyof DetectorCallbacks<THandlerData>) => { | ||
| return (e: GestureHandlerEvent<THandlerData>) => { | ||
| if (gesture?.detectorCallbacks[key]) { | ||
| if (typeof gesture?.detectorCallbacks[key] === 'function') { | ||
| // @ts-expect-error passing event to a union of functions where only one is typed as such | ||
| gesture.detectorCallbacks[key](e); | ||
| } | ||
|
|
||
| virtualChildren.forEach((child) => { | ||
| const method = child.methods[key]; | ||
| if (method) { | ||
| if (typeof method === 'function') { | ||
| // @ts-expect-error passing event to a union of functions where only one is typed as such | ||
|
Comment on lines
+129
to
+137
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Those types. |
||
| method(e); | ||
| } | ||
| }); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,38 @@ | ||
| import { useGestureStateChangeEvent } from './callbacks/js/useGestureStateChangeEvent'; | ||
| import { useGestureUpdateEvent } from './callbacks/js/useGestureUpdateEvent'; | ||
| import { useGestureTouchEvent } from './callbacks/js/useGestureTouchEvent'; | ||
| import { AnimatedEvent, BaseGestureConfig } from '../types'; | ||
| import { checkMappingForChangeProperties, isAnimatedEvent } from './utils'; | ||
| import { AnimatedEvent, BaseGestureConfig, GestureUpdateEvent } from '../types'; | ||
| import { | ||
| checkMappingForChangeProperties, | ||
| isNativeAnimatedEvent, | ||
| } from './utils'; | ||
| import { useReanimatedStateChangeEvent } from './callbacks/reanimated/useReanimatedStateChangeEvent'; | ||
| import { useReanimatedUpdateEvent } from './callbacks/reanimated/useReanimatedUpdateEvent'; | ||
| import { useReanimatedTouchEvent } from './callbacks/reanimated/useReanimatedTouchEvent'; | ||
| import { tagMessage } from '../../utils'; | ||
|
|
||
| function guardJSAnimatedEvent(handler: (...args: unknown[]) => void) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not a fun of this name, but I cannot think of any better. |
||
| return (...args: unknown[]) => { | ||
| try { | ||
| handler(...args); | ||
| } catch (e) { | ||
| if ( | ||
| e instanceof Error && | ||
| e.message.includes('Bad event of type undefined for key') | ||
| ) { | ||
| throw new Error( | ||
| tagMessage( | ||
| 'The event mapping inside an Animated.event is invalid. ' + | ||
| 'Please make sure you are using the correct structure for the gesture event:\n\n' + | ||
| '{ nativeEvent: { handlerData: { /* your mappings here */ } } }' | ||
| ) | ||
| ); | ||
| } | ||
|
|
||
| throw e; | ||
| } | ||
| }; | ||
| } | ||
|
|
||
| export function useGestureCallbacks<THandlerData, TConfig>( | ||
| handlerTag: number, | ||
|
|
@@ -31,10 +58,21 @@ export function useGestureCallbacks<THandlerData, TConfig>( | |
| onReanimatedTouchEvent = useReanimatedTouchEvent(handlerTag, config); | ||
| } | ||
|
|
||
| let onGestureHandlerAnimatedEvent: AnimatedEvent | undefined; | ||
| if (isAnimatedEvent(config.onUpdate)) { | ||
| checkMappingForChangeProperties(config.onUpdate); | ||
| onGestureHandlerAnimatedEvent = config.onUpdate; | ||
| let onGestureHandlerAnimatedEvent: | ||
| | ((event: GestureUpdateEvent<THandlerData>) => void) | ||
| | AnimatedEvent | ||
| | undefined; | ||
| if (config.dispatchesAnimatedEvents) { | ||
| if (__DEV__ && isNativeAnimatedEvent(config.onUpdate)) { | ||
| checkMappingForChangeProperties(config.onUpdate); | ||
| } | ||
|
|
||
| if (__DEV__ && !isNativeAnimatedEvent(config.onUpdate)) { | ||
| // @ts-expect-error At this point we know it's not a native animated event, so it's callable | ||
| onGestureHandlerAnimatedEvent = guardJSAnimatedEvent(config.onUpdate); | ||
| } else { | ||
| onGestureHandlerAnimatedEvent = config.onUpdate; | ||
| } | ||
| } | ||
|
|
||
| return { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,7 +25,9 @@ export type GestureCallbacks<THandlerData> = { | |
| event: GestureStateChangeEvent<THandlerData>, | ||
| didSucceed: boolean | ||
| ) => void; | ||
| onUpdate?: (event: GestureUpdateEvent<THandlerData>) => void | AnimatedEvent; | ||
| onUpdate?: | ||
| | ((event: GestureUpdateEvent<THandlerData>) => void) | ||
| | AnimatedEvent; | ||
|
Comment on lines
+28
to
+30
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of a function or an This was irritating, as it was the reason types in |
||
| onTouchesDown?: (event: GestureTouchEvent) => void; | ||
| onTouchesMove?: (event: GestureTouchEvent) => void; | ||
| onTouchesUp?: (event: GestureTouchEvent) => void; | ||
|
|
@@ -48,6 +50,7 @@ export type InternalConfigProps<THandlerData> = { | |
|
|
||
| export type CommonGestureConfig = { | ||
| disableReanimated?: boolean; | ||
| useAnimated?: boolean; | ||
| } & WithSharedValue< | ||
| { | ||
| runOnJS?: boolean; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -48,10 +48,10 @@ export type TouchEvent = | |
| | GestureTouchEvent | ||
| | NativeSyntheticEvent<GestureTouchEvent>; | ||
|
|
||
| // This is almost how Animated.event is typed in React Native. We add _argMapping in order to: | ||
| // 1. Distinguish it from a regular function, | ||
| // 2. Have access to the _argMapping property to check for usage of `change*` callbacks. | ||
| export type AnimatedEvent = ((...args: any[]) => void) & { | ||
| // This is not how Animated.event is typed in React Native. We add _argMapping in order to | ||
| // have access to the _argMapping property to check for usage of `change*` callbacks. | ||
| // It's also not typed as a function, which is breaking Gesture Handler type definitions. | ||
| export type AnimatedEvent = { | ||
| _argMapping: (Animated.Mapping | null)[]; | ||
| }; | ||
|
Comment on lines
+54
to
56
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After fixing the type above, this started breaking type inference and every |
||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is also covering
undefinedcheck,typeof undefined === 'undefined'