CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-native-gesture-handler

Declarative API exposing platform native touch and gesture system to React Native

Pending
Overview
Eval results
Files

gestures.mddocs/

Modern Gesture API

The recommended approach for creating sophisticated gesture interactions using the new Gesture API with GestureDetector and Gesture factory methods.

Capabilities

GestureDetector

Main component for detecting and handling gestures using the modern API. This component wraps your views and applies gesture recognition to them.

/**
 * Component for detecting gestures using the modern Gesture API
 * Wraps child components and applies gesture recognition
 */
function GestureDetector(props: {
  gesture: ComposedGesture | GestureType;
  userSelect?: UserSelect;
  enableContextMenu?: boolean;
  touchAction?: TouchAction;
  children?: React.ReactNode;
}): JSX.Element;

// Web-specific prop types
type UserSelect = "none" | "auto" | "text" | "contain" | "all";
type TouchAction = "none" | "auto" | "pan-x" | "pan-y" | "manipulation";

Usage Example:

import React from "react";
import { View } from "react-native";
import { GestureDetector, Gesture } from "react-native-gesture-handler";

function MyComponent() {
  const tapGesture = Gesture.Tap()
    .numberOfTaps(2)
    .onEnd(() => {
      console.log("Double tap!");
    });

  return (
    <GestureDetector gesture={tapGesture}>
      <View style={{ width: 100, height: 100, backgroundColor: "blue" }} />
    </GestureDetector>
  );
}

Gesture Factory

Factory object providing methods to create different types of gestures. Each method returns a configurable gesture instance.

/**
 * Factory object for creating gesture instances
 * Provides methods for all supported gesture types
 */
interface GestureObjects {
  Tap(): TapGestureType;
  Pan(): PanGestureType;
  Pinch(): PinchGestureType;
  Rotation(): RotationGestureType;
  Fling(): FlingGestureType;
  LongPress(): LongPressGestureType;
  ForceTouch(): ForceTouchGestureType; // Deprecated
  Native(): NativeGestureType;
  Manual(): ManualGestureType;
  Hover(): HoverGestureType;
  Race(...gestures: GestureType[]): RaceGestureType;
  Simultaneous(...gestures: GestureType[]): SimultaneousGestureType;
  Exclusive(...gestures: GestureType[]): ExclusiveGestureType;
}

// Available as Gesture export
declare const Gesture: GestureObjects;

Tap Gesture

Recognizes single or multiple tap gestures with configurable parameters for timing and positioning.

/**
 * Tap gesture type with configuration methods
 * Recognizes single or multiple taps with configurable constraints
 */
interface TapGestureType {
  /** Set minimum number of pointers required (default: 1) */
  minPointers(count: number): TapGestureType;
  /** Set required number of consecutive taps (default: 1) */
  numberOfTaps(count: number): TapGestureType;
  /** Set maximum distance pointer can travel (in points) */
  maxDistance(distance: number): TapGestureType;
  /** Set maximum tap duration in milliseconds */
  maxDuration(ms: number): TapGestureType;
  /** Set maximum delay between taps in milliseconds */
  maxDelay(ms: number): TapGestureType;
  /** Set maximum travel distance on X axis (in points) */
  maxDeltaX(delta: number): TapGestureType;
  /** Set maximum travel distance on Y axis (in points) */
  maxDeltaY(delta: number): TapGestureType;
  /** Callback when gesture begins */
  onBegin(callback: (event: GestureStateChangeEvent) => void): TapGestureType;
  /** Callback when gesture starts */
  onStart(callback: (event: GestureStateChangeEvent) => void): TapGestureType;
  /** Callback when gesture ends successfully */
  onEnd(callback: (event: GestureStateChangeEvent) => void): TapGestureType;
  /** Callback when gesture is cancelled or fails */
  onFinalize(callback: (event: GestureStateChangeEvent) => void): TapGestureType;
}

Usage Example:

const doubleTap = Gesture.Tap()
  .numberOfTaps(2)
  .maxDelay(500)
  .onEnd(() => {
    console.log("Double tap detected!");
  });

const tripleTap = Gesture.Tap()
  .numberOfTaps(3)
  .maxDistance(20)
  .onEnd(() => {
    console.log("Triple tap detected!");
  });

Pan Gesture

Recognizes dragging gestures with velocity, translation, and configurable activation areas.

/**
 * Pan gesture type for drag interactions
 * Provides translation, velocity, and configurable activation constraints
 */
interface PanGestureType {
  /** Set Y-axis activation offset range */
  activeOffsetY(offset: number | number[]): PanGestureType;
  /** Set X-axis activation offset range */
  activeOffsetX(offset: number | number[]): PanGestureType;
  /** Set Y-axis failure offset range */
  failOffsetY(offset: number | number[]): PanGestureType;
  /** Set X-axis failure offset range */
  failOffsetX(offset: number | number[]): PanGestureType;
  /** Set minimum number of pointers (default: 1) */
  minPointers(count: number): PanGestureType;
  /** Set maximum number of pointers (default: 10) */
  maxPointers(count: number): PanGestureType;
  /** Set minimum travel distance to activate */
  minDistance(distance: number): PanGestureType;
  /** Set minimum velocity to activate */
  minVelocity(velocity: number): PanGestureType;
  /** Set minimum X-axis velocity to activate */
  minVelocityX(velocity: number): PanGestureType;
  /** Set minimum Y-axis velocity to activate */
  minVelocityY(velocity: number): PanGestureType;
  /** Android only: average multiple touch positions */
  averageTouches(enabled: boolean): PanGestureType;
  /** iOS only: enable trackpad two-finger gesture support */
  enableTrackpadTwoFingerGesture(enabled: boolean): PanGestureType;
  /** Activate pan gesture after long press delay */
  activateAfterLongPress(duration: number): PanGestureType;
  /** Callback during gesture updates */
  onUpdate(callback: (event: GestureUpdateEvent<PanGestureChangeEventPayload>) => void): PanGestureType;
  /** Callback when gesture begins */
  onBegin(callback: (event: GestureStateChangeEvent) => void): PanGestureType;
  /** Callback when gesture starts */
  onStart(callback: (event: GestureStateChangeEvent) => void): PanGestureType;
  /** Callback when gesture ends */
  onEnd(callback: (event: GestureStateChangeEvent<PanGestureChangeEventPayload>) => void): PanGestureType;
}

interface PanGestureChangeEventPayload {
  translationX: number;
  translationY: number;
  velocityX: number;
  velocityY: number;
}

Usage Example:

const panGesture = Gesture.Pan()
  .minDistance(10)
  .activeOffsetX([-10, 10])
  .onUpdate((event) => {
    console.log(`Translation: ${event.translationX}, ${event.translationY}`);
    console.log(`Velocity: ${event.velocityX}, ${event.velocityY}`);
  })
  .onEnd(() => {
    console.log("Pan gesture ended");
  });

Pinch Gesture

Recognizes pinch/zoom gestures providing scale factor and focal point information.

/**
 * Pinch gesture type for scaling interactions
 * Provides scale factor and focal point coordinates
 */
interface PinchGestureType {
  /** Callback during gesture updates */
  onUpdate(callback: (event: GestureUpdateEvent<PinchGestureChangeEventPayload>) => void): PinchGestureType;
  /** Callback when gesture begins */
  onBegin(callback: (event: GestureStateChangeEvent) => void): PinchGestureType;
  /** Callback when gesture starts */
  onStart(callback: (event: GestureStateChangeEvent) => void): PinchGestureType;
  /** Callback when gesture ends */
  onEnd(callback: (event: GestureStateChangeEvent<PinchGestureChangeEventPayload>) => void): PinchGestureType;
}

interface PinchGestureChangeEventPayload {
  scale: number;
  focalX: number;
  focalY: number;
  velocity: number;
}

Rotation Gesture

Recognizes rotation gestures providing rotation angle and anchor point information.

/**
 * Rotation gesture type for rotating interactions
 * Provides rotation angle in radians and anchor point coordinates
 */
interface RotationGestureType {
  /** Callback during gesture updates */
  onUpdate(callback: (event: GestureUpdateEvent<RotationGestureChangeEventPayload>) => void): RotationGestureType;
  /** Callback when gesture begins */
  onBegin(callback: (event: GestureStateChangeEvent) => void): RotationGestureType;
  /** Callback when gesture starts */
  onStart(callback: (event: GestureStateChangeEvent) => void): RotationGestureType;
  /** Callback when gesture ends */
  onEnd(callback: (event: GestureStateChangeEvent<RotationGestureChangeEventPayload>) => void): RotationGestureType;
}

interface RotationGestureChangeEventPayload {
  rotation: number; // in radians
  anchorX: number;
  anchorY: number;
  velocity: number;
}

Fling Gesture

Recognizes quick swipe/fling gestures with directional constraints.

/**
 * Fling gesture type for quick swipe movements
 * Recognizes fast directional movements with configurable constraints
 */
interface FlingGestureType {
  /** Set allowed fling directions using Directions constants */
  direction(direction: number): FlingGestureType;
  /** Set number of pointers required (default: 1) */
  numberOfPointers(count: number): FlingGestureType;
  /** Callback when gesture is recognized */
  onStart(callback: (event: GestureStateChangeEvent) => void): FlingGestureType;
  /** Callback when gesture ends */
  onEnd(callback: (event: GestureStateChangeEvent) => void): FlingGestureType;
}

Long Press Gesture

Recognizes long press gestures with configurable duration and movement constraints.

/**
 * Long press gesture type
 * Recognizes press and hold gestures with configurable timing
 */
interface LongPressGestureType {
  /** Set minimum press duration in milliseconds (default: 500) */
  minDuration(ms: number): LongPressGestureType;
  /** Set maximum allowed movement distance */
  maxDistance(distance: number): LongPressGestureType;
  /** Callback when gesture is activated */
  onStart(callback: (event: GestureStateChangeEvent) => void): LongPressGestureType;
  /** Callback when gesture ends */
  onEnd(callback: (event: GestureStateChangeEvent) => void): LongPressGestureType;
}

Gesture Composition

Methods for combining multiple gestures with different relationship rules.

/**
 * Race composition - first gesture to activate wins, others are cancelled
 * @param gestures - Array of gestures to race
 */
function Race(...gestures: GestureType[]): RaceGestureType;

/**
 * Simultaneous composition - gestures can be active at the same time
 * @param gestures - Array of gestures that can run simultaneously
 */
function Simultaneous(...gestures: GestureType[]): SimultaneousGestureType;

/**
 * Exclusive composition - only one gesture can be active at a time
 * @param gestures - Array of mutually exclusive gestures
 */
function Exclusive(...gestures: GestureType[]): ExclusiveGestureType;

// Composition types
interface RaceGestureType extends GestureType {}
interface SimultaneousGestureType extends GestureType {}
interface ExclusiveGestureType extends GestureType {}
interface ComposedGestureType extends GestureType {}

Usage Example:

const tapGesture = Gesture.Tap().onEnd(() => console.log("Tap"));
const longPressGesture = Gesture.LongPress().onStart(() => console.log("Long press"));

// Race - first to activate wins
const raceGesture = Gesture.Race(tapGesture, longPressGesture);

// Simultaneous - both can be active
const simultaneousGesture = Gesture.Simultaneous(
  Gesture.Pan(),
  Gesture.Pinch()
);

// Exclusive - only one at a time
const exclusiveGesture = Gesture.Exclusive(
  Gesture.Pan(),
  Gesture.Rotation()
);

Advanced Gesture Types

Additional gesture types for specialized interactions.

/**
 * Native gesture type for wrapping platform-specific gestures
 */
interface NativeGestureType {
  /** iOS: Use UIPanGestureRecognizer, Android: use built-in touch handling */
  shouldActivateOnStart(enabled: boolean): NativeGestureType;
  /** Configure gesture to disallow interruption */
  disallowInterruption(enabled: boolean): NativeGestureType;
}

/**
 * Manual gesture type for programmatic control
 */
interface ManualGestureType {
  /** Manually set gesture state */
  setState(state: number): void;
}

/**
 * Hover gesture type for mouse/trackpad hover (Web/desktop only)
 */
interface HoverGestureType {
  /** Callback when hover starts */
  onStart(callback: (event: GestureStateChangeEvent) => void): HoverGestureType;
  /** Callback when hover ends */
  onEnd(callback: (event: GestureStateChangeEvent) => void): HoverGestureType;
}

Common Gesture Configuration

All gesture types share common configuration methods and lifecycle callbacks available on the base gesture class.

/**
 * Common methods available on all gesture types
 * These methods provide lifecycle callbacks, configuration, and gesture relationships
 */
interface BaseGestureConfiguration {
  // Lifecycle callbacks
  /** Called when gesture begins recognition */
  onBegin(callback: (event: GestureStateChangeEvent) => void): GestureType;
  /** Called when gesture starts (becomes active) */
  onStart(callback: (event: GestureStateChangeEvent) => void): GestureType;
  /** Called when gesture ends */
  onEnd(callback: (event: GestureStateChangeEvent, success: boolean) => void): GestureType;
  /** Called when gesture finishes (success or failure) */
  onFinalize(callback: (event: GestureStateChangeEvent, success: boolean) => void): GestureType;

  // Touch event callbacks
  /** Called when touches begin */
  onTouchesDown(callback: (event: GestureTouchEvent) => void): GestureType;
  /** Called when touches move */
  onTouchesMove(callback: (event: GestureTouchEvent) => void): GestureType;
  /** Called when touches end */
  onTouchesUp(callback: (event: GestureTouchEvent) => void): GestureType;
  /** Called when touches are cancelled */
  onTouchesCancelled(callback: (event: GestureTouchEvent) => void): GestureType;

  // Configuration methods
  /** Enable or disable the gesture */
  enabled(enabled: boolean): GestureType;
  /** Cancel gesture when touch moves outside bounds */
  shouldCancelWhenOutside(value: boolean): GestureType;
  /** Configure hit area for gesture recognition */
  hitSlop(hitSlop: HitSlop): GestureType;
  /** Set cursor style when gesture is active (Web only) */
  activeCursor(cursor: ActiveCursor): GestureType;
  /** Configure which mouse buttons trigger gesture (Web & Android) */
  mouseButton(button: MouseButton): GestureType;
  /** Run callbacks on JavaScript thread */
  runOnJS(runOnJS: boolean): GestureType;
  /** Allow gesture to run simultaneously with external gestures */
  simultaneousWithExternalGesture(...gestures: GestureRef[]): GestureType;
  /** Require external gestures to fail before this gesture activates */
  requireExternalGestureToFail(...gestures: GestureRef[]): GestureType;
  /** Block external gestures when this gesture is active */
  blocksExternalGesture(...gestures: GestureRef[]): GestureType;
  /** Set test ID for testing */
  withTestId(id: string): GestureType;
  /** Cancel touches in UIScrollView when gesture activates (iOS only) */
  cancelsTouchesInView(value: boolean): GestureType;
  /** Associate gesture with a ref for programmatic control */
  withRef(ref: React.MutableRefObject<GestureType>): GestureType;

  // Continuous gestures only (Pan, Pinch, Rotation)
  /** Called during gesture updates (continuous gestures only) */
  onUpdate?(callback: (event: GestureUpdateEvent) => void): GestureType;
  /** Alias for onUpdate (continuous gestures only) */
  onChange?(callback: (event: GestureUpdateEvent) => void): GestureType;
  /** Require manual activation instead of automatic (continuous gestures only) */
  manualActivation?(enabled: boolean): GestureType;
}

// Supporting types
interface HitSlop {
  left?: number;
  right?: number;
  top?: number;
  bottom?: number;
  vertical?: number;
  horizontal?: number;
  width?: number;
  height?: number;
}

type ActiveCursor = 
  | "auto" | "default" | "none" | "context-menu" | "help" | "pointer"
  | "progress" | "wait" | "cell" | "crosshair" | "text" | "vertical-text"
  | "alias" | "copy" | "move" | "no-drop" | "not-allowed" | "grab"
  | "grabbing" | "e-resize" | "n-resize" | "ne-resize" | "nw-resize"
  | "s-resize" | "se-resize" | "sw-resize" | "w-resize" | "ew-resize"
  | "ns-resize" | "nesw-resize" | "nwse-resize" | "col-resize" | "row-resize"
  | "all-scroll" | "zoom-in" | "zoom-out";

interface GestureRef {
  current: GestureType | null;
}

Usage Example:

import React, { useRef } from "react";
import { GestureDetector, Gesture } from "react-native-gesture-handler";

function CommonConfigurationExample() {
  const gestureRef = useRef(null);

  const panGesture = Gesture.Pan()
    .enabled(true)
    .shouldCancelWhenOutside(true)
    .hitSlop({ horizontal: 10, vertical: 10 })
    .runOnJS(true)
    .withRef(gestureRef)
    .withTestId("pan-gesture")
    .onBegin(() => console.log("Pan began"))
    .onStart(() => console.log("Pan started"))
    .onUpdate((event) => console.log("Pan update:", event.translationX))
    .onEnd((event, success) => console.log("Pan ended:", success))
    .onFinalize(() => console.log("Pan finalized"));

  const tapGesture = Gesture.Tap()
    .simultaneousWithExternalGesture(gestureRef)
    .onStart(() => console.log("Tap (simultaneous with pan)"));

  return (
    <GestureDetector gesture={Gesture.Simultaneous(panGesture, tapGesture)}>
      {/* Your component */}
    </GestureDetector>
  );
}

Integration with Reanimated

The modern Gesture API integrates seamlessly with react-native-reanimated for smooth animations:

import { useSharedValue } from "react-native-reanimated";
import { Gesture, GestureDetector } from "react-native-gesture-handler";

function AnimatedComponent() {
  const translateX = useSharedValue(0);
  
  const panGesture = Gesture.Pan()
    .onUpdate((event) => {
      translateX.value = event.translationX;
    });

  return (
    <GestureDetector gesture={panGesture}>
      {/* Your animated view */}
    </GestureDetector>
  );
}

Install with Tessl CLI

npx tessl i tessl/npm-react-native-gesture-handler

docs

advanced-components.md

buttons.md

components.md

constants.md

events.md

gestures.md

index.md

setup.md

tile.json