CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-map-gl

React components for MapLibre GL JS and Mapbox GL JS that provide a React-friendly API wrapper for interactive mapping applications

Pending
Overview
Eval results
Files

events-types.mddocs/

Events and Types

Comprehensive event system and type definitions for react-map-gl, providing strongly-typed event handling for all map interactions, view state changes, and user interactions.

Capabilities

Core Event System

The event system provides comprehensive coverage of all map interactions with strongly-typed event objects.

/**
 * Main event callback interface containing all possible map event handlers
 */
interface MapCallbacks {
  // View state events
  onMove?: (event: ViewStateChangeEvent) => void;
  onMoveStart?: (event: ViewStateChangeEvent) => void;
  onMoveEnd?: (event: ViewStateChangeEvent) => void;
  onZoom?: (event: ViewStateChangeEvent) => void;
  onZoomStart?: (event: ViewStateChangeEvent) => void;
  onZoomEnd?: (event: ViewStateChangeEvent) => void;
  onRotate?: (event: ViewStateChangeEvent) => void;
  onRotateStart?: (event: ViewStateChangeEvent) => void;
  onRotateEnd?: (event: ViewStateChangeEvent) => void;
  onPitch?: (event: ViewStateChangeEvent) => void;
  onPitchStart?: (event: ViewStateChangeEvent) => void;
  onPitchEnd?: (event: ViewStateChangeEvent) => void;

  // Mouse events
  onClick?: (event: MapMouseEvent) => void;
  onDblClick?: (event: MapMouseEvent) => void;
  onMouseDown?: (event: MapMouseEvent) => void;
  onMouseUp?: (event: MapMouseEvent) => void;
  onMouseOver?: (event: MapMouseEvent) => void;
  onMouseMove?: (event: MapMouseEvent) => void;
  onMouseOut?: (event: MapMouseEvent) => void;
  onContextMenu?: (event: MapMouseEvent) => void;
  onMouseEnter?: (event: MapMouseEvent) => void;
  onMouseLeave?: (event: MapMouseEvent) => void;

  // Touch events
  onTouchStart?: (event: MapTouchEvent) => void;
  onTouchEnd?: (event: MapTouchEvent) => void;
  onTouchMove?: (event: MapTouchEvent) => void;
  onTouchCancel?: (event: MapTouchEvent) => void;

  // Wheel events
  onWheel?: (event: MapWheelEvent) => void;

  // Drag events
  onDragStart?: (event: ViewStateChangeEvent) => void;
  onDrag?: (event: ViewStateChangeEvent) => void;
  onDragEnd?: (event: ViewStateChangeEvent) => void;

  // Box zoom events
  onBoxZoomStart?: (event: MapBoxZoomEvent) => void;
  onBoxZoomEnd?: (event: MapBoxZoomEvent) => void;
  onBoxZoomCancel?: (event: MapBoxZoomEvent) => void;

  // Map lifecycle events
  onLoad?: (event: MapEvent) => void;
  onResize?: (event: MapEvent) => void;
  onRemove?: (event: MapEvent) => void;
  onError?: (event: ErrorEvent) => void;

  // Data events
  onData?: (event: MapStyleDataEvent | MapSourceDataEvent) => void;
  onStyleData?: (event: MapStyleDataEvent) => void;
  onSourceData?: (event: MapSourceDataEvent) => void;

  // Render events
  onRender?: (event: MapEvent) => void;
  onIdle?: (event: MapEvent) => void;
}

View State Events

Events related to camera position and view state changes.

/**
 * Event fired when the map's view state changes
 * Contains new view state and interaction information
 */
interface ViewStateChangeEvent {
  /** New view state after the change */
  viewState: ViewState;
  /** Current interaction state causing the change */
  interactionState: InteractionState;
  /** Original DOM event that triggered the change */
  originalEvent: Event;
}

/**
 * Current camera view state
 */
interface ViewState {
  /** Longitude at map center */
  longitude: number;
  /** Latitude at map center */
  latitude: number;
  /** Map zoom level */
  zoom: number;
  /** Map rotation bearing in degrees counter-clockwise from north */
  bearing: number;
  /** Map angle in degrees at which the camera is looking at the ground */
  pitch: number;
  /** Dimensions in pixels applied on each side of the viewport for shifting the vanishing point */
  padding: PaddingOptions;
}

/**
 * Information about current user interaction
 */
interface InteractionState {
  inTransition?: boolean;
  isDragging?: boolean;
  isPanning?: boolean;
  isZooming?: boolean;
  isRotating?: boolean;
}

Mouse Events

Events fired by mouse interactions with the map.

/**
 * Mouse event on the map containing position and feature information
 */
interface MapMouseEvent extends MapEvent {
  /** Mouse position in screen coordinates */
  point: Point;
  /** Geographic coordinates of the event */
  lngLat: LngLat;
  /** Features at the event location */
  features?: MapGeoJSONFeature[];
  /** Original DOM mouse event */
  originalEvent: MouseEvent;
}

/**
 * Base map event interface
 */
interface MapEvent {
  /** Event type identifier */
  type: string;
  /** Target map instance */
  target: MapInstance;
  /** Original DOM event if applicable */
  originalEvent?: Event;
}

Touch Events

Events fired by touch interactions on mobile devices.

/**
 * Touch event on the map
 */
interface MapTouchEvent extends MapEvent {
  /** Touch position in screen coordinates */
  point: Point;
  /** Geographic coordinates of the first touch */
  lngLat: LngLat;
  /** Array of all touch points */
  points: Point[];
  /** Array of geographic coordinates for all touches */
  lngLats: LngLat[];
  /** Features at the first touch location */
  features?: MapGeoJSONFeature[];
  /** Original DOM touch event */
  originalEvent: TouchEvent;
}

Wheel Events

Events fired by mouse wheel interactions.

/**
 * Mouse wheel event on the map
 */
interface MapWheelEvent extends MapEvent {
  /** Wheel position in screen coordinates */
  point: Point;
  /** Geographic coordinates of the wheel event */
  lngLat: LngLat;
  /** Delta values from the wheel event */
  deltaY: number;
  deltaX?: number;
  deltaZ?: number;
  /** Original DOM wheel event */
  originalEvent: WheelEvent;
}

Box Zoom Events

Events fired during box zoom interactions.

/**
 * Box zoom event containing selection bounds
 */
interface MapBoxZoomEvent extends MapEvent {
  /** Selection box bounds in screen coordinates */
  boxZoomBounds: LngLatBounds;
  /** Original DOM event */
  originalEvent: MouseEvent;
}

Data Events

Events fired when map data is loaded or updated.

/**
 * Event fired when map style data is loaded or updated
 */
interface MapStyleDataEvent extends MapEvent {
  /** Type of style data that changed */
  dataType: 'style' | 'sprite' | 'glyphs';
  /** Whether this is the initial load */
  isSourceLoaded?: boolean;
  /** Source ID if applicable */
  sourceId?: string;
  /** Source data type if applicable */
  sourceDataType?: 'metadata' | 'content' | 'visibility' | 'idle';
  /** Tile coordinates if applicable */
  tile?: any;
  /** Coordinate information */
  coord?: any;
}

/**
 * Event fired when map source data is loaded or updated
 */
interface MapSourceDataEvent extends MapEvent {
  /** Type of source data that changed */
  dataType: 'source';
  /** Whether this is the initial load */
  isSourceLoaded: boolean;
  /** Source ID that changed */
  sourceId: string;
  /** Source data type */
  sourceDataType: 'metadata' | 'content' | 'visibility' | 'idle';
  /** Tile coordinates if applicable */
  tile?: any;
  /** Coordinate information */
  coord?: any;
}

/**
 * Event fired when a style image is missing
 */
interface MapStyleImageMissingEvent extends MapEvent {
  /** ID of the missing image */
  id: string;
}

Error Events

Events fired when errors occur during map operations.

/**
 * Error event containing error information
 */
interface ErrorEvent extends MapEvent {
  /** Error object with details */
  error: Error;
  /** Error message */
  message?: string;
  /** Error source or context */
  source?: string;
}

Component-Specific Events

Events specific to individual map components.

/**
 * Marker-related events
 */
interface MarkerEvent {
  /** Event type */
  type: string;
  /** Target marker instance */
  target: MarkerInstance;
  /** Original DOM event */
  originalEvent: Event;
}

/**
 * Marker drag events with position information
 */
interface MarkerDragEvent extends MarkerEvent {
  /** New marker position */
  lngLat: LngLat;
}

/**
 * Popup-related events
 */
interface PopupEvent {
  /** Event type */
  type: string;
  /** Target popup instance */
  target: PopupInstance;
  /** Original DOM event if applicable */
  originalEvent?: Event;
}

/**
 * Geolocation control events
 */
interface GeolocateEvent {
  /** Event type */
  type: string;
  /** Target geolocate control */
  target: GeolocateControlInstance;
}

/**
 * Successful geolocation result
 */
interface GeolocateResultEvent extends GeolocateEvent {
  /** Geolocation coordinates */
  coords: GeolocationCoordinates;
  /** Timestamp of the geolocation */
  timestamp: number;
}

/**
 * Geolocation error event
 */
interface GeolocateErrorEvent extends GeolocateEvent {
  /** Geolocation error */
  error: GeolocationPositionError;
}

Geometric Types

Core geometric types used throughout the event system.

/**
 * 2D point in screen coordinates
 */
interface Point {
  x: number;
  y: number;
}

/**
 * Point-like values that can be converted to Point
 */
type PointLike = Point | [number, number];

/**
 * Geographic coordinates
 */
interface LngLat {
  lng: number;
  lat: number;
}

/**
 * Longitude/latitude-like values that can be converted to LngLat
 */
type LngLatLike = 
  | LngLat 
  | [number, number] 
  | { lon: number; lat: number }
  | { longitude: number; latitude: number };

/**
 * Geographic bounds rectangle
 */
interface LngLatBounds {
  _sw: LngLat;
  _ne: LngLat;
  
  /** Get southwest corner */
  getSouthWest(): LngLat;
  /** Get northeast corner */
  getNorthEast(): LngLat;
  /** Get northwest corner */
  getNorthWest(): LngLat;
  /** Get southeast corner */
  getSouthEast(): LngLat;
  /** Get center point */
  getCenter(): LngLat;
  /** Check if bounds contain a point */
  contains(lnglat: LngLatLike): boolean;
  /** Extend bounds to include a point */
  extend(lnglat: LngLatLike): LngLatBounds;
}

/**
 * Bounds-like values that can be converted to LngLatBounds
 */
type LngLatBoundsLike = 
  | LngLatBounds 
  | [LngLatLike, LngLatLike] 
  | [number, number, number, number];

/**
 * Padding options for map viewport
 */
interface PaddingOptions {
  top?: number;
  bottom?: number;
  left?: number;
  right?: number;
}

/**
 * GeoJSON feature with additional map-specific properties
 */
interface MapGeoJSONFeature {
  type: 'Feature';
  id?: string | number;
  properties: { [key: string]: any };
  geometry: any;
  layer?: { id: string; type: string; source: string; 'source-layer'?: string };
  source?: string;
  sourceLayer?: string;
  state?: { [key: string]: any };
}

Library Integration Types

Types for integrating with underlying map libraries.

/**
 * Map library interface for Mapbox/MapLibre compatibility
 */
interface MapLib {
  Map: any;
  Marker: any;
  Popup: any;
  AttributionControl: any;
  FullscreenControl: any;
  GeolocateControl: any;
  NavigationControl: any;
  ScaleControl: any;
  TerrainControl?: any; // MapLibre only
  LogoControl?: any; // MapLibre only
  version: string;
}

/**
 * Map instance type combining library-specific methods
 */
interface MapInstance {
  // Core map methods
  getContainer(): HTMLElement;
  getCanvasContainer(): HTMLElement;
  getCanvas(): HTMLCanvasElement;
  
  // View state methods
  getCenter(): LngLat;
  setCenter(center: LngLatLike): MapInstance;
  getZoom(): number;
  setZoom(zoom: number): MapInstance;
  getBearing(): number;
  setBearing(bearing: number): MapInstance;
  getPitch(): number;
  setPitch(pitch: number): MapInstance;
  getPadding(): PaddingOptions;
  setPadding(padding: PaddingOptions): MapInstance;
  
  // Bounds methods
  getBounds(): LngLatBounds;
  setMaxBounds(bounds?: LngLatBoundsLike): MapInstance;
  getMaxBounds(): LngLatBounds | null;
  fitBounds(bounds: LngLatBoundsLike, options?: any): MapInstance;
  fitScreenCoordinates(p0: PointLike, p1: PointLike, bearing: number, options?: any): MapInstance;
  
  // Conversion methods
  project(lnglat: LngLatLike): Point;
  unproject(point: PointLike): LngLat;
  
  // Style methods
  getStyle(): any;
  setStyle(style: any): MapInstance;
  
  // Source methods
  addSource(id: string, source: any): MapInstance;
  removeSource(id: string): MapInstance;
  getSource(id: string): any;
  
  // Layer methods
  addLayer(layer: any, beforeId?: string): MapInstance;
  removeLayer(id: string): MapInstance;
  getLayer(id: string): any;
  moveLayer(id: string, beforeId?: string): MapInstance;
  
  // Feature methods
  queryRenderedFeatures(pointOrBox?: PointLike | [PointLike, PointLike], options?: any): MapGeoJSONFeature[];
  querySourceFeatures(sourceId: string, options?: any): MapGeoJSONFeature[];
  
  // Control methods
  addControl(control: IControl, position?: ControlPosition): MapInstance;
  removeControl(control: IControl): MapInstance;
  
  // Event methods
  on(type: string, listener: Function): MapInstance;
  off(type: string, listener: Function): MapInstance;
  once(type: string, listener: Function): MapInstance;
  fire(type: string, properties?: any): MapInstance;
  
  // Lifecycle methods
  remove(): void;
  resize(): MapInstance;
  redraw(): MapInstance;
}

/**
 * Control interface for custom map controls
 */
interface IControl {
  onAdd(map: MapInstance): HTMLElement;
  onRemove(map: MapInstance): void;
  getDefaultPosition?(): ControlPosition;
}

/**
 * Control position options
 */
type ControlPosition = 
  | 'top-left' 
  | 'top-right' 
  | 'bottom-left' 
  | 'bottom-right';

/**
 * Component instance types
 */
interface MarkerInstance {
  getLngLat(): LngLat;
  setLngLat(lnglat: LngLatLike): MarkerInstance;
  getOffset(): Point;
  setOffset(offset: PointLike): MarkerInstance;
  addTo(map: MapInstance): MarkerInstance;
  remove(): MarkerInstance;
  togglePopup(): MarkerInstance;
  getPopup(): PopupInstance;
  setPopup(popup?: PopupInstance): MarkerInstance;
  bindPopup(popup: PopupInstance): MarkerInstance;
  unbindPopup(): MarkerInstance;
  on(type: string, listener: Function): MarkerInstance;
  off(type: string, listener: Function): MarkerInstance;
}

interface PopupInstance {
  addTo(map: MapInstance): PopupInstance;
  isOpen(): boolean;
  remove(): PopupInstance;
  getLngLat(): LngLat;
  setLngLat(lnglat: LngLatLike): PopupInstance;
  setHTML(html: string): PopupInstance;
  setText(text: string): PopupInstance;
  setDOMContent(htmlNode: Node): PopupInstance;
  getElement(): HTMLElement;
  on(type: string, listener: Function): PopupInstance;
  off(type: string, listener: Function): PopupInstance;
}

interface GeolocateControlInstance extends IControl {
  trigger(): boolean;
}

Usage Examples

Handling View State Changes:

import React from 'react';
import Map, { ViewStateChangeEvent } from 'react-map-gl/mapbox';

function ViewStateExample() {
  const handleMove = (event: ViewStateChangeEvent) => {
    console.log('New position:', {
      longitude: event.viewState.longitude,
      latitude: event.viewState.latitude,
      zoom: event.viewState.zoom
    });
    
    if (event.interactionState.isDragging) {
      console.log('User is dragging the map');
    }
  };

  return (
    <Map
      initialViewState={{longitude: -100, latitude: 40, zoom: 4}}
      onMove={handleMove}
      onMoveStart={() => console.log('Move started')}
      onMoveEnd={() => console.log('Move ended')}
    />
  );
}

Handling Click Events with Feature Queries:

import React from 'react';
import Map, { MapMouseEvent } from 'react-map-gl/mapbox';

function ClickExample() {
  const handleClick = (event: MapMouseEvent) => {
    console.log('Clicked at:', event.lngLat);
    console.log('Screen position:', event.point);
    
    if (event.features && event.features.length > 0) {
      console.log('Clicked features:', event.features);
      console.log('First feature properties:', event.features[0].properties);
    }
  };

  return (
    <Map
      initialViewState={{longitude: -100, latitude: 40, zoom: 4}}
      onClick={handleClick}
      interactiveLayerIds={['data-layer']} // Only fire click events for this layer
    />
  );
}

Error Handling:

import React from 'react';
import Map, { ErrorEvent } from 'react-map-gl/mapbox';

function ErrorHandlingExample() {
  const handleError = (event: ErrorEvent) => {
    console.error('Map error:', event.error.message);
    
    // Handle specific error types
    if (event.error.message.includes('access token')) {
      console.error('Invalid access token provided');
    } else if (event.error.message.includes('style')) {
      console.error('Style loading error');
    }
  };

  return (
    <Map
      initialViewState={{longitude: -100, latitude: 40, zoom: 4}}
      mapStyle="mapbox://styles/mapbox/streets-v12"
      mapboxAccessToken="YOUR_TOKEN"
      onError={handleError}
    />
  );
}

Install with Tessl CLI

npx tessl i tessl/npm-react-map-gl

docs

events-types.md

index.md

mapbox-legacy.md

mapbox-maplibre.md

tile.json