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

events.mddocs/

Gesture Event System

Comprehensive event types and payload structures for handling gesture interactions with detailed coordinate and timing information.

Capabilities

Core Event Types

Base event types used throughout the gesture handling system.

/**
 * Basic gesture event structure
 * Contains native event data with handler and state information
 */
interface GestureEvent<T = Record<string, unknown>> {
  nativeEvent: T & {
    handlerTag: number;
    numberOfPointers: number;
    state: number;
  };
}

/**
 * Handler state change event structure
 * Fired when gesture handler changes state (begin, active, end, etc.)
 */
interface HandlerStateChangeEvent<T = Record<string, unknown>> {
  nativeEvent: T & {
    handlerTag: number;
    numberOfPointers: number;
    state: number;
    oldState: number;
  };
}

Modern API Event Types

Event types used with the new Gesture API (GestureDetector and Gesture factory).

/**
 * Update event for the modern Gesture API
 * Provides real-time gesture data during interaction
 */
interface GestureUpdateEvent<T = Record<string, unknown>> {
  x: number;
  y: number;
  absoluteX: number;
  absoluteY: number;
  handlerTag: number;
  numberOfPointers: number;
  state: number;
} & T;

/**
 * State change event for the modern Gesture API
 * Fired when gesture state transitions occur
 */
interface GestureStateChangeEvent<T = Record<string, unknown>> {
  x: number;
  y: number;
  absoluteX: number;
  absoluteY: number;
  handlerTag: number;
  numberOfPointers: number;
  state: number;
  oldState: number;
} & T;

Touch Event Types

Advanced touch event types providing detailed touch information.

/**
 * Touch event with multiple pointer support
 * Contains detailed information about all active touches
 */
interface GestureTouchEvent {
  handlerTag: number;
  numberOfTouches: number;
  state: number;
  eventType: number;
  allTouches: TouchData[];
  changedTouches: TouchData[];
}

/**
 * Individual touch data
 * Detailed information about a single touch point
 */
interface TouchData {
  id: number;
  x: number;
  y: number;
  absoluteX: number;
  absoluteY: number;
  force?: number;
  timestamp: number;
}

Gesture-Specific Event Payloads

Tap Gesture Events

Events specific to tap gesture interactions.

/**
 * Tap gesture event payload
 * Contains position information for tap gestures
 */
interface TapGestureHandlerEventPayload {
  x: number;
  y: number;
  absoluteX: number;
  absoluteY: number;
}

// Complete tap gesture event types
type TapGestureHandlerGestureEvent = GestureEvent<TapGestureHandlerEventPayload>;
type TapGestureHandlerStateChangeEvent = HandlerStateChangeEvent<TapGestureHandlerEventPayload>;

Pan Gesture Events

Events specific to pan/drag gesture interactions.

/**
 * Pan gesture event payload
 * Contains position, translation, and velocity information
 */
interface PanGestureHandlerEventPayload {
  x: number;
  y: number;
  absoluteX: number;
  absoluteY: number;
  translationX: number;
  translationY: number;
  velocityX: number;
  velocityY: number;
  stylusData?: StylusData;
}

/**
 * Pan gesture change event payload (New API)
 * Streamlined payload for modern pan gestures
 */
interface PanGestureChangeEventPayload {
  translationX: number;
  translationY: number;
  velocityX: number;
  velocityY: number;
}

/**
 * Stylus-specific data for supported devices
 */
interface StylusData {
  pressure: number;
  tiltX: number;
  tiltY: number;
  twist: number;
}

// Complete pan gesture event types
type PanGestureHandlerGestureEvent = GestureEvent<PanGestureHandlerEventPayload>;
type PanGestureHandlerStateChangeEvent = HandlerStateChangeEvent<PanGestureHandlerEventPayload>;

Pinch Gesture Events

Events specific to pinch/zoom gesture interactions.

/**
 * Pinch gesture event payload
 * Contains scale factor and focal point information
 */
interface PinchGestureHandlerEventPayload {
  x: number;
  y: number;
  absoluteX: number;
  absoluteY: number;
  scale: number;
  focalX: number;
  focalY: number;
  velocity: number;
}

/**
 * Pinch gesture change event payload (New API)
 * Streamlined payload for modern pinch gestures
 */
interface PinchGestureChangeEventPayload {
  scale: number;
  focalX: number;
  focalY: number;
  velocity: number;
}

// Complete pinch gesture event types
type PinchGestureHandlerGestureEvent = GestureEvent<PinchGestureHandlerEventPayload>;
type PinchGestureHandlerStateChangeEvent = HandlerStateChangeEvent<PinchGestureHandlerEventPayload>;

Rotation Gesture Events

Events specific to rotation gesture interactions.

/**
 * Rotation gesture event payload
 * Contains rotation angle and anchor point information
 */
interface RotationGestureHandlerEventPayload {
  x: number;
  y: number;
  absoluteX: number;
  absoluteY: number;
  rotation: number; // in radians
  anchorX: number;
  anchorY: number;
  velocity: number;
}

// Complete rotation gesture event types
type RotationGestureHandlerGestureEvent = GestureEvent<RotationGestureHandlerEventPayload>;
type RotationGestureHandlerStateChangeEvent = HandlerStateChangeEvent<RotationGestureHandlerEventPayload>;

Long Press Gesture Events

Events specific to long press gesture interactions.

/**
 * Long press gesture event payload
 * Contains position and duration information
 */
interface LongPressGestureHandlerEventPayload {
  x: number;
  y: number;
  absoluteX: number;
  absoluteY: number;
  duration: number; // in milliseconds
}

// Complete long press gesture event types
type LongPressGestureHandlerGestureEvent = GestureEvent<LongPressGestureHandlerEventPayload>;
type LongPressGestureHandlerStateChangeEvent = HandlerStateChangeEvent<LongPressGestureHandlerEventPayload>;

Fling Gesture Events

Events specific to fling/swipe gesture interactions.

/**
 * Fling gesture event payload
 * Contains position information for fling gestures
 */
interface FlingGestureHandlerEventPayload {
  x: number;
  y: number;
  absoluteX: number;
  absoluteY: number;
}

// Complete fling gesture event types
type FlingGestureHandlerGestureEvent = GestureEvent<FlingGestureHandlerEventPayload>;
type FlingGestureHandlerStateChangeEvent = HandlerStateChangeEvent<FlingGestureHandlerEventPayload>;

Force Touch Gesture Events (Deprecated)

Events specific to force touch gesture interactions (deprecated feature).

/**
 * Force touch gesture event payload (deprecated)
 * Contains position and force information
 * @deprecated Force touch is deprecated
 */
interface ForceTouchGestureHandlerEventPayload {
  x: number;
  y: number;
  absoluteX: number;
  absoluteY: number;
  force: number; // 0.0 to 1.0
}

/**
 * Force touch gesture change event payload (New API, deprecated)
 * @deprecated Force touch is deprecated
 */
interface ForceTouchGestureChangeEventPayload {
  force: number;
}

// Complete force touch gesture event types
type ForceTouchGestureHandlerGestureEvent = GestureEvent<ForceTouchGestureHandlerEventPayload>;
type ForceTouchGestureHandlerStateChangeEvent = HandlerStateChangeEvent<ForceTouchGestureHandlerEventPayload>;

Native View Gesture Events

Events specific to native view gesture interactions.

/**
 * Native view gesture event payload
 * Contains pointer inside/outside information
 */
interface NativeViewGestureHandlerPayload {
  pointerInside: boolean;
}

// Complete native view gesture event types
type NativeViewGestureHandlerGestureEvent = GestureEvent<NativeViewGestureHandlerPayload>;
type NativeViewGestureHandlerStateChangeEvent = HandlerStateChangeEvent<NativeViewGestureHandlerPayload>;

Event Usage Examples

Basic Event Handling

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

function EventHandlingExample() {
  const tapGesture = Gesture.Tap()
    .onBegin((event) => {
      console.log("Tap began at:", event.x, event.y);
    })
    .onStart((event) => {
      console.log("Tap started at:", event.absoluteX, event.absoluteY);
    })
    .onEnd((event) => {
      console.log("Tap ended with state:", event.state);
    });

  const panGesture = Gesture.Pan()
    .onUpdate((event) => {
      console.log("Pan translation:", event.translationX, event.translationY);
      console.log("Pan velocity:", event.velocityX, event.velocityY);
    })
    .onEnd((event) => {
      console.log("Pan ended with final translation:", event.translationX, event.translationY);
    });

  return (
    <GestureDetector gesture={Gesture.Simultaneous(tapGesture, panGesture)}>
      <View style={{ width: 200, height: 200, backgroundColor: "lightblue" }}>
        <Text>Tap and Pan Events</Text>
      </View>
    </GestureDetector>
  );
}

Advanced Event Processing

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

function AdvancedEventProcessing() {
  const handlePinchUpdate = useCallback((event: GestureUpdateEvent<PinchGestureChangeEventPayload>) => {
    const { scale, focalX, focalY, velocity } = event;
    
    // Process pinch data
    console.log(`Pinch: scale=${scale.toFixed(2)}, focal=(${focalX.toFixed(0)}, ${focalY.toFixed(0)})`);
    
    // Apply scale with velocity damping
    const dampedScale = scale * (1 - velocity * 0.01);
    console.log(`Damped scale: ${dampedScale.toFixed(2)}`);
  }, []);

  const handleRotationUpdate = useCallback((event: GestureUpdateEvent<RotationGestureChangeEventPayload>) => {
    const { rotation, anchorX, anchorY, velocity } = event;
    
    // Convert radians to degrees
    const degrees = (rotation * 180) / Math.PI;
    console.log(`Rotation: ${degrees.toFixed(1)}°, anchor=(${anchorX.toFixed(0)}, ${anchorY.toFixed(0)})`);
  }, []);

  const pinchGesture = Gesture.Pinch().onUpdate(handlePinchUpdate);
  const rotationGesture = Gesture.Rotation().onUpdate(handleRotationUpdate);

  return (
    <GestureDetector gesture={Gesture.Simultaneous(pinchGesture, rotationGesture)}>
      <View style={{ width: 300, height: 300, backgroundColor: "lightgreen" }} />
    </GestureDetector>
  );
}

Touch Event Processing

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

function TouchEventProcessing() {
  const panGesture = Gesture.Pan()
    .onUpdate((event) => {
      // Access basic touch information
      console.log(`Touch at: (${event.x}, ${event.y})`);
      console.log(`Absolute position: (${event.absoluteX}, ${event.absoluteY})`);
      console.log(`Number of pointers: ${event.numberOfPointers}`);
      
      // Pan-specific data
      if ('translationX' in event && 'translationY' in event) {
        console.log(`Translation: (${event.translationX}, ${event.translationY})`);
        console.log(`Velocity: (${event.velocityX}, ${event.velocityY})`);
      }
    });

  return (
    <GestureDetector gesture={panGesture}>
      <View style={{ width: 200, height: 200, backgroundColor: "orange" }} />
    </GestureDetector>
  );
}

Event State Management

Gesture States

Understanding gesture states is crucial for proper event handling:

import { State } from "react-native-gesture-handler";

function handleStateChange(event: GestureStateChangeEvent) {
  switch (event.state) {
    case State.UNDETERMINED:
      console.log("Gesture state: UNDETERMINED");
      break;
    case State.FAILED:
      console.log("Gesture state: FAILED");
      break;
    case State.BEGAN:
      console.log("Gesture state: BEGAN");
      break;
    case State.CANCELLED:
      console.log("Gesture state: CANCELLED");
      break;
    case State.ACTIVE:
      console.log("Gesture state: ACTIVE");
      break;
    case State.END:
      console.log("Gesture state: END");
      break;
  }
}

Event Timing

Events provide timing information for performance analysis:

function analyzeEventTiming(event: GestureUpdateEvent) {
  // Most events include timestamp information
  const timestamp = Date.now();
  console.log(`Event processed at: ${timestamp}`);
  
  // For long press gestures, duration is available
  if ('duration' in event) {
    console.log(`Long press duration: ${event.duration}ms`);
  }
}

Performance Considerations

Event Frequency

Gesture update events fire frequently. Optimize handlers for performance:

import { runOnUI } from "react-native-reanimated";

// ✅ Good: Use runOnUI for performance-critical calculations
const panGesture = Gesture.Pan().onUpdate((event) => {
  'worklet';
  runOnUI(() => {
    // Perform calculations on UI thread
    const distance = Math.sqrt(event.translationX ** 2 + event.translationY ** 2);
    console.log(`Distance: ${distance}`);
  })();
});

// ❌ Avoid: Heavy calculations on JavaScript thread
const badPanGesture = Gesture.Pan().onUpdate((event) => {
  // Heavy calculation on JS thread - will cause stuttering
  const expensiveCalculation = performComplexMath(event);
});

Memory Management

Properly clean up event handlers to prevent memory leaks:

import React, { useEffect, useCallback } from "react";

function MemoryEfficientEvents() {
  const handleUpdate = useCallback((event) => {
    // Event handling logic
  }, []);

  useEffect(() => {
    // Cleanup if needed
    return () => {
      // Clean up resources
    };
  }, []);

  const gesture = Gesture.Pan().onUpdate(handleUpdate);

  return (
    <GestureDetector gesture={gesture}>
      {/* Component content */}
    </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