0
# Events and Types
1
2
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.
3
4
## Capabilities
5
6
### Core Event System
7
8
The event system provides comprehensive coverage of all map interactions with strongly-typed event objects.
9
10
```typescript { .api }
11
/**
12
* Main event callback interface containing all possible map event handlers
13
*/
14
interface MapCallbacks {
15
// View state events
16
onMove?: (event: ViewStateChangeEvent) => void;
17
onMoveStart?: (event: ViewStateChangeEvent) => void;
18
onMoveEnd?: (event: ViewStateChangeEvent) => void;
19
onZoom?: (event: ViewStateChangeEvent) => void;
20
onZoomStart?: (event: ViewStateChangeEvent) => void;
21
onZoomEnd?: (event: ViewStateChangeEvent) => void;
22
onRotate?: (event: ViewStateChangeEvent) => void;
23
onRotateStart?: (event: ViewStateChangeEvent) => void;
24
onRotateEnd?: (event: ViewStateChangeEvent) => void;
25
onPitch?: (event: ViewStateChangeEvent) => void;
26
onPitchStart?: (event: ViewStateChangeEvent) => void;
27
onPitchEnd?: (event: ViewStateChangeEvent) => void;
28
29
// Mouse events
30
onClick?: (event: MapMouseEvent) => void;
31
onDblClick?: (event: MapMouseEvent) => void;
32
onMouseDown?: (event: MapMouseEvent) => void;
33
onMouseUp?: (event: MapMouseEvent) => void;
34
onMouseOver?: (event: MapMouseEvent) => void;
35
onMouseMove?: (event: MapMouseEvent) => void;
36
onMouseOut?: (event: MapMouseEvent) => void;
37
onContextMenu?: (event: MapMouseEvent) => void;
38
onMouseEnter?: (event: MapMouseEvent) => void;
39
onMouseLeave?: (event: MapMouseEvent) => void;
40
41
// Touch events
42
onTouchStart?: (event: MapTouchEvent) => void;
43
onTouchEnd?: (event: MapTouchEvent) => void;
44
onTouchMove?: (event: MapTouchEvent) => void;
45
onTouchCancel?: (event: MapTouchEvent) => void;
46
47
// Wheel events
48
onWheel?: (event: MapWheelEvent) => void;
49
50
// Drag events
51
onDragStart?: (event: ViewStateChangeEvent) => void;
52
onDrag?: (event: ViewStateChangeEvent) => void;
53
onDragEnd?: (event: ViewStateChangeEvent) => void;
54
55
// Box zoom events
56
onBoxZoomStart?: (event: MapBoxZoomEvent) => void;
57
onBoxZoomEnd?: (event: MapBoxZoomEvent) => void;
58
onBoxZoomCancel?: (event: MapBoxZoomEvent) => void;
59
60
// Map lifecycle events
61
onLoad?: (event: MapEvent) => void;
62
onResize?: (event: MapEvent) => void;
63
onRemove?: (event: MapEvent) => void;
64
onError?: (event: ErrorEvent) => void;
65
66
// Data events
67
onData?: (event: MapStyleDataEvent | MapSourceDataEvent) => void;
68
onStyleData?: (event: MapStyleDataEvent) => void;
69
onSourceData?: (event: MapSourceDataEvent) => void;
70
71
// Render events
72
onRender?: (event: MapEvent) => void;
73
onIdle?: (event: MapEvent) => void;
74
}
75
```
76
77
### View State Events
78
79
Events related to camera position and view state changes.
80
81
```typescript { .api }
82
/**
83
* Event fired when the map's view state changes
84
* Contains new view state and interaction information
85
*/
86
interface ViewStateChangeEvent {
87
/** New view state after the change */
88
viewState: ViewState;
89
/** Current interaction state causing the change */
90
interactionState: InteractionState;
91
/** Original DOM event that triggered the change */
92
originalEvent: Event;
93
}
94
95
/**
96
* Current camera view state
97
*/
98
interface ViewState {
99
/** Longitude at map center */
100
longitude: number;
101
/** Latitude at map center */
102
latitude: number;
103
/** Map zoom level */
104
zoom: number;
105
/** Map rotation bearing in degrees counter-clockwise from north */
106
bearing: number;
107
/** Map angle in degrees at which the camera is looking at the ground */
108
pitch: number;
109
/** Dimensions in pixels applied on each side of the viewport for shifting the vanishing point */
110
padding: PaddingOptions;
111
}
112
113
/**
114
* Information about current user interaction
115
*/
116
interface InteractionState {
117
inTransition?: boolean;
118
isDragging?: boolean;
119
isPanning?: boolean;
120
isZooming?: boolean;
121
isRotating?: boolean;
122
}
123
```
124
125
### Mouse Events
126
127
Events fired by mouse interactions with the map.
128
129
```typescript { .api }
130
/**
131
* Mouse event on the map containing position and feature information
132
*/
133
interface MapMouseEvent extends MapEvent {
134
/** Mouse position in screen coordinates */
135
point: Point;
136
/** Geographic coordinates of the event */
137
lngLat: LngLat;
138
/** Features at the event location */
139
features?: MapGeoJSONFeature[];
140
/** Original DOM mouse event */
141
originalEvent: MouseEvent;
142
}
143
144
/**
145
* Base map event interface
146
*/
147
interface MapEvent {
148
/** Event type identifier */
149
type: string;
150
/** Target map instance */
151
target: MapInstance;
152
/** Original DOM event if applicable */
153
originalEvent?: Event;
154
}
155
```
156
157
### Touch Events
158
159
Events fired by touch interactions on mobile devices.
160
161
```typescript { .api }
162
/**
163
* Touch event on the map
164
*/
165
interface MapTouchEvent extends MapEvent {
166
/** Touch position in screen coordinates */
167
point: Point;
168
/** Geographic coordinates of the first touch */
169
lngLat: LngLat;
170
/** Array of all touch points */
171
points: Point[];
172
/** Array of geographic coordinates for all touches */
173
lngLats: LngLat[];
174
/** Features at the first touch location */
175
features?: MapGeoJSONFeature[];
176
/** Original DOM touch event */
177
originalEvent: TouchEvent;
178
}
179
```
180
181
### Wheel Events
182
183
Events fired by mouse wheel interactions.
184
185
```typescript { .api }
186
/**
187
* Mouse wheel event on the map
188
*/
189
interface MapWheelEvent extends MapEvent {
190
/** Wheel position in screen coordinates */
191
point: Point;
192
/** Geographic coordinates of the wheel event */
193
lngLat: LngLat;
194
/** Delta values from the wheel event */
195
deltaY: number;
196
deltaX?: number;
197
deltaZ?: number;
198
/** Original DOM wheel event */
199
originalEvent: WheelEvent;
200
}
201
```
202
203
### Box Zoom Events
204
205
Events fired during box zoom interactions.
206
207
```typescript { .api }
208
/**
209
* Box zoom event containing selection bounds
210
*/
211
interface MapBoxZoomEvent extends MapEvent {
212
/** Selection box bounds in screen coordinates */
213
boxZoomBounds: LngLatBounds;
214
/** Original DOM event */
215
originalEvent: MouseEvent;
216
}
217
```
218
219
### Data Events
220
221
Events fired when map data is loaded or updated.
222
223
```typescript { .api }
224
/**
225
* Event fired when map style data is loaded or updated
226
*/
227
interface MapStyleDataEvent extends MapEvent {
228
/** Type of style data that changed */
229
dataType: 'style' | 'sprite' | 'glyphs';
230
/** Whether this is the initial load */
231
isSourceLoaded?: boolean;
232
/** Source ID if applicable */
233
sourceId?: string;
234
/** Source data type if applicable */
235
sourceDataType?: 'metadata' | 'content' | 'visibility' | 'idle';
236
/** Tile coordinates if applicable */
237
tile?: any;
238
/** Coordinate information */
239
coord?: any;
240
}
241
242
/**
243
* Event fired when map source data is loaded or updated
244
*/
245
interface MapSourceDataEvent extends MapEvent {
246
/** Type of source data that changed */
247
dataType: 'source';
248
/** Whether this is the initial load */
249
isSourceLoaded: boolean;
250
/** Source ID that changed */
251
sourceId: string;
252
/** Source data type */
253
sourceDataType: 'metadata' | 'content' | 'visibility' | 'idle';
254
/** Tile coordinates if applicable */
255
tile?: any;
256
/** Coordinate information */
257
coord?: any;
258
}
259
260
/**
261
* Event fired when a style image is missing
262
*/
263
interface MapStyleImageMissingEvent extends MapEvent {
264
/** ID of the missing image */
265
id: string;
266
}
267
```
268
269
### Error Events
270
271
Events fired when errors occur during map operations.
272
273
```typescript { .api }
274
/**
275
* Error event containing error information
276
*/
277
interface ErrorEvent extends MapEvent {
278
/** Error object with details */
279
error: Error;
280
/** Error message */
281
message?: string;
282
/** Error source or context */
283
source?: string;
284
}
285
```
286
287
### Component-Specific Events
288
289
Events specific to individual map components.
290
291
```typescript { .api }
292
/**
293
* Marker-related events
294
*/
295
interface MarkerEvent {
296
/** Event type */
297
type: string;
298
/** Target marker instance */
299
target: MarkerInstance;
300
/** Original DOM event */
301
originalEvent: Event;
302
}
303
304
/**
305
* Marker drag events with position information
306
*/
307
interface MarkerDragEvent extends MarkerEvent {
308
/** New marker position */
309
lngLat: LngLat;
310
}
311
312
/**
313
* Popup-related events
314
*/
315
interface PopupEvent {
316
/** Event type */
317
type: string;
318
/** Target popup instance */
319
target: PopupInstance;
320
/** Original DOM event if applicable */
321
originalEvent?: Event;
322
}
323
324
/**
325
* Geolocation control events
326
*/
327
interface GeolocateEvent {
328
/** Event type */
329
type: string;
330
/** Target geolocate control */
331
target: GeolocateControlInstance;
332
}
333
334
/**
335
* Successful geolocation result
336
*/
337
interface GeolocateResultEvent extends GeolocateEvent {
338
/** Geolocation coordinates */
339
coords: GeolocationCoordinates;
340
/** Timestamp of the geolocation */
341
timestamp: number;
342
}
343
344
/**
345
* Geolocation error event
346
*/
347
interface GeolocateErrorEvent extends GeolocateEvent {
348
/** Geolocation error */
349
error: GeolocationPositionError;
350
}
351
```
352
353
### Geometric Types
354
355
Core geometric types used throughout the event system.
356
357
```typescript { .api }
358
/**
359
* 2D point in screen coordinates
360
*/
361
interface Point {
362
x: number;
363
y: number;
364
}
365
366
/**
367
* Point-like values that can be converted to Point
368
*/
369
type PointLike = Point | [number, number];
370
371
/**
372
* Geographic coordinates
373
*/
374
interface LngLat {
375
lng: number;
376
lat: number;
377
}
378
379
/**
380
* Longitude/latitude-like values that can be converted to LngLat
381
*/
382
type LngLatLike =
383
| LngLat
384
| [number, number]
385
| { lon: number; lat: number }
386
| { longitude: number; latitude: number };
387
388
/**
389
* Geographic bounds rectangle
390
*/
391
interface LngLatBounds {
392
_sw: LngLat;
393
_ne: LngLat;
394
395
/** Get southwest corner */
396
getSouthWest(): LngLat;
397
/** Get northeast corner */
398
getNorthEast(): LngLat;
399
/** Get northwest corner */
400
getNorthWest(): LngLat;
401
/** Get southeast corner */
402
getSouthEast(): LngLat;
403
/** Get center point */
404
getCenter(): LngLat;
405
/** Check if bounds contain a point */
406
contains(lnglat: LngLatLike): boolean;
407
/** Extend bounds to include a point */
408
extend(lnglat: LngLatLike): LngLatBounds;
409
}
410
411
/**
412
* Bounds-like values that can be converted to LngLatBounds
413
*/
414
type LngLatBoundsLike =
415
| LngLatBounds
416
| [LngLatLike, LngLatLike]
417
| [number, number, number, number];
418
419
/**
420
* Padding options for map viewport
421
*/
422
interface PaddingOptions {
423
top?: number;
424
bottom?: number;
425
left?: number;
426
right?: number;
427
}
428
429
/**
430
* GeoJSON feature with additional map-specific properties
431
*/
432
interface MapGeoJSONFeature {
433
type: 'Feature';
434
id?: string | number;
435
properties: { [key: string]: any };
436
geometry: any;
437
layer?: { id: string; type: string; source: string; 'source-layer'?: string };
438
source?: string;
439
sourceLayer?: string;
440
state?: { [key: string]: any };
441
}
442
```
443
444
### Library Integration Types
445
446
Types for integrating with underlying map libraries.
447
448
```typescript { .api }
449
/**
450
* Map library interface for Mapbox/MapLibre compatibility
451
*/
452
interface MapLib {
453
Map: any;
454
Marker: any;
455
Popup: any;
456
AttributionControl: any;
457
FullscreenControl: any;
458
GeolocateControl: any;
459
NavigationControl: any;
460
ScaleControl: any;
461
TerrainControl?: any; // MapLibre only
462
LogoControl?: any; // MapLibre only
463
version: string;
464
}
465
466
/**
467
* Map instance type combining library-specific methods
468
*/
469
interface MapInstance {
470
// Core map methods
471
getContainer(): HTMLElement;
472
getCanvasContainer(): HTMLElement;
473
getCanvas(): HTMLCanvasElement;
474
475
// View state methods
476
getCenter(): LngLat;
477
setCenter(center: LngLatLike): MapInstance;
478
getZoom(): number;
479
setZoom(zoom: number): MapInstance;
480
getBearing(): number;
481
setBearing(bearing: number): MapInstance;
482
getPitch(): number;
483
setPitch(pitch: number): MapInstance;
484
getPadding(): PaddingOptions;
485
setPadding(padding: PaddingOptions): MapInstance;
486
487
// Bounds methods
488
getBounds(): LngLatBounds;
489
setMaxBounds(bounds?: LngLatBoundsLike): MapInstance;
490
getMaxBounds(): LngLatBounds | null;
491
fitBounds(bounds: LngLatBoundsLike, options?: any): MapInstance;
492
fitScreenCoordinates(p0: PointLike, p1: PointLike, bearing: number, options?: any): MapInstance;
493
494
// Conversion methods
495
project(lnglat: LngLatLike): Point;
496
unproject(point: PointLike): LngLat;
497
498
// Style methods
499
getStyle(): any;
500
setStyle(style: any): MapInstance;
501
502
// Source methods
503
addSource(id: string, source: any): MapInstance;
504
removeSource(id: string): MapInstance;
505
getSource(id: string): any;
506
507
// Layer methods
508
addLayer(layer: any, beforeId?: string): MapInstance;
509
removeLayer(id: string): MapInstance;
510
getLayer(id: string): any;
511
moveLayer(id: string, beforeId?: string): MapInstance;
512
513
// Feature methods
514
queryRenderedFeatures(pointOrBox?: PointLike | [PointLike, PointLike], options?: any): MapGeoJSONFeature[];
515
querySourceFeatures(sourceId: string, options?: any): MapGeoJSONFeature[];
516
517
// Control methods
518
addControl(control: IControl, position?: ControlPosition): MapInstance;
519
removeControl(control: IControl): MapInstance;
520
521
// Event methods
522
on(type: string, listener: Function): MapInstance;
523
off(type: string, listener: Function): MapInstance;
524
once(type: string, listener: Function): MapInstance;
525
fire(type: string, properties?: any): MapInstance;
526
527
// Lifecycle methods
528
remove(): void;
529
resize(): MapInstance;
530
redraw(): MapInstance;
531
}
532
533
/**
534
* Control interface for custom map controls
535
*/
536
interface IControl {
537
onAdd(map: MapInstance): HTMLElement;
538
onRemove(map: MapInstance): void;
539
getDefaultPosition?(): ControlPosition;
540
}
541
542
/**
543
* Control position options
544
*/
545
type ControlPosition =
546
| 'top-left'
547
| 'top-right'
548
| 'bottom-left'
549
| 'bottom-right';
550
551
/**
552
* Component instance types
553
*/
554
interface MarkerInstance {
555
getLngLat(): LngLat;
556
setLngLat(lnglat: LngLatLike): MarkerInstance;
557
getOffset(): Point;
558
setOffset(offset: PointLike): MarkerInstance;
559
addTo(map: MapInstance): MarkerInstance;
560
remove(): MarkerInstance;
561
togglePopup(): MarkerInstance;
562
getPopup(): PopupInstance;
563
setPopup(popup?: PopupInstance): MarkerInstance;
564
bindPopup(popup: PopupInstance): MarkerInstance;
565
unbindPopup(): MarkerInstance;
566
on(type: string, listener: Function): MarkerInstance;
567
off(type: string, listener: Function): MarkerInstance;
568
}
569
570
interface PopupInstance {
571
addTo(map: MapInstance): PopupInstance;
572
isOpen(): boolean;
573
remove(): PopupInstance;
574
getLngLat(): LngLat;
575
setLngLat(lnglat: LngLatLike): PopupInstance;
576
setHTML(html: string): PopupInstance;
577
setText(text: string): PopupInstance;
578
setDOMContent(htmlNode: Node): PopupInstance;
579
getElement(): HTMLElement;
580
on(type: string, listener: Function): PopupInstance;
581
off(type: string, listener: Function): PopupInstance;
582
}
583
584
interface GeolocateControlInstance extends IControl {
585
trigger(): boolean;
586
}
587
```
588
589
## Usage Examples
590
591
**Handling View State Changes:**
592
```typescript
593
import React from 'react';
594
import Map, { ViewStateChangeEvent } from 'react-map-gl/mapbox';
595
596
function ViewStateExample() {
597
const handleMove = (event: ViewStateChangeEvent) => {
598
console.log('New position:', {
599
longitude: event.viewState.longitude,
600
latitude: event.viewState.latitude,
601
zoom: event.viewState.zoom
602
});
603
604
if (event.interactionState.isDragging) {
605
console.log('User is dragging the map');
606
}
607
};
608
609
return (
610
<Map
611
initialViewState={{longitude: -100, latitude: 40, zoom: 4}}
612
onMove={handleMove}
613
onMoveStart={() => console.log('Move started')}
614
onMoveEnd={() => console.log('Move ended')}
615
/>
616
);
617
}
618
```
619
620
**Handling Click Events with Feature Queries:**
621
```typescript
622
import React from 'react';
623
import Map, { MapMouseEvent } from 'react-map-gl/mapbox';
624
625
function ClickExample() {
626
const handleClick = (event: MapMouseEvent) => {
627
console.log('Clicked at:', event.lngLat);
628
console.log('Screen position:', event.point);
629
630
if (event.features && event.features.length > 0) {
631
console.log('Clicked features:', event.features);
632
console.log('First feature properties:', event.features[0].properties);
633
}
634
};
635
636
return (
637
<Map
638
initialViewState={{longitude: -100, latitude: 40, zoom: 4}}
639
onClick={handleClick}
640
interactiveLayerIds={['data-layer']} // Only fire click events for this layer
641
/>
642
);
643
}
644
```
645
646
**Error Handling:**
647
```typescript
648
import React from 'react';
649
import Map, { ErrorEvent } from 'react-map-gl/mapbox';
650
651
function ErrorHandlingExample() {
652
const handleError = (event: ErrorEvent) => {
653
console.error('Map error:', event.error.message);
654
655
// Handle specific error types
656
if (event.error.message.includes('access token')) {
657
console.error('Invalid access token provided');
658
} else if (event.error.message.includes('style')) {
659
console.error('Style loading error');
660
}
661
};
662
663
return (
664
<Map
665
initialViewState={{longitude: -100, latitude: 40, zoom: 4}}
666
mapStyle="mapbox://styles/mapbox/streets-v12"
667
mapboxAccessToken="YOUR_TOKEN"
668
onError={handleError}
669
/>
670
);
671
}
672
```