or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-react-tap-event-plugin

React plugin that addresses iOS's 300ms tap delay by injecting a TapEventPlugin into React's event system

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/react-tap-event-plugin@3.0.x

To install, run

npx @tessl/cli install tessl/npm-react-tap-event-plugin@3.0.0

index.mddocs/

React Tap Event Plugin

React Tap Event Plugin is a deprecated React plugin that addresses iOS's dreaded 300ms tap delay by injecting a TapEventPlugin into React's event system. It enables developers to use onTouchTap and onTouchTapCapture events instead of onClick to avoid mobile tap delays, though it has been deprecated since React 16.4 as modern browsers have largely resolved the original delay issue.

Package Information

  • Package Name: react-tap-event-plugin
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install react-tap-event-plugin
  • Compatibility: React 16.0.0 to < 16.4.0
  • Status: Deprecated (use only for legacy browser support)

Core Imports

var injectTapEventPlugin = require("react-tap-event-plugin");

ES6 import (if using transpilation):

import injectTapEventPlugin from "react-tap-event-plugin";

Basic Usage

var injectTapEventPlugin = require("react-tap-event-plugin");
var React = require("react");
var ReactDOM = require("react-dom");

// Inject the plugin once, early in your app lifecycle
injectTapEventPlugin();

var Main = React.createClass({
  render: function() {
    return (
      <a
        href="#"
        onTouchTap={this.handleTouchTap}
        onTouchTapCapture={this.handleTouchTapCapture}
        onClick={this.handleClick}>
        Tap Me
      </a>
    );
  },

  handleClick: function(e) {
    console.log("click", e);
  },

  handleTouchTap: function(e) {
    console.log("touchTap", e);
  },

  handleTouchTapCapture: function(e) {
    console.log("touchTapCapture", e);
  }
});

ReactDOM.render(<Main />, document.getElementById("container"));

Capabilities

Plugin Injection

The main functionality is injecting the tap event plugin into React's internal event system.

/**
 * Injects the TapEventPlugin into React's event system to handle tap events
 * Must be called once per application lifecycle, before ReactDOM.render()
 * 
 * @param {Object} strategyOverrides - Optional configuration object
 * @param {Function} strategyOverrides.shouldRejectClick - Custom click rejection strategy function
 * @throws {Error} In development mode, throws if called multiple times
 */
function injectTapEventPlugin(strategyOverrides);

Usage Examples:

// Basic injection with default settings
injectTapEventPlugin();

// Advanced: Custom click rejection strategy
injectTapEventPlugin({
  shouldRejectClick: function(lastTouchEventTimestamp, clickEventTimestamp) {
    // Always reject clicks (touch-only mode)
    return true;
  }
});

// Advanced: Longer click rejection window
injectTapEventPlugin({
  shouldRejectClick: function(lastTouchEventTimestamp, clickEventTimestamp) {
    // Reject clicks within 1000ms instead of default 750ms
    return lastTouchEventTimestamp && (clickEventTimestamp - lastTouchEventTimestamp) < 1000;
  }
});

Touch Tap Event Handling

Once injected, components can use the onTouchTap event handler.

/**
 * Touch tap event properties available in event handlers
 * This is a SyntheticEvent that follows React's standard event interface
 */
interface TouchTapEvent {
  /** Event type - always 'touchTap' */
  type: string;
  /** The target element that received the tap */
  target: HTMLElement;
  /** Current target (may differ from target during event bubbling) */
  currentTarget: HTMLElement;
  /** Event phase (1=capturing, 2=target, 3=bubbling) */
  eventPhase: number;
  /** Whether the event bubbles */
  bubbles: boolean;
  /** Whether the event can be cancelled */
  cancelable: boolean;
  /** Timestamp when the event occurred */
  timeStamp: number;
  /** Whether default action was prevented */
  defaultPrevented: boolean;
  /** Whether the event is trusted */
  isTrusted: boolean;
  
  /** Prevent the default browser behavior */
  preventDefault(): void;
  /** Stop event propagation to parent elements */
  stopPropagation(): void;
  /** Persist the event object (prevent pooling) */
  persist(): void;
}

Types

Strategy Override Configuration

/**
 * Configuration object for customizing plugin behavior
 */
interface StrategyOverrides {
  /** 
   * Custom function to determine if a click event should be rejected
   * @param lastTouchEventTimestamp - Timestamp of the last touch event (number)
   * @param clickEventTimestamp - Timestamp of the click event to evaluate (number)
   * @returns {boolean} - true if click should be rejected, false otherwise
   */
  shouldRejectClick?: (lastTouchEventTimestamp: number, clickEventTimestamp: number) => boolean;
}

Default Click Rejection Strategy

The plugin includes a built-in strategy for rejecting ghost clicks:

/**
 * Default click rejection strategy
 * Rejects click events that occur within 750ms of a touch event
 * 
 * @param {number} lastTouchEvent - Timestamp of last touch event
 * @param {number} clickTimestamp - Timestamp of click event to evaluate
 * @returns {boolean} - true if click should be rejected
 */
function defaultClickRejectionStrategy(lastTouchEvent, clickTimestamp);

Architecture

The plugin works by:

  1. Event System Integration: Injects itself into React's internal EventPluginHub using private APIs
  2. Touch Event Detection: Listens for touchstart, touchend, touchcancel, and touchmove events
  3. Tap Gesture Recognition: Detects taps by measuring distance between touch start/end (within 10px threshold)
  4. Ghost Click Prevention: Automatically rejects click events that follow touch events within 750ms
  5. Event Synthesis: Creates synthetic touchTap events that bubble through React's event system

Error Handling

The plugin includes several safety mechanisms:

  • Development Mode Protection: Throws an invariant error if injectTapEventPlugin() is called multiple times
  • Production Mode Tolerance: Silently ignores multiple injection attempts in production
  • Event Pooling: Uses React's event pooling for memory efficiency
  • Graceful Degradation: Falls back to regular click events if touch events are not available

Browser Compatibility

  • Target Browsers: Primarily iOS Safari and older mobile browsers with 300ms click delay
  • Modern Browser Note: Most modern browsers have eliminated the 300ms delay, making this plugin unnecessary
  • React Version: Compatible with React 16.0.0 to < 16.4.0 only
  • Deprecation: Plugin is deprecated and will not work with React 16.4+

Common Use Cases

  1. Legacy Mobile Support: Supporting older mobile browsers that still have the 300ms delay
  2. Hybrid Apps: React apps running in WebView containers (like Cordova/PhoneGap)
  3. Consistent Touch Response: Ensuring immediate feedback for touch interactions across all mobile devices
  4. Touch-Only Interfaces: Applications designed exclusively for touch devices