Conversation
There was a problem hiding this comment.
Pull request overview
This pull request introduces a new type parameter TBaseHandlerData to distinguish between base gesture handler data (available in lifecycle callbacks onBegin and onFinalize) and full handler data (available in active phase callbacks onActivate, onUpdate, and onDeactivate). This provides more precise typing for gesture lifecycle callbacks, as computed properties like changeX, changeY, rotationChange, etc. are only available during the active gesture phase.
Changes:
- Added
TBaseHandlerDatatype parameter to all gesture types and configurations - Created
OptionalPropsutility type for cases where computed properties may be absent - Refactored all gesture implementations (Pan, Hover, Rotation, Pinch, Tap, Fling, LongPress, Manual, Native) to separate base and computed handler data
- Updated all utility functions, hooks, and callback handlers to support the new type parameter
Reviewed changes
Copilot reviewed 33 out of 33 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| UtilityTypes.ts | Added OptionalProps utility type for making specific properties optional |
| NativeWrapperType.ts | Updated GestureCallbacks to use both base and full handler data types |
| GestureTypes.ts | Added TBaseHandlerData parameter to all gesture-related types (BaseGestureConfig, SingleGesture, etc.) |
| ConfigTypes.ts | Updated GestureCallbacks definition with separate types for lifecycle vs active callbacks; reordered properties logically |
| usePanGesture.ts | Split PanHandlerData into PanBaseHandlerData and computed properties (changeX, changeY) |
| useHoverGesture.ts | Split HoverHandlerData into HoverBaseHandlerData and computed properties |
| useRotationGesture.ts | Split RotationHandlerData into RotationBaseHandlerData and computed properties |
| usePinchGesture.ts | Split PinchHandlerData into PinchBaseHandlerData and computed properties |
| useTapGesture.ts | Updated type parameters (no split needed as Tap has no computed properties) |
| useFlingGesture.ts | Updated type parameters (no split needed as Fling has no computed properties) |
| useLongPressGesture.ts | Updated type parameters (no split needed as LongPress has no computed properties) |
| useManualGesture.ts | Updated type parameters (no split needed as Manual has no computed properties) |
| useNativeGesture.ts | Updated type parameters (no split needed as Native has no computed properties) |
| All utility/helper files | Updated function signatures to accept TBaseHandlerData parameter |
| All callback handler files | Updated to properly type callbacks with base vs full handler data |
| NativeProxy.ts & NativeProxy.web.ts | Updated proxy methods to support new type parameter |
| Pressable utils.ts | Used OptionalProps to handle HoverGestureEvent in onBegin context where change properties are optional |
| jestUtils.ts | Updated SingleGesture type references to include three type parameters |
| handlersRegistry.ts | Updated registerGesture signature |
| reanimatedWrapper.ts | Updated useHandler signature |
| RelationsTraversal.test.tsx | Updated test type annotations to use three-parameter SingleGesture type |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 43 out of 43 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
packages/react-native-gesture-handler/src/v3/hooks/callbacks/eventHandler.ts
Show resolved
Hide resolved
packages/react-native-gesture-handler/src/v3/hooks/gestures/hover/useHoverGesture.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 63 out of 63 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
packages/react-native-gesture-handler/src/v3/index.ts:39
- The newly introduced
*GestureActiveEventtypes (TapGestureActiveEvent, FlingGestureActiveEvent, LongPressGestureActiveEvent, etc.) are not exported from the main v3/index.ts file. These types should be added to the export statement to make them available to consumers of the library who import from the main package. This would allow users to properly type their event handlers when they use the extended handler data.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
packages/react-native-gesture-handler/src/v3/types/UtilityTypes.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 63 out of 63 changed files in this pull request and generated 10 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
packages/react-native-gesture-handler/src/v3/createNativeWrapper.tsx
Outdated
Show resolved
Hide resolved
packages/react-native-gesture-handler/src/components/Pressable/utils.ts
Outdated
Show resolved
Hide resolved
| onBegin?: GestureEventCallback<THandlerData>; | ||
| onActivate?: GestureEventCallback<THandlerData>; | ||
| onDeactivate?: GestureEventCallbackWithDidSucceed<THandlerData>; | ||
| onActivate?: GestureEventCallback<TExtendedHandlerData>; | ||
| onUpdate?: GestureEventCallback<TExtendedHandlerData> | AnimatedEvent; | ||
| onDeactivate?: GestureEventCallbackWithDidSucceed<TExtendedHandlerData>; | ||
| onFinalize?: GestureEventCallbackWithDidSucceed<THandlerData>; |
There was a problem hiding this comment.
onActivate and onDeactivate are typed to receive TExtendedHandlerData, but these callbacks are invoked from state-change events (see handleStateChangeEvent → flattenAndFilterEvent), which only carry the base handler data (no computed change* fields). This makes the public typing unsound (it suggests properties exist that will be missing at runtime). Consider typing onActivate/onDeactivate with THandlerData (keeping onUpdate on TExtendedHandlerData).
There was a problem hiding this comment.
This might be right, maybe we should fill it with neutral values? (cc @j-piasecki)
There was a problem hiding this comment.
I thought we already decided to do it, no?
There was a problem hiding this comment.
We talked about doing it, true. I just wanted to confirm that we want to.
packages/react-native-gesture-handler/src/v3/components/GestureComponents.tsx
Outdated
Show resolved
Hide resolved
| export interface VirtualDetectorProps<TConfig, THandlerData> { | ||
| children?: React.ReactNode; | ||
| gesture: Gesture<THandlerData, TConfig>; | ||
| gesture: Gesture<TConfig, THandlerData>; |
There was a problem hiding this comment.
Doesn't this one also need TExtendedHandlerData?
| translationX: number; | ||
| translationY: number; | ||
| velocityX: number; | ||
| velocityY: number; |
There was a problem hiding this comment.
Shouldn't this also be in the extended one?
| scale: number; | ||
| velocity: number; |
| rotation: number; | ||
| velocity: number; |
Description
This PR splits
HandlerDatatype intoHandlerDataandExtendedHandlerData. This allows us to hidechange*properties from callbacks that shouldn't have them in theireventparameter. It also removesanchorandfocalfromrotationandpinchfromonBeginandonFinalizecallbacks.Test plan
yarn ts-checkyarn lint-jsTest code
I've not attached gestures as this is type only change. However, they were tested on expo-example.