Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
4e3e30f
Pan gesture
m-bert Dec 9, 2025
7ac164d
Merge branch 'next' into @mbert/docs-v3
m-bert Dec 10, 2025
203131e
Finish (?) Pan
m-bert Dec 10, 2025
db99336
Tap
m-bert Dec 10, 2025
f01bd66
Long press
m-bert Dec 10, 2025
5490439
Rotation
m-bert Dec 10, 2025
ded8083
Pinch
m-bert Dec 10, 2025
e38591c
Fling
m-bert Dec 10, 2025
f338fa7
Hover
m-bert Dec 10, 2025
11c91a7
Native
m-bert Dec 10, 2025
37d7438
Manual
m-bert Dec 10, 2025
a93970a
Fix path
m-bert Dec 10, 2025
d23e66b
Remove cache from workflow
m-bert Dec 10, 2025
5c0b717
composition
m-bert Dec 11, 2025
f293949
Remove PanHandlerData
m-bert Dec 15, 2025
34a93a5
Use correct HandlerData
m-bert Dec 15, 2025
f4847dc
Merge branch 'next' into @mbert/docs-v3
m-bert Dec 15, 2025
87a1130
Merge branch 'next' into @mbert/docs-v3
m-bert Dec 16, 2025
b96d788
Bye bye API 2
m-bert Dec 16, 2025
cf3f810
Fix hover
m-bert Dec 16, 2025
944d689
Fix old links
m-bert Dec 16, 2025
d2958e0
Another links
m-bert Dec 16, 2025
d8eaaeb
remove useless prop
m-bert Dec 22, 2025
b2a373e
Add warning to requireToFail
m-bert Dec 22, 2025
d3c7893
One composition
m-bert Dec 22, 2025
e96349e
Remove outdated info
m-bert Dec 22, 2025
cd7c0d6
Remove SharedValue notes
m-bert Dec 22, 2025
ca2d46a
rephrase exclusive
m-bert Dec 22, 2025
1811c9c
Other composition updates
m-bert Dec 22, 2025
4fa234f
Change reference to example
m-bert Dec 22, 2025
fb8e2ef
Change reference to example yet again (manual)
m-bert Dec 22, 2025
47da2df
Tapp
m-bert Dec 22, 2025
c8a4a76
Native on web
m-bert Dec 22, 2025
5c3d918
Add missing pan properties
m-bert Dec 22, 2025
a8c6ccc
Simplify pinch example
m-bert Dec 22, 2025
421d247
scaleChange
m-bert Dec 22, 2025
b14eadf
Add pan headers
m-bert Dec 22, 2025
b769862
Rotation gesture changes
m-bert Dec 22, 2025
49b1d3e
Test id correct prop name
m-bert Dec 22, 2025
41f7a4f
Add SharedValue info
m-bert Dec 22, 2025
1fb9b51
Add missing shared value info to long press
m-bert Dec 22, 2025
6d2da5a
Remove secondary headers
m-bert Dec 22, 2025
f90b378
Change order
m-bert Dec 22, 2025
b4cd005
Merge branch 'next' into @mbert/docs-detector
m-bert Dec 23, 2025
5255e4a
Detecor page
m-bert Dec 23, 2025
205c0a8
Gesture detector
m-bert Dec 23, 2025
4c53b94
Change ordering
m-bert Dec 23, 2025
42b04b1
Update links
m-bert Dec 23, 2025
03501dc
Other links
m-bert Dec 23, 2025
e1fae87
Merge branch 'next' into @mbert/docs-detector
m-bert Jan 7, 2026
59fd8df
Merge branch 'next' into @mbert/docs-detector
m-bert Jan 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
id: gesture-composition
title: Gesture composition & interactions
sidebar_label: Gesture composition & interactions
sidebar_position: 10
sidebar_position: 4
---

RNGH3 simplifies gesture interaction through dedicated composition hooks and configuration properties. To choose the right approach, simply ask: Are all the gestures attached to the same component?
Expand Down
211 changes: 211 additions & 0 deletions packages/docs-gesture-handler/docs/fundamentals/gesture-detector.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
---
id: gesture-detectors
title: Gesture Detectors
sidebar_label: Gesture detectors
sidebar_position: 3
---

## Gesture Detector

`GestureDetector` is the core component of RNGH3. Unlike in previous version, it no longer manages the lifecycle of gestures directly. It supports recognizing multiple gestures through [gesture composition](/docs/fundamentals/gesture-composition).
Copy link
Member

Choose a reason for hiding this comment

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

Unlike in previous version, it no longer manages the lifecycle of gestures directly.

So what's the difference between the two versions?

I feel like this page should focus on what it does instead of on what it doesn't. We're going to have an entire migration guide about the differences.


To facilitate a smooth migration, the gesture property accepts both RNGH3 and RNGH2 gestures.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
To facilitate a smooth migration, the gesture property accepts both RNGH3 and RNGH2 gestures.
To facilitate a smooth migration, the gesture property accepts both gestures created using the hooks API and gestures created using the builder pattern.

I'm not sold on using RNGH2 and RNGH3 as a way to differentiate between the two APIs, especially given that some parts stayed the same (i.e. GestureDetector).

Copy link
Contributor

Choose a reason for hiding this comment

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

How nested GestureDetectors from different GH versions interact? I'm not sure we should indicate the user can use both in one component. Especially as relations definetly don't work.


When using RNGH3 gestures, you can also integrate them directly with the [Animated API](https://reactnative.dev/docs/animated).

### Example

#### Simple example

```js
import { GestureDetector, useTapGesture } from 'react-native-gesture-handler';

export default function App() {
const tap = useTapGesture({});
Copy link
Member

Choose a reason for hiding this comment

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

Can this have a console.log at least?


return (
<GestureHandlerRootView>
// highlight-next-line
<GestureDetector gesture={tap}>
<Animated.View />
// highlight-next-line
</GestureDetector>
</GestureHandlerRootView>
);
}
```

#### Usage with Animated API
Copy link
Member

Choose a reason for hiding this comment

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

This might be worth its own page.


```js
import * as React from 'react';
import { Animated, useAnimatedValue } from 'react-native';
import {
GestureHandlerRootView,
GestureDetector,
usePanGesture,
} from 'react-native-gesture-handler';

export default function App() {
const value = useAnimatedValue(0);
const event = Animated.event(
[{ nativeEvent: { handlerData: { translationX: value } } }],
{
useNativeDriver: true,
}
);

const gesture = usePanGesture({
onUpdate: event,
});

return (
<GestureHandlerRootView>
// highlight-next-line
<GestureDetector gesture={gesture}>
<Animated.View
style={[
{
width: 150,
height: 150,
backgroundColor: '#b58df1',
},
{ transform: [{ translateX: value }] },
]}
/>
// highlight-next-line
</GestureDetector>
</GestureHandlerRootView>
);
}
```

## Virtual Detectors

In RNGH3, `GestureDetector` is a standalone native component. Depending on your view hierarchy, this can occasionally disrupt interactions between specific components. To resolve this, use `InterceptingGestureDetector` in combination with `VirtualNativeDetector`.
Copy link
Member

Choose a reason for hiding this comment

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

AFAIK, the established name is host component.


### InterceptingGestureDetector

`InterceptingGestureDetector` functions like a standard `GestureDetector`, but adds support for `VirtualGestureDetector` within its component subtree. Because it can be used solely to establish the context for virtual detectors, the [`gesture`](#gesture) property is optional.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
`InterceptingGestureDetector` functions like a standard `GestureDetector`, but adds support for `VirtualGestureDetector` within its component subtree. Because it can be used solely to establish the context for virtual detectors, the [`gesture`](#gesture) property is optional.
`InterceptingGestureDetector` functions similarly to a standard `GestureDetector`, but it can also act as a proxy for `VirtualGestureDetector` within its component subtree. Because it can be used solely to establish the context for virtual detectors, the [`gesture`](#gesture) property is optional.

Idk, what do you think?


### VirtualGestureDetector

`VirtualGestureDetector` is similar to the `GestureDetector` from RNGH2. Because it is not a native component, it does not interfere with the native view hierarchy. This allows you to attach gestures without disrupting functionality that depends on that hierarchy.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
`VirtualGestureDetector` is similar to the `GestureDetector` from RNGH2. Because it is not a native component, it does not interfere with the native view hierarchy. This allows you to attach gestures without disrupting functionality that depends on that hierarchy.
`VirtualGestureDetector` is similar to the `GestureDetector` from RNGH2. Because it is not a host component, it does not interfere with the host view hierarchy. This allows you to attach gestures without disrupting functionality that depends on it, like `react-native-svg` components.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think virtual detector deserves a known use case subsection: svg, nested text. People will search for it, and it will be easier for llm's to figure out if it is explicit.


### Example

```js
import React from 'react';
import { View, StyleSheet } from 'react-native';
import {
GestureHandlerRootView,
InterceptingGestureDetector,
useTapGesture,
VirtualGestureDetector,
} from 'react-native-gesture-handler';
import Svg, { Circle } from 'react-native-svg';

export default function App() {
const outerTap = useTapGesture({});
const innerTap = useTapGesture({});
Comment on lines +109 to +110
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
const outerTap = useTapGesture({});
const innerTap = useTapGesture({});
const outerTap = useTapGesture({onActivate: ()=> console.log("box tapped")});
const innerTap = useTapGesture({onActivate: ()=> console.log("circle tapped")});


return (
<GestureHandlerRootView style={styles.container}>
// highlight-next-line
<InterceptingGestureDetector gesture={innerTap}>
<View style={styles.box}>
<Svg height="250" width="250">
// highlight-next-line
<VirtualGestureDetector gesture={outerTap}>
Copy link
Contributor

Choose a reason for hiding this comment

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

The inner component's gesture should probably be innerTap and outer's outerTap

<Circle
cx="125"
cy="125"
r="125"
fill="#001A72"
onPress={() => {}}
/>
// highlight-next-line
</VirtualGestureDetector>
</Svg>
</View>
// highlight-next-line
</InterceptingGestureDetector>
</GestureHandlerRootView>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
box: {
backgroundColor: '#b58df1',
},
});
```

## Interaction with Reanimated

`GestureDetector` will decide whether to use [Reanimated](https://docs.swmansion.com/react-native-reanimated/) to process provided gestures based on their configuration. If any of the callbacks is a worklet and Reanimated is not explicitly turned off, tools provided by the Reanimated will be utilized bringing ability to handle gestures synchronously.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
`GestureDetector` will decide whether to use [Reanimated](https://docs.swmansion.com/react-native-reanimated/) to process provided gestures based on their configuration. If any of the callbacks is a worklet and Reanimated is not explicitly turned off, tools provided by the Reanimated will be utilized bringing ability to handle gestures synchronously.
`GestureDetector` will decide whether to use [Reanimated](https://docs.swmansion.com/react-native-reanimated/) to process provided gestures based on their configuration. If any of the callbacks is a worklet and Reanimated is not explicitly turned off, tools provided by Reanimated will be utilized, bringing the ability to handle gestures synchronously on the main thread.


## Properties

### gesture

```ts
gesture: SingleGesture | ComposedGesture;
```

A gesture object containing the configuration and callbacks. Can be any of the base gestures or any [`ComposedGesture`](/docs/fundamentals/gesture-composition).

### userSelect (Web only)

```ts
userSelect: 'none' | 'auto' | 'text';
```

This parameter allows to specify which `userSelect` property should be applied to underlying view. Default value is set to `"none"`.

### touchAction (Web only)

```ts
userSelect: TouchAction;
```

This parameter allows to specify which `touchAction` property should be applied to underlying view. Supports all CSS [touch-action](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/touch-action) values. Default value is set to `"none"`.

### enableContextMenu (Web only)

```ts
enableContextMenu: boolean;
```

Specifies whether context menu should be enabled after clicking on underlying view with right mouse button. Default value is set to `false`.

## Remarks

- Using the same instance of a gesture across multiple Gesture Detectors is not possible. Have a look at the code below:

```jsx
export default function Example() {
const pan = usePanGesture({});

return (
<View>
// highlight-next-line
<GestureDetector gesture={pan}>
<View>
// highlight-next-line
<GestureDetector gesture={pan}>
<View />
</GestureDetector>
</View>
</GestureDetector>
</View>
);
}
```

This example will throw an error, becuse we try to use the same instance of `Pan` in two different Gesture Detectors.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
This example will throw an error, becuse we try to use the same instance of `Pan` in two different Gesture Detectors.
This example will throw an error, because the same instance of `Pan` is being used in two different Gesture Detectors.

Copy link
Contributor

Choose a reason for hiding this comment

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

Does it throw an error though? I haven't checked on ios or android but web does not throw. It attaches to only one detector, but it is undefined behaviour which one. I think at some point we discussed where to put the error check in the office, but we figured it is not trivial, as we might break reattaching.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
id: states-events
title: Gesture states & events
sidebar_label: Gesture states & events
sidebar_position: 4
sidebar_position: 5
---

Every gesture can be treated as ["state machine"](https://en.wikipedia.org/wiki/Finite-state_machine).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ simultaneousWith: Gesture | Gesture[]

Adds a gesture that should be recognized simultaneously with this one.

**IMPORTANT:** Note that this method only marks the relation between gestures, without [composing them](/docs/fundamentals/gesture-composition). [`GestureDetector`](/docs/gestures/gesture-detector) will not recognize the `otherGestures` and it needs to be added to another detector in order to be recognized.
**IMPORTANT:** Note that this method only marks the relation between gestures, without [composing them](/docs/fundamentals/gesture-composition). [`GestureDetector`](/docs/fundamentals/gesture-detectors#gesture-detector) will not recognize the `otherGestures` and it needs to be added to another detector in order to be recognized.

### requireToFail

Expand All @@ -99,7 +99,7 @@ requireToFail: Gesture | Gesture[]

Adds a relation requiring another gesture to fail, before this one can activate.

**IMPORTANT:** Note that this method only marks the relation between gestures, without [composing them](/docs/fundamentals/gesture-composition). [`GestureDetector`](/docs/gestures/gesture-detector) will not recognize the `otherGestures` and it needs to be added to another detector in order to be recognized.
**IMPORTANT:** Note that this method only marks the relation between gestures, without [composing them](/docs/fundamentals/gesture-composition). [`GestureDetector`](/docs/fundamentals/gesture-detectors#gesture-detector) will not recognize the `otherGestures` and it needs to be added to another detector in order to be recognized.

### block

Expand All @@ -109,7 +109,7 @@ block: Gesture | Gesture[]

Adds a relation that makes other gestures wait with activation until this gesture fails (or doesn't start at all).

**IMPORTANT:** Note that this method only marks the relation between gestures, without [composing them](/docs/fundamentals/gesture-composition).[`GestureDetector`](/docs/gestures/gesture-detector) will not recognize the `otherGestures` and it needs to be added to another detector in order to be recognized.
**IMPORTANT:** Note that this method only marks the relation between gestures, without [composing them](/docs/fundamentals/gesture-composition).[`GestureDetector`](/docs/fundamentals/gesture-detectors#gesture-detector) will not recognize the `otherGestures` and it needs to be added to another detector in order to be recognized.

### activeCursor

Expand Down

This file was deleted.

81 changes: 0 additions & 81 deletions packages/docs-gesture-handler/docs/gestures/gesture-detector.md

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -159,15 +159,15 @@ Allows users to choose which mouse button should handler respond to. Arguments c
x: number;
```

X coordinate of the current position of the pointer (finger or a leading pointer when there are multiple fingers placed) relative to the view attached to the [`GestureDetector`](/docs/gestures/gesture-detector). Expressed in point units.
X coordinate of the current position of the pointer (finger or a leading pointer when there are multiple fingers placed) relative to the view attached to the [`GestureDetector`](/docs/fundamentals/gesture-detectors#gesture-detector). Expressed in point units.

### y

```ts
y: number;
```

Y coordinate of the current position of the pointer (finger or a leading pointer when there are multiple fingers placed) relative to the view attached to the [`GestureDetector`](/docs/gestures/gesture-detector). Expressed in point units.
Y coordinate of the current position of the pointer (finger or a leading pointer when there are multiple fingers placed) relative to the view attached to the [`GestureDetector`](/docs/fundamentals/gesture-detectors#gesture-detector). Expressed in point units.

### absoluteX

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,15 +118,15 @@ Visual effect applied to the view while the view is hovered. Defaults to `HoverE
x: number;
```

X coordinate of the current position of the pointer relative to the view attached to the [`GestureDetector`](/docs/gestures/gesture-detector). Expressed in point units.
X coordinate of the current position of the pointer relative to the view attached to the [`GestureDetector`](/docs/fundamentals/gesture-detectors#gesture-detector). Expressed in point units.

### y

```ts
y: number;
```

Y coordinate of the current position of the pointer relative to the view attached to the [`GestureDetector`](/docs/gestures/gesture-detector). Expressed in point units.
Y coordinate of the current position of the pointer relative to the view attached to the [`GestureDetector`](/docs/fundamentals/gesture-detectors#gesture-detector). Expressed in point units.

### absoluteX

Expand Down
Loading