Skip to content

Split HandlerData#3980

Open
m-bert wants to merge 13 commits intomainfrom
@mbert/split-change-properties
Open

Split HandlerData#3980
m-bert wants to merge 13 commits intomainfrom
@mbert/split-change-properties

Conversation

@m-bert
Copy link
Contributor

@m-bert m-bert commented Feb 16, 2026

Description

This PR splits HandlerData type into HandlerData and ExtendedHandlerData. This allows us to hide change* properties from callbacks that shouldn't have them in their event parameter. It also removes anchor and focal from rotation and pinch from onBegin and onFinalize callbacks.

Test plan

  • yarn ts-check
  • yarn lint-js
Test code

I've not attached gestures as this is type only change. However, they were tested on expo-example.

import React from 'react';
import { View } from 'react-native';
import { usePanGesture, usePinchGesture } from 'react-native-gesture-handler';

export default function EmptyExample() {
  const pan = usePanGesture({
    onBegin: (e) => {
      console.log('pan begin', e.translationX);
    },
    onUpdate: (e) => {
      console.log('pan update', e.changeX);
    },
  });

  const pinch = usePinchGesture({
    onBegin: (e) => {
      console.log('pinch begin', e.scale, e);
    },
    onUpdate: (e) => {
      console.log('pinch update', e.scaleChange, e.focalX);
    },
  });

  console.log(pan, pinch);

  return <View />;
}

Copilot AI review requested due to automatic review settings February 16, 2026 11:53
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 TBaseHandlerData type parameter to all gesture types and configurations
  • Created OptionalProps utility 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.

@m-bert m-bert changed the title Add BaseHandlerData Split HandlerData Feb 17, 2026
@m-bert m-bert requested a review from Copilot February 17, 2026 08:57
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 *GestureActiveEvent types (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.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines 31 to 35
onBegin?: GestureEventCallback<THandlerData>;
onActivate?: GestureEventCallback<THandlerData>;
onDeactivate?: GestureEventCallbackWithDidSucceed<THandlerData>;
onActivate?: GestureEventCallback<TExtendedHandlerData>;
onUpdate?: GestureEventCallback<TExtendedHandlerData> | AnimatedEvent;
onDeactivate?: GestureEventCallbackWithDidSucceed<TExtendedHandlerData>;
onFinalize?: GestureEventCallbackWithDidSucceed<THandlerData>;
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

onActivate and onDeactivate are typed to receive TExtendedHandlerData, but these callbacks are invoked from state-change events (see handleStateChangeEventflattenAndFilterEvent), 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).

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be right, maybe we should fill it with neutral values? (cc @j-piasecki)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we already decided to do it, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We talked about doing it, true. I just wanted to confirm that we want to.

@m-bert m-bert marked this pull request as ready for review February 17, 2026 10:48
export interface VirtualDetectorProps<TConfig, THandlerData> {
children?: React.ReactNode;
gesture: Gesture<THandlerData, TConfig>;
gesture: Gesture<TConfig, THandlerData>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this one also need TExtendedHandlerData?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably it needs. Added in 67b69a7

Comment on lines +135 to +138
translationX: number;
translationY: number;
velocityX: number;
velocityY: number;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this also be in the extended one?

Comment on lines +11 to +12
scale: number;
velocity: number;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same

Comment on lines +11 to +12
rotation: number;
velocity: number;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments