0
# Modern Gesture API
1
2
The recommended approach for creating sophisticated gesture interactions using the new Gesture API with `GestureDetector` and `Gesture` factory methods.
3
4
## Capabilities
5
6
### GestureDetector
7
8
Main component for detecting and handling gestures using the modern API. This component wraps your views and applies gesture recognition to them.
9
10
```typescript { .api }
11
/**
12
* Component for detecting gestures using the modern Gesture API
13
* Wraps child components and applies gesture recognition
14
*/
15
function GestureDetector(props: {
16
gesture: ComposedGesture | GestureType;
17
userSelect?: UserSelect;
18
enableContextMenu?: boolean;
19
touchAction?: TouchAction;
20
children?: React.ReactNode;
21
}): JSX.Element;
22
23
// Web-specific prop types
24
type UserSelect = "none" | "auto" | "text" | "contain" | "all";
25
type TouchAction = "none" | "auto" | "pan-x" | "pan-y" | "manipulation";
26
```
27
28
**Usage Example:**
29
30
```typescript
31
import React from "react";
32
import { View } from "react-native";
33
import { GestureDetector, Gesture } from "react-native-gesture-handler";
34
35
function MyComponent() {
36
const tapGesture = Gesture.Tap()
37
.numberOfTaps(2)
38
.onEnd(() => {
39
console.log("Double tap!");
40
});
41
42
return (
43
<GestureDetector gesture={tapGesture}>
44
<View style={{ width: 100, height: 100, backgroundColor: "blue" }} />
45
</GestureDetector>
46
);
47
}
48
```
49
50
### Gesture Factory
51
52
Factory object providing methods to create different types of gestures. Each method returns a configurable gesture instance.
53
54
```typescript { .api }
55
/**
56
* Factory object for creating gesture instances
57
* Provides methods for all supported gesture types
58
*/
59
interface GestureObjects {
60
Tap(): TapGestureType;
61
Pan(): PanGestureType;
62
Pinch(): PinchGestureType;
63
Rotation(): RotationGestureType;
64
Fling(): FlingGestureType;
65
LongPress(): LongPressGestureType;
66
ForceTouch(): ForceTouchGestureType; // Deprecated
67
Native(): NativeGestureType;
68
Manual(): ManualGestureType;
69
Hover(): HoverGestureType;
70
Race(...gestures: GestureType[]): RaceGestureType;
71
Simultaneous(...gestures: GestureType[]): SimultaneousGestureType;
72
Exclusive(...gestures: GestureType[]): ExclusiveGestureType;
73
}
74
75
// Available as Gesture export
76
declare const Gesture: GestureObjects;
77
```
78
79
### Tap Gesture
80
81
Recognizes single or multiple tap gestures with configurable parameters for timing and positioning.
82
83
```typescript { .api }
84
/**
85
* Tap gesture type with configuration methods
86
* Recognizes single or multiple taps with configurable constraints
87
*/
88
interface TapGestureType {
89
/** Set minimum number of pointers required (default: 1) */
90
minPointers(count: number): TapGestureType;
91
/** Set required number of consecutive taps (default: 1) */
92
numberOfTaps(count: number): TapGestureType;
93
/** Set maximum distance pointer can travel (in points) */
94
maxDistance(distance: number): TapGestureType;
95
/** Set maximum tap duration in milliseconds */
96
maxDuration(ms: number): TapGestureType;
97
/** Set maximum delay between taps in milliseconds */
98
maxDelay(ms: number): TapGestureType;
99
/** Set maximum travel distance on X axis (in points) */
100
maxDeltaX(delta: number): TapGestureType;
101
/** Set maximum travel distance on Y axis (in points) */
102
maxDeltaY(delta: number): TapGestureType;
103
/** Callback when gesture begins */
104
onBegin(callback: (event: GestureStateChangeEvent) => void): TapGestureType;
105
/** Callback when gesture starts */
106
onStart(callback: (event: GestureStateChangeEvent) => void): TapGestureType;
107
/** Callback when gesture ends successfully */
108
onEnd(callback: (event: GestureStateChangeEvent) => void): TapGestureType;
109
/** Callback when gesture is cancelled or fails */
110
onFinalize(callback: (event: GestureStateChangeEvent) => void): TapGestureType;
111
}
112
```
113
114
**Usage Example:**
115
116
```typescript
117
const doubleTap = Gesture.Tap()
118
.numberOfTaps(2)
119
.maxDelay(500)
120
.onEnd(() => {
121
console.log("Double tap detected!");
122
});
123
124
const tripleTap = Gesture.Tap()
125
.numberOfTaps(3)
126
.maxDistance(20)
127
.onEnd(() => {
128
console.log("Triple tap detected!");
129
});
130
```
131
132
### Pan Gesture
133
134
Recognizes dragging gestures with velocity, translation, and configurable activation areas.
135
136
```typescript { .api }
137
/**
138
* Pan gesture type for drag interactions
139
* Provides translation, velocity, and configurable activation constraints
140
*/
141
interface PanGestureType {
142
/** Set Y-axis activation offset range */
143
activeOffsetY(offset: number | number[]): PanGestureType;
144
/** Set X-axis activation offset range */
145
activeOffsetX(offset: number | number[]): PanGestureType;
146
/** Set Y-axis failure offset range */
147
failOffsetY(offset: number | number[]): PanGestureType;
148
/** Set X-axis failure offset range */
149
failOffsetX(offset: number | number[]): PanGestureType;
150
/** Set minimum number of pointers (default: 1) */
151
minPointers(count: number): PanGestureType;
152
/** Set maximum number of pointers (default: 10) */
153
maxPointers(count: number): PanGestureType;
154
/** Set minimum travel distance to activate */
155
minDistance(distance: number): PanGestureType;
156
/** Set minimum velocity to activate */
157
minVelocity(velocity: number): PanGestureType;
158
/** Set minimum X-axis velocity to activate */
159
minVelocityX(velocity: number): PanGestureType;
160
/** Set minimum Y-axis velocity to activate */
161
minVelocityY(velocity: number): PanGestureType;
162
/** Android only: average multiple touch positions */
163
averageTouches(enabled: boolean): PanGestureType;
164
/** iOS only: enable trackpad two-finger gesture support */
165
enableTrackpadTwoFingerGesture(enabled: boolean): PanGestureType;
166
/** Activate pan gesture after long press delay */
167
activateAfterLongPress(duration: number): PanGestureType;
168
/** Callback during gesture updates */
169
onUpdate(callback: (event: GestureUpdateEvent<PanGestureChangeEventPayload>) => void): PanGestureType;
170
/** Callback when gesture begins */
171
onBegin(callback: (event: GestureStateChangeEvent) => void): PanGestureType;
172
/** Callback when gesture starts */
173
onStart(callback: (event: GestureStateChangeEvent) => void): PanGestureType;
174
/** Callback when gesture ends */
175
onEnd(callback: (event: GestureStateChangeEvent<PanGestureChangeEventPayload>) => void): PanGestureType;
176
}
177
178
interface PanGestureChangeEventPayload {
179
translationX: number;
180
translationY: number;
181
velocityX: number;
182
velocityY: number;
183
}
184
```
185
186
**Usage Example:**
187
188
```typescript
189
const panGesture = Gesture.Pan()
190
.minDistance(10)
191
.activeOffsetX([-10, 10])
192
.onUpdate((event) => {
193
console.log(`Translation: ${event.translationX}, ${event.translationY}`);
194
console.log(`Velocity: ${event.velocityX}, ${event.velocityY}`);
195
})
196
.onEnd(() => {
197
console.log("Pan gesture ended");
198
});
199
```
200
201
### Pinch Gesture
202
203
Recognizes pinch/zoom gestures providing scale factor and focal point information.
204
205
```typescript { .api }
206
/**
207
* Pinch gesture type for scaling interactions
208
* Provides scale factor and focal point coordinates
209
*/
210
interface PinchGestureType {
211
/** Callback during gesture updates */
212
onUpdate(callback: (event: GestureUpdateEvent<PinchGestureChangeEventPayload>) => void): PinchGestureType;
213
/** Callback when gesture begins */
214
onBegin(callback: (event: GestureStateChangeEvent) => void): PinchGestureType;
215
/** Callback when gesture starts */
216
onStart(callback: (event: GestureStateChangeEvent) => void): PinchGestureType;
217
/** Callback when gesture ends */
218
onEnd(callback: (event: GestureStateChangeEvent<PinchGestureChangeEventPayload>) => void): PinchGestureType;
219
}
220
221
interface PinchGestureChangeEventPayload {
222
scale: number;
223
focalX: number;
224
focalY: number;
225
velocity: number;
226
}
227
```
228
229
### Rotation Gesture
230
231
Recognizes rotation gestures providing rotation angle and anchor point information.
232
233
```typescript { .api }
234
/**
235
* Rotation gesture type for rotating interactions
236
* Provides rotation angle in radians and anchor point coordinates
237
*/
238
interface RotationGestureType {
239
/** Callback during gesture updates */
240
onUpdate(callback: (event: GestureUpdateEvent<RotationGestureChangeEventPayload>) => void): RotationGestureType;
241
/** Callback when gesture begins */
242
onBegin(callback: (event: GestureStateChangeEvent) => void): RotationGestureType;
243
/** Callback when gesture starts */
244
onStart(callback: (event: GestureStateChangeEvent) => void): RotationGestureType;
245
/** Callback when gesture ends */
246
onEnd(callback: (event: GestureStateChangeEvent<RotationGestureChangeEventPayload>) => void): RotationGestureType;
247
}
248
249
interface RotationGestureChangeEventPayload {
250
rotation: number; // in radians
251
anchorX: number;
252
anchorY: number;
253
velocity: number;
254
}
255
```
256
257
### Fling Gesture
258
259
Recognizes quick swipe/fling gestures with directional constraints.
260
261
```typescript { .api }
262
/**
263
* Fling gesture type for quick swipe movements
264
* Recognizes fast directional movements with configurable constraints
265
*/
266
interface FlingGestureType {
267
/** Set allowed fling directions using Directions constants */
268
direction(direction: number): FlingGestureType;
269
/** Set number of pointers required (default: 1) */
270
numberOfPointers(count: number): FlingGestureType;
271
/** Callback when gesture is recognized */
272
onStart(callback: (event: GestureStateChangeEvent) => void): FlingGestureType;
273
/** Callback when gesture ends */
274
onEnd(callback: (event: GestureStateChangeEvent) => void): FlingGestureType;
275
}
276
```
277
278
### Long Press Gesture
279
280
Recognizes long press gestures with configurable duration and movement constraints.
281
282
```typescript { .api }
283
/**
284
* Long press gesture type
285
* Recognizes press and hold gestures with configurable timing
286
*/
287
interface LongPressGestureType {
288
/** Set minimum press duration in milliseconds (default: 500) */
289
minDuration(ms: number): LongPressGestureType;
290
/** Set maximum allowed movement distance */
291
maxDistance(distance: number): LongPressGestureType;
292
/** Callback when gesture is activated */
293
onStart(callback: (event: GestureStateChangeEvent) => void): LongPressGestureType;
294
/** Callback when gesture ends */
295
onEnd(callback: (event: GestureStateChangeEvent) => void): LongPressGestureType;
296
}
297
```
298
299
### Gesture Composition
300
301
Methods for combining multiple gestures with different relationship rules.
302
303
```typescript { .api }
304
/**
305
* Race composition - first gesture to activate wins, others are cancelled
306
* @param gestures - Array of gestures to race
307
*/
308
function Race(...gestures: GestureType[]): RaceGestureType;
309
310
/**
311
* Simultaneous composition - gestures can be active at the same time
312
* @param gestures - Array of gestures that can run simultaneously
313
*/
314
function Simultaneous(...gestures: GestureType[]): SimultaneousGestureType;
315
316
/**
317
* Exclusive composition - only one gesture can be active at a time
318
* @param gestures - Array of mutually exclusive gestures
319
*/
320
function Exclusive(...gestures: GestureType[]): ExclusiveGestureType;
321
322
// Composition types
323
interface RaceGestureType extends GestureType {}
324
interface SimultaneousGestureType extends GestureType {}
325
interface ExclusiveGestureType extends GestureType {}
326
interface ComposedGestureType extends GestureType {}
327
```
328
329
**Usage Example:**
330
331
```typescript
332
const tapGesture = Gesture.Tap().onEnd(() => console.log("Tap"));
333
const longPressGesture = Gesture.LongPress().onStart(() => console.log("Long press"));
334
335
// Race - first to activate wins
336
const raceGesture = Gesture.Race(tapGesture, longPressGesture);
337
338
// Simultaneous - both can be active
339
const simultaneousGesture = Gesture.Simultaneous(
340
Gesture.Pan(),
341
Gesture.Pinch()
342
);
343
344
// Exclusive - only one at a time
345
const exclusiveGesture = Gesture.Exclusive(
346
Gesture.Pan(),
347
Gesture.Rotation()
348
);
349
```
350
351
### Advanced Gesture Types
352
353
Additional gesture types for specialized interactions.
354
355
```typescript { .api }
356
/**
357
* Native gesture type for wrapping platform-specific gestures
358
*/
359
interface NativeGestureType {
360
/** iOS: Use UIPanGestureRecognizer, Android: use built-in touch handling */
361
shouldActivateOnStart(enabled: boolean): NativeGestureType;
362
/** Configure gesture to disallow interruption */
363
disallowInterruption(enabled: boolean): NativeGestureType;
364
}
365
366
/**
367
* Manual gesture type for programmatic control
368
*/
369
interface ManualGestureType {
370
/** Manually set gesture state */
371
setState(state: number): void;
372
}
373
374
/**
375
* Hover gesture type for mouse/trackpad hover (Web/desktop only)
376
*/
377
interface HoverGestureType {
378
/** Callback when hover starts */
379
onStart(callback: (event: GestureStateChangeEvent) => void): HoverGestureType;
380
/** Callback when hover ends */
381
onEnd(callback: (event: GestureStateChangeEvent) => void): HoverGestureType;
382
}
383
```
384
385
### Common Gesture Configuration
386
387
All gesture types share common configuration methods and lifecycle callbacks available on the base gesture class.
388
389
```typescript { .api }
390
/**
391
* Common methods available on all gesture types
392
* These methods provide lifecycle callbacks, configuration, and gesture relationships
393
*/
394
interface BaseGestureConfiguration {
395
// Lifecycle callbacks
396
/** Called when gesture begins recognition */
397
onBegin(callback: (event: GestureStateChangeEvent) => void): GestureType;
398
/** Called when gesture starts (becomes active) */
399
onStart(callback: (event: GestureStateChangeEvent) => void): GestureType;
400
/** Called when gesture ends */
401
onEnd(callback: (event: GestureStateChangeEvent, success: boolean) => void): GestureType;
402
/** Called when gesture finishes (success or failure) */
403
onFinalize(callback: (event: GestureStateChangeEvent, success: boolean) => void): GestureType;
404
405
// Touch event callbacks
406
/** Called when touches begin */
407
onTouchesDown(callback: (event: GestureTouchEvent) => void): GestureType;
408
/** Called when touches move */
409
onTouchesMove(callback: (event: GestureTouchEvent) => void): GestureType;
410
/** Called when touches end */
411
onTouchesUp(callback: (event: GestureTouchEvent) => void): GestureType;
412
/** Called when touches are cancelled */
413
onTouchesCancelled(callback: (event: GestureTouchEvent) => void): GestureType;
414
415
// Configuration methods
416
/** Enable or disable the gesture */
417
enabled(enabled: boolean): GestureType;
418
/** Cancel gesture when touch moves outside bounds */
419
shouldCancelWhenOutside(value: boolean): GestureType;
420
/** Configure hit area for gesture recognition */
421
hitSlop(hitSlop: HitSlop): GestureType;
422
/** Set cursor style when gesture is active (Web only) */
423
activeCursor(cursor: ActiveCursor): GestureType;
424
/** Configure which mouse buttons trigger gesture (Web & Android) */
425
mouseButton(button: MouseButton): GestureType;
426
/** Run callbacks on JavaScript thread */
427
runOnJS(runOnJS: boolean): GestureType;
428
/** Allow gesture to run simultaneously with external gestures */
429
simultaneousWithExternalGesture(...gestures: GestureRef[]): GestureType;
430
/** Require external gestures to fail before this gesture activates */
431
requireExternalGestureToFail(...gestures: GestureRef[]): GestureType;
432
/** Block external gestures when this gesture is active */
433
blocksExternalGesture(...gestures: GestureRef[]): GestureType;
434
/** Set test ID for testing */
435
withTestId(id: string): GestureType;
436
/** Cancel touches in UIScrollView when gesture activates (iOS only) */
437
cancelsTouchesInView(value: boolean): GestureType;
438
/** Associate gesture with a ref for programmatic control */
439
withRef(ref: React.MutableRefObject<GestureType>): GestureType;
440
441
// Continuous gestures only (Pan, Pinch, Rotation)
442
/** Called during gesture updates (continuous gestures only) */
443
onUpdate?(callback: (event: GestureUpdateEvent) => void): GestureType;
444
/** Alias for onUpdate (continuous gestures only) */
445
onChange?(callback: (event: GestureUpdateEvent) => void): GestureType;
446
/** Require manual activation instead of automatic (continuous gestures only) */
447
manualActivation?(enabled: boolean): GestureType;
448
}
449
450
// Supporting types
451
interface HitSlop {
452
left?: number;
453
right?: number;
454
top?: number;
455
bottom?: number;
456
vertical?: number;
457
horizontal?: number;
458
width?: number;
459
height?: number;
460
}
461
462
type ActiveCursor =
463
| "auto" | "default" | "none" | "context-menu" | "help" | "pointer"
464
| "progress" | "wait" | "cell" | "crosshair" | "text" | "vertical-text"
465
| "alias" | "copy" | "move" | "no-drop" | "not-allowed" | "grab"
466
| "grabbing" | "e-resize" | "n-resize" | "ne-resize" | "nw-resize"
467
| "s-resize" | "se-resize" | "sw-resize" | "w-resize" | "ew-resize"
468
| "ns-resize" | "nesw-resize" | "nwse-resize" | "col-resize" | "row-resize"
469
| "all-scroll" | "zoom-in" | "zoom-out";
470
471
interface GestureRef {
472
current: GestureType | null;
473
}
474
```
475
476
**Usage Example:**
477
478
```typescript
479
import React, { useRef } from "react";
480
import { GestureDetector, Gesture } from "react-native-gesture-handler";
481
482
function CommonConfigurationExample() {
483
const gestureRef = useRef(null);
484
485
const panGesture = Gesture.Pan()
486
.enabled(true)
487
.shouldCancelWhenOutside(true)
488
.hitSlop({ horizontal: 10, vertical: 10 })
489
.runOnJS(true)
490
.withRef(gestureRef)
491
.withTestId("pan-gesture")
492
.onBegin(() => console.log("Pan began"))
493
.onStart(() => console.log("Pan started"))
494
.onUpdate((event) => console.log("Pan update:", event.translationX))
495
.onEnd((event, success) => console.log("Pan ended:", success))
496
.onFinalize(() => console.log("Pan finalized"));
497
498
const tapGesture = Gesture.Tap()
499
.simultaneousWithExternalGesture(gestureRef)
500
.onStart(() => console.log("Tap (simultaneous with pan)"));
501
502
return (
503
<GestureDetector gesture={Gesture.Simultaneous(panGesture, tapGesture)}>
504
{/* Your component */}
505
</GestureDetector>
506
);
507
}
508
```
509
510
## Integration with Reanimated
511
512
The modern Gesture API integrates seamlessly with react-native-reanimated for smooth animations:
513
514
```typescript
515
import { useSharedValue } from "react-native-reanimated";
516
import { Gesture, GestureDetector } from "react-native-gesture-handler";
517
518
function AnimatedComponent() {
519
const translateX = useSharedValue(0);
520
521
const panGesture = Gesture.Pan()
522
.onUpdate((event) => {
523
translateX.value = event.translationX;
524
});
525
526
return (
527
<GestureDetector gesture={panGesture}>
528
{/* Your animated view */}
529
</GestureDetector>
530
);
531
}
532
```