From 3b863f5e327728c6981b094920e0d9a89409ef51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Wed, 4 Feb 2026 13:10:45 +0100 Subject: [PATCH 1/9] Update migration guide --- .../docs/guides/upgrading-to-3.mdx | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx b/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx index e25157ed6d..bf3dd1b5ca 100644 --- a/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx +++ b/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx @@ -85,6 +85,35 @@ code2={ `} /> +### onChange + +We decided to simplify API by removing `onChange` callback. You can now access `change*` properties in `onUpdate` callback. + + { + console.log(e.changeX); +}); +`} +code2={ +`const pan = usePanGesture({ + onUpdate: (e) => { + console.log(e.changeX); + }, +}); +`} +/> + +### state & oldState + +The `state` and `oldState` properties are no longer available in event objects. Tracking state changes can now only be accomplished using the appropriate [callbacks](/docs/fundamentals/callbacks-events). + +### Event types + +The types of events have been unified for all callbacks. Each event falls into one of two categories: [`GestureEvent`](/docs/fundamentals/callbacks-events#gestureevent) for gesture callbacks, or [`GestureTouchEvent`](/docs/fundamentals/callbacks-events#touchevent) for `TouchEvent` callbacks. + ### StateManager In Gesture Handler 3, `stateManager` is no longer passed to `TouchEvent` callbacks. Instead, you should use the global [`GestureStateManager`](/docs/fundamentals/state-manager). From e2001e1aa6b959e3176c280b70189d872c5debb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Wed, 4 Feb 2026 13:11:42 +0100 Subject: [PATCH 2/9] Cancelled to cancel --- .../docs/fundamentals/callbacks-events.mdx | 4 ++-- .../docs-gesture-handler/docs/gestures/use-manual-gesture.mdx | 2 +- .../src/examples/CallbacksFlowCharts/TouchEventChart.jsx | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/docs-gesture-handler/docs/fundamentals/callbacks-events.mdx b/packages/docs-gesture-handler/docs/fundamentals/callbacks-events.mdx index e556caa5b0..4c6b121b9b 100644 --- a/packages/docs-gesture-handler/docs/fundamentals/callbacks-events.mdx +++ b/packages/docs-gesture-handler/docs/fundamentals/callbacks-events.mdx @@ -93,10 +93,10 @@ onTouchesUp: (event: GestureTouchEvent) => void Called when pointers are lifted from the screen. It may carry information about more than one pointer because the events are batched. -### onTouchesCancelled +### onTouchesCancel ```ts -onTouchesCancelled: (event: GestureTouchEvent) => void +onTouchesCancel: (event: GestureTouchEvent) => void ``` Called when there will be no more information about this pointer. It may be called because the gesture has ended or was interrupted. It may carry information about more than one pointer because the events are batched. diff --git a/packages/docs-gesture-handler/docs/gestures/use-manual-gesture.mdx b/packages/docs-gesture-handler/docs/gestures/use-manual-gesture.mdx index edbf89b89b..84e779cea1 100644 --- a/packages/docs-gesture-handler/docs/gestures/use-manual-gesture.mdx +++ b/packages/docs-gesture-handler/docs/gestures/use-manual-gesture.mdx @@ -59,7 +59,7 @@ To demonstrate how to make a manual gesture we will make a simple one that track We also need to handle lifting fingers from the screen, which corresponds to `onTouchesUp`. Here we will just hide the pointers that were lifted and end the gesture if there are no more pointers on the screen. - Note that we are not handling `onTouchesCancelled` as in this very basic case we don't expect it to happen, however you should clear data about cancelled pointers (most of the time all active ones) when it is called. + Note that we are not handling `onTouchesCancel` as in this very basic case we don't expect it to happen, however you should clear data about cancelled pointers (most of the time all active ones) when it is called. diff --git a/packages/docs-gesture-handler/src/examples/CallbacksFlowCharts/TouchEventChart.jsx b/packages/docs-gesture-handler/src/examples/CallbacksFlowCharts/TouchEventChart.jsx index f7ddb634a3..180a00dfde 100644 --- a/packages/docs-gesture-handler/src/examples/CallbacksFlowCharts/TouchEventChart.jsx +++ b/packages/docs-gesture-handler/src/examples/CallbacksFlowCharts/TouchEventChart.jsx @@ -20,7 +20,7 @@ const nodes = new DataSet([ }, { id: 4, - label: 'onTouchesCancelled', + label: 'onTouchesCancel', level: 2, }, ]); From 7d74133002c4dfe3af448b02f3a4822a61b5bb63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Wed, 4 Feb 2026 13:27:09 +0100 Subject: [PATCH 3/9] Rephrase onChange --- packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx b/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx index bf3dd1b5ca..91876b56a2 100644 --- a/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx +++ b/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx @@ -87,7 +87,7 @@ code2={ ### onChange -We decided to simplify API by removing `onChange` callback. You can now access `change*` properties in `onUpdate` callback. +`onChange` callback has been removed, and its functionality has been integrated into `onUpdate`. You can now access `change*` properties in `onUpdate` callback. Date: Wed, 4 Feb 2026 13:43:22 +0100 Subject: [PATCH 4/9] Mention touchesCancel in renamed callbacks --- .../docs-gesture-handler/docs/guides/upgrading-to-3.mdx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx b/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx index 91876b56a2..d8515f3727 100644 --- a/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx +++ b/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx @@ -58,6 +58,7 @@ In Gesture Handler 3 some of the callbacks were renamed, namely: | --------- | -------------- | | `onStart` | `onActivate` | | `onEnd` | `onDeactivate` | +| `onTouchesCancelled` | `onTouchesCancel` | Here is comparison of the two APIs: @@ -71,6 +72,9 @@ code1={ }) .onEnd(() => { console.log('Pan ended!'); + }) + .onTouchesCancelled(() => { + console.log('Pan touches cancelled!'); }); `} code2={ @@ -81,6 +85,9 @@ code2={ onDeactivate: () => { console.log('Pan deactivated!'); }, + onTouchesCancel: () => { + console.log('Pan touches cancelled!'); + }, }); `} /> From f04e13d76890a918de269319643b6ef1cbaa202f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Thu, 5 Feb 2026 10:17:17 +0100 Subject: [PATCH 5/9] State manager --- .../docs-gesture-handler/docs/fundamentals/state-manager.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/docs-gesture-handler/docs/fundamentals/state-manager.mdx b/packages/docs-gesture-handler/docs/fundamentals/state-manager.mdx index fb31dc06db..a7151c087b 100644 --- a/packages/docs-gesture-handler/docs/fundamentals/state-manager.mdx +++ b/packages/docs-gesture-handler/docs/fundamentals/state-manager.mdx @@ -7,7 +7,7 @@ sidebar_position: 6 import CollapsibleCode from '@site/src/components/CollapsibleCode'; -RNGH3 allows to manually control gestures lifecycle by using `GestureStateManager`. +RNGH3 allows to manually control [gestures lifecycle](/docs/under-the-hood/state) by using `GestureStateManager`. ## State management From 8c802a4c0ad14bfdfbea9bcc58fe4afc494c777d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Thu, 5 Feb 2026 10:27:23 +0100 Subject: [PATCH 6/9] Callbacks --- .../docs/fundamentals/callbacks-events.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/docs-gesture-handler/docs/fundamentals/callbacks-events.mdx b/packages/docs-gesture-handler/docs/fundamentals/callbacks-events.mdx index 4c6b121b9b..bf0fb759be 100644 --- a/packages/docs-gesture-handler/docs/fundamentals/callbacks-events.mdx +++ b/packages/docs-gesture-handler/docs/fundamentals/callbacks-events.mdx @@ -8,9 +8,9 @@ sidebar_position: 7 import { GestureEventFlowChart, TouchEventFlowChart } from '@site/src/examples/CallbacksFlowCharts' import CollapsibleCode from '@site/src/components/CollapsibleCode'; -At any given time, each handler instance has an assigned [state](/docs/under-the-hood/state) that can change when new touch events occur or can be forced to change by the touch system in certain circumstances. You can hook into state transitions using specific [gesture callbacks](#callbacks). +At any given time, each handler instance has an assigned [state](/docs/under-the-hood/state) that can change when new touch events occur or can be forced to change by the touch system under certain circumstances. You can hook into state transitions using specific [gesture callbacks](#callbacks). -When `Reanimated` is installed, all callbacks are automatically workletized. For more details, refer to the [Integration with Reanimated](/docs/fundamentals/reanimated-interactions#automatic-workletization-of-gesture-callbacks) section. +When Reanimated is installed, all callbacks are automatically workletized. For more details, refer to the [Integration with Reanimated](/docs/fundamentals/reanimated-interactions#automatic-workletization-of-gesture-callbacks) section. ## Callbacks flow From b144d0152ce33220949137e387e7d6a35c8acee6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Thu, 5 Feb 2026 10:27:42 +0100 Subject: [PATCH 7/9] Quickstart --- packages/docs-gesture-handler/docs/guides/quickstart/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/docs-gesture-handler/docs/guides/quickstart/index.md b/packages/docs-gesture-handler/docs/guides/quickstart/index.md index cbfa9bbbd2..bbc96e1017 100644 --- a/packages/docs-gesture-handler/docs/guides/quickstart/index.md +++ b/packages/docs-gesture-handler/docs/guides/quickstart/index.md @@ -23,7 +23,7 @@ To see the new API in action, let's build a simple app where you can drag a ball
- Next, define the `SharedValues` to track the ball's position and create the animated styles required to position the ball on the screen: + Next, define the `SharedValues` to track the ball's position and create the animated styles required to position the ball on the screen:
From ec27c02f5ce45b7002f06aedc4ad8e5440575ed8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Thu, 5 Feb 2026 10:33:44 +0100 Subject: [PATCH 8/9] Troubleshooting --- ...troubleshooting.md => troubleshooting.mdx} | 81 +++++++++++-------- 1 file changed, 47 insertions(+), 34 deletions(-) rename packages/docs-gesture-handler/docs/guides/{troubleshooting.md => troubleshooting.mdx} (54%) diff --git a/packages/docs-gesture-handler/docs/guides/troubleshooting.md b/packages/docs-gesture-handler/docs/guides/troubleshooting.mdx similarity index 54% rename from packages/docs-gesture-handler/docs/guides/troubleshooting.md rename to packages/docs-gesture-handler/docs/guides/troubleshooting.mdx index 4ceeb8e0f2..0a37da0478 100644 --- a/packages/docs-gesture-handler/docs/guides/troubleshooting.md +++ b/packages/docs-gesture-handler/docs/guides/troubleshooting.mdx @@ -4,6 +4,9 @@ title: Troubleshooting sidebar_position: 3 --- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + ## Troubleshooting Thanks for giving this library a try! We are sorry that you might have encountered issues though. Here is how you can seek help: @@ -11,15 +14,12 @@ Thanks for giving this library a try! We are sorry that you might have encounter 1. Search over the [issues on Github](https://github.com/software-mansion/react-native-gesture-handler/issues). There is a chance someone had this problem in the past and it has been resolved! 2. When sure your problem hasn't been reported or was reported but the proposed solution doesn't work for you please follow [our issue reporting guidelines](#reporting-issues). 3. You can try seeking help on [Software Mansion Discord](https://discord.com/invite/VemJ4df8Yr). -4. If you feel like reading the source code I highly recommend it, as this is by far the best resource and gives you the most up to date insights into how the library works and what might be causing the bug. +4. If you feel like reading the source code we highly recommend it, as this is by far the best resource and gives you the most up to date insights into how the library works and what might be causing the bug. 5. If you managed to find the solution consider [contributing](/docs/#contributing) a fix or update our documentation to make this information easier to find for the others in the future. ## Reporting issues -This library is maintained by a very small team. -Please be mindful of that when reporting issue and when it happens that we can't get back to you as soon as you might expect. -We would love to fix all the problems as soon as possible, but often our time is constraint with other issues/features or projects. -To make it easier for us to understand your issue and to be able to approach it sooner you can help by: +This library is maintained by a very small team. Please keep this in mind when reporting issues, as we may not be able to respond as quickly as you might expect. We strive to address all problems as soon as possible, but our time is often constrained by other issues, features, or projects. To help us understand and address your issue more promptly, you can assist by: - Making sure the issue description is complete. Please include all the details about your environment (library version, RN version, device OS etc). - It is the best to provide an example app that reproduces the issue you are having. Put it up on [gist](https://gist.github.com/), [snack](https://snack.expo.io) or create a repo on Github – it doesn't matter as long as we can easily pull it in, run and see the issue. @@ -32,44 +32,57 @@ To make it easier for us to understand your issue and to be able to approach it - Changing `enabled` prop during a gesture has no effect, only when a gesture starts (that is a finger touches the screen) the `enabled` prop is taken into consideration to decide whether to extract (or not) the gesture and provide it with stream of events to analyze. - `Native` gesture may not conform to the standard state flow due to platform specific workarounds to incorporate native views into RNGH. -- Keep in mind that `Touchables` from RNGH are rendering two additional views that may need to be styled separately to achieve desired effect (`style` and `containerStyle` props). -- In order for the gesture composition to work, all composed gestures must be attached to the same `GestureHandlerRootView`. +- Keep in mind that [`Touchables`](/docs/components/touchables) from RNGH are rendering two additional views that may need to be styled separately to achieve desired effect (`style` and `containerStyle` props). +- In order for the [gesture composition](/docs/fundamentals/gesture-composition) to work, all composed gestures must be attached to the same `GestureHandlerRootView`. + +## Multiple instances of Gesture Handler were detected + +This error usually happens when in your project there exists more than one instance of Gesture Handler. It can occur when some of your dependencies have installed Gesture Handler inside their own `node_modules` instead of using it as a peer dependency. In this case two different versions of Gesture Handler JS module try to install the same Native Module. -### Multiple instances of Gesture Handler were detected +You can resolve this problem manually by modifying your `package.json` file. This will depend on the package manager you are using. -This error usually happens when in your project there exists more than one instance of Gesture Handler. It can occur when some of your dependencies have installed Gesture Handler inside their own `node_modules` instead of using it as a peer dependency. In this case two different versions of Gesture Handler JS module try to install the same Native Module. You can resolve this problem manually by modifying your `package.json` file. -You can check which libraries are using Gesture Handler, for example, with the command: + + + You can check which libraries are using Gesture Handler with the command: + + ```bash + npm ls react-native-gesture-handler + ``` -```bash -npm ls react-native-gesture-handler -yarn why react-native-gesture-handler -``` + Add [`overrides`](https://docs.npmjs.com/cli/v8/configuring-npm/package-json#overrides) property. -If you use `yarn` you should add [`resolution` property](https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/). + ```json + "overrides": { + "react-native-gesture-handler": + } + ``` -```json -"resolutions": { - "react-native-gesture-handler": -} -``` + After that you need to run your package manager again: -If you use `npm` you should add [`overrides` property](https://docs.npmjs.com/cli/v8/configuring-npm/package-json#overrides). + ```bash + npm install + ``` + + + You can check which libraries are using Gesture Handler with the command: -```json -"overrides": { - "react-native-gesture-handler": -} -``` + ```bash + yarn why react-native-gesture-handler + ``` -After that you need to run your package manager again + Add [`resolutions`](https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/) property. -```bash -yarn -``` + ```json + "resolutions": { + "react-native-gesture-handler": + } + ``` -or + After that you need to run your package manager again: -```bash -npm install -``` + ```bash + yarn + ``` + + From e7b4a59985bb151df3ea4146f3bc6f67766c194c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Fri, 6 Feb 2026 11:35:34 +0100 Subject: [PATCH 9/9] Testing --- .../docs/guides/testing.md | 107 ++++++++---------- 1 file changed, 50 insertions(+), 57 deletions(-) diff --git a/packages/docs-gesture-handler/docs/guides/testing.md b/packages/docs-gesture-handler/docs/guides/testing.md index 9153c9842c..3f2c6428ca 100644 --- a/packages/docs-gesture-handler/docs/guides/testing.md +++ b/packages/docs-gesture-handler/docs/guides/testing.md @@ -23,40 +23,31 @@ Example: ## Testing Gestures' and Gesture handlers' callbacks -RNGH provides an API for triggering selected handlers: +RNGH provides APIs, specifically [`fireGestureHandler`](#firegesturehandler) and [`getByGestureTestId`](#getbygesturetestid), to trigger selected handlers. -- [`fireGestureHandler(gestureOrHandler, eventList)`](/docs/guides/testing#firegesturehandlergestureorhandler-eventlist) -- [`getByGestureTestId(testID)`](/docs/guides/testing#getbygesturetestidtestid) +### fireGestureHandler -## fireGestureHandler(gestureOrHandler, eventList) +```ts +fireGestureHandler: (componentOrGesture, eventList) => void; +``` Simulates one event stream (i.e. event sequence starting with `BEGIN` state and ending with one of `END`/`FAIL`/`CANCEL` states), calling appropriate callbacks associated with given gesture handler. -### Arguments - -#### `gestureOrHandler` - -Represents either: - -1. Gesture handler component found by Jest queries (e.g. `getByTestId`) -2. Gesture found by [`getByGestureTestId()`](/docs/guides/testing#getbygesturetestidtestid) - -#### `eventList` +- `componentOrGesture` - Either Gesture Handler component found by `Jest` queries (e.g. `getByTestId`) or Gesture found by [`getByGestureTestId()`](#getbygesturetestidtestid) -Event data passed to appropriate callback. RNGH fills event list if required -data is missing using these rules: +- `eventList` - Event data passed to appropriate callback. RNGH fills event list if required + data is missing using these rules: + - `oldState` is filled using state of the previous event. `BEGIN` events use + `UNDETERMINED` value as previous event. + - Events after first `ACTIVE` state can omit `state` field. + - Handler specific data is filled (e.g. `numberOfTouches`, `x` fields) with + defaults. + - Missing `BEGIN` and `END` events are added with data copied from first and last + passed event, respectively. + - If first event don't have `state` field, the `ACTIVE` state is assumed. -1. `oldState` is filled using state of the previous event. `BEGIN` events use - `UNDETERMINED` value as previous event. -2. Events after first `ACTIVE` state can omit `state` field. -3. Handler specific data is filled (e.g. `numberOfTouches`, `x` fields) with - defaults. -4. Missing `BEGIN` and `END` events are added with data copied from first and last - passed event, respectively. -5. If first event don't have `state` field, the `ACTIVE` state is assumed. - -Some examples: +Some `eventList` examples: ```jsx const oldStateFilled = [ @@ -86,44 +77,46 @@ const implicitBeginAndEnd = [ const allImplicits = []; // 3 events, one BEGIN, one ACTIVE, one END with defaults. ``` -### Example - -Extracted from RNGH tests, check `Events.test.tsx` for full implementation. +### getByGestureTestId ```tsx -it('sends events with additional data to handlers', () => { - const panHandlers = mockedEventHandlers(); - render(); - fireGestureHandler(getByGestureTestId('pan'), [ - { state: State.BEGAN, translationX: 0 }, - { state: State.ACTIVE, translationX: 10 }, - { translationX: 20 }, - { translationX: 20 }, - { state: State.END, translationX: 30 }, - ]); - - expect(panHandlers.active).toHaveBeenCalledTimes(3); - expect(panHandlers.active).toHaveBeenLastCalledWith( - expect.objectContaining({ translationX: 20 }) - ); -}); +getByGestureTestId: (testID: string) => Gesture; ``` -## getByGestureTestId(testID) - -Returns opaque data type associated with gesture. Gesture is found via `testID` attribute in rendered -components (see [`testID`](/docs/gestures/use-pan-gesture#testid)). - -### Arguments +Returns opaque data type associated with gesture. Gesture is found via [`testID`](/docs/gestures/use-pan-gesture#testid) attribute in rendered +components. -#### `testID` +- `testID` - String identifying gesture. -String identifying gesture. +:::warning +`testID` must be unique among components rendered in test. +::: -### Notes +## Example -`testID` must be unique among components rendered in test. +Extracted from RNGH tests, check [`api_v3.test.tsx`](https://github.com/software-mansion/react-native-gesture-handler/blob/main/packages/react-native-gesture-handler/src/__tests__/api_v3.test.tsx) for full implementation. -### Example +```tsx +test('Pan gesture', () => { + const onBegin = jest.fn(); + const onStart = jest.fn(); + + const panGesture = renderHook(() => + usePanGesture({ + disableReanimated: true, + onBegin: (e) => onBegin(e), + onActivate: (e) => onStart(e), + }) + ).result.current; + + fireGestureHandler(panGesture, [ + { oldState: State.UNDETERMINED, state: State.BEGAN }, + { oldState: State.BEGAN, state: State.ACTIVE }, + { oldState: State.ACTIVE, state: State.ACTIVE }, + { oldState: State.ACTIVE, state: State.END }, + ]); -See above example for `fireGestureHandler`. + expect(onBegin).toHaveBeenCalledTimes(1); + expect(onStart).toHaveBeenCalledTimes(1); +}); +```