UNPKG

4 kBTypeScriptView Raw
1import * as MapboxGl from 'mapbox-gl';
2
3export type MapEvent = (
4 map: MapboxGl.Map,
5 // tslint:disable-next-line:no-any
6 evt: React.SyntheticEvent<any>
7) => void;
8
9export interface Events {
10 onStyleLoad?: MapEvent;
11 onResize?: MapEvent;
12 onDblClick?: MapEvent;
13 onClick?: MapEvent;
14 onMouseMove?: MapEvent;
15 onMouseOut?: MapEvent;
16 onMoveStart?: MapEvent;
17 onMove?: MapEvent;
18 onMoveEnd?: MapEvent;
19 onMouseDown?: MapEvent;
20 onMouseUp?: MapEvent;
21 onDragStart?: MapEvent;
22 onDragEnd?: MapEvent;
23 onDrag?: MapEvent;
24 onZoomStart?: MapEvent;
25 onZoom?: MapEvent;
26 onZoomEnd?: MapEvent;
27 onPitch?: MapEvent;
28 onPitchStart?: MapEvent;
29 onPitchEnd?: MapEvent;
30 onWebGlContextLost?: MapEvent;
31 onWebGlContextRestored?: MapEvent;
32 onRemove?: MapEvent;
33 onContextMenu?: MapEvent;
34 onRender?: MapEvent;
35 onError?: MapEvent;
36 onSourceData?: MapEvent;
37 onDataLoading?: MapEvent;
38 onStyleDataLoading?: MapEvent;
39 onStyleImageMissing?: MapEvent;
40 onTouchCancel?: MapEvent;
41 onData?: MapEvent;
42 onSourceDataLoading?: MapEvent;
43 onTouchMove?: MapEvent;
44 onTouchEnd?: MapEvent;
45 onTouchStart?: MapEvent;
46 onStyleData?: MapEvent;
47 onBoxZoomStart?: MapEvent;
48 onBoxZoomEnd?: MapEvent;
49 onBoxZoomCancel?: MapEvent;
50 onRotateStart?: MapEvent;
51 onRotate?: MapEvent;
52 onRotateEnd?: MapEvent;
53}
54
55export type EventMapping = { [T in keyof Events]: string };
56
57export const events: EventMapping = {
58 onResize: 'resize',
59 onDblClick: 'dblclick',
60 onClick: 'click',
61 onMouseMove: 'mousemove',
62 onMouseOut: 'mouseout',
63 onMoveStart: 'movestart',
64 onMove: 'move',
65 onMoveEnd: 'moveend',
66 onMouseUp: 'mouseup',
67 onMouseDown: 'mousedown',
68 onDragStart: 'dragstart',
69 onDrag: 'drag',
70 onDragEnd: 'dragend',
71 onZoomStart: 'zoomstart',
72 onZoom: 'zoom',
73 onZoomEnd: 'zoomend',
74 onPitch: 'pitch',
75 onPitchStart: 'pitchstart',
76 onPitchEnd: 'pitchend',
77 onWebGlContextLost: 'webglcontextlost',
78 onWebGlContextRestored: 'webglcontextrestored',
79 onRemove: 'remove',
80 onContextMenu: 'contextmenu',
81 onRender: 'render',
82 onError: 'error',
83 onSourceData: 'sourcedata',
84 onDataLoading: 'dataloading',
85 onStyleDataLoading: 'styledataloading',
86 onStyleImageMissing: 'styleimagemissing',
87 onTouchCancel: 'touchcancel',
88 onData: 'data',
89 onSourceDataLoading: 'sourcedataloading',
90 onTouchMove: 'touchmove',
91 onTouchEnd: 'touchend',
92 onTouchStart: 'touchstart',
93 onStyleData: 'styledata',
94 onBoxZoomStart: 'boxzoomstart',
95 onBoxZoomEnd: 'boxzoomend',
96 onBoxZoomCancel: 'boxzoomcancel',
97 onRotateStart: 'rotatestart',
98 onRotate: 'rotate',
99 onRotateEnd: 'rotateend'
100};
101
102export type Listeners = {
103 [T in keyof Events]: (evt: React.SyntheticEvent<any>) => void // tslint:disable-line:no-any
104};
105
106export const listenEvents = (
107 partialEvents: EventMapping,
108 props: Partial<Events>,
109 map: MapboxGl.Map
110) =>
111 Object.keys(partialEvents).reduce(
112 (listeners, event) => {
113 const propEvent = props[event];
114
115 if (propEvent) {
116 // tslint:disable-next-line:no-any
117 const listener = (evt: React.SyntheticEvent<any>) => {
118 propEvent(map, evt);
119 };
120
121 map.on(partialEvents[event], listener);
122
123 listeners[event] = listener;
124 }
125
126 return listeners;
127 },
128 // tslint:disable-next-line:no-object-literal-type-assertion
129 {} as Listeners
130 );
131
132export const updateEvents = (
133 listeners: Listeners,
134 currentProps: Partial<Events>,
135 map: MapboxGl.Map
136) => {
137 const toListenOff = Object.keys(events).filter(
138 eventKey =>
139 listeners[eventKey] && typeof currentProps[eventKey] !== 'function'
140 );
141
142 toListenOff.forEach(key => {
143 map.off(events[key], listeners[key]);
144 delete listeners[key];
145 });
146
147 const toListenOn = Object.keys(events)
148 .filter(key => !listeners[key] && typeof currentProps[key] === 'function')
149 .reduce((acc, next) => ((acc[next] = events[next]), acc), {});
150
151 const newListeners = listenEvents(toListenOn, currentProps, map);
152
153 return { ...listeners, ...newListeners };
154};