react-bkoi-gl 1.0.6 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/README.md +163 -18
  2. package/dist/components/attribution-control.d.ts +4 -6
  3. package/dist/components/attribution-control.js +6 -5
  4. package/dist/components/attribution-control.js.map +1 -1
  5. package/dist/components/fullscreen-control.d.ts +4 -6
  6. package/dist/components/fullscreen-control.js +4 -4
  7. package/dist/components/fullscreen-control.js.map +1 -1
  8. package/dist/components/geolocate-control.d.ts +10 -26
  9. package/dist/components/geolocate-control.js +11 -11
  10. package/dist/components/geolocate-control.js.map +1 -1
  11. package/dist/components/layer.d.ts +7 -6
  12. package/dist/components/layer.js +8 -9
  13. package/dist/components/layer.js.map +1 -1
  14. package/dist/components/logo-control.d.ts +9 -0
  15. package/dist/components/logo-control.js +28 -0
  16. package/dist/components/logo-control.js.map +1 -0
  17. package/dist/components/map.d.ts +20 -16
  18. package/dist/components/map.js +38 -32
  19. package/dist/components/map.js.map +1 -1
  20. package/dist/components/marker.d.ts +10 -33
  21. package/dist/components/marker.js +22 -15
  22. package/dist/components/marker.js.map +1 -1
  23. package/dist/components/navigation-control.d.ts +4 -6
  24. package/dist/components/navigation-control.js +4 -4
  25. package/dist/components/navigation-control.js.map +1 -1
  26. package/dist/components/popup.d.ts +7 -25
  27. package/dist/components/popup.js +17 -28
  28. package/dist/components/popup.js.map +1 -1
  29. package/dist/components/scale-control.d.ts +4 -6
  30. package/dist/components/scale-control.js +4 -4
  31. package/dist/components/scale-control.js.map +1 -1
  32. package/dist/components/source.d.ts +3 -4
  33. package/dist/components/source.js +20 -22
  34. package/dist/components/source.js.map +1 -1
  35. package/dist/components/terrain-control.d.ts +10 -0
  36. package/dist/components/terrain-control.js +19 -0
  37. package/dist/components/terrain-control.js.map +1 -0
  38. package/dist/components/use-control.d.ts +6 -6
  39. package/dist/components/use-control.js +4 -5
  40. package/dist/components/use-control.js.map +1 -1
  41. package/dist/components/use-map.d.ts +8 -9
  42. package/dist/components/use-map.js +5 -5
  43. package/dist/components/use-map.js.map +1 -1
  44. package/dist/exports-maplibre-gl.d.ts +33 -0
  45. package/dist/exports-maplibre-gl.js +21 -0
  46. package/dist/exports-maplibre-gl.js.map +1 -0
  47. package/dist/index.cjs +590 -681
  48. package/dist/index.d.ts +2 -2
  49. package/dist/index.js +2 -2
  50. package/dist/index.js.map +1 -1
  51. package/dist/{mapbox → maplibre}/create-ref.d.ts +6 -6
  52. package/dist/maplibre/create-ref.js +30 -0
  53. package/dist/maplibre/create-ref.js.map +1 -0
  54. package/dist/maplibre/maplibre.d.ts +81 -0
  55. package/dist/maplibre/maplibre.js +387 -0
  56. package/dist/maplibre/maplibre.js.map +1 -0
  57. package/dist/styles/index.d.ts +4 -0
  58. package/dist/styles/react-bkoi-gl.css +1 -1
  59. package/dist/styles.d.js +2 -0
  60. package/dist/styles.d.js.map +1 -0
  61. package/dist/tsconfig.build.tsbuildinfo +1 -0
  62. package/dist/types/common.d.ts +2 -60
  63. package/dist/types/common.js.map +1 -1
  64. package/dist/types/events.d.ts +64 -23
  65. package/dist/types/events.js.map +1 -1
  66. package/dist/types/internal.d.ts +14 -0
  67. package/dist/types/internal.js +2 -0
  68. package/dist/types/internal.js.map +1 -0
  69. package/dist/types/lib.d.ts +16 -200
  70. package/dist/types/lib.js.map +1 -1
  71. package/dist/types/style-spec.d.ts +1 -0
  72. package/dist/types/style-spec.js +2 -0
  73. package/dist/types/style-spec.js.map +1 -0
  74. package/dist/utils/apply-react-style.d.ts +1 -1
  75. package/dist/utils/apply-react-style.js.map +1 -1
  76. package/dist/utils/compare-class-names.d.ts +2 -0
  77. package/dist/utils/compare-class-names.js +23 -0
  78. package/dist/utils/compare-class-names.js.map +1 -0
  79. package/dist/utils/deep-equal.d.ts +1 -1
  80. package/dist/utils/deep-equal.js +1 -1
  81. package/dist/utils/deep-equal.js.map +1 -1
  82. package/dist/utils/set-globals.d.ts +6 -8
  83. package/dist/utils/set-globals.js +22 -10
  84. package/dist/utils/set-globals.js.map +1 -1
  85. package/dist/utils/style-utils.d.ts +3 -2
  86. package/dist/utils/style-utils.js +4 -4
  87. package/dist/utils/style-utils.js.map +1 -1
  88. package/dist/utils/transform.d.ts +11 -19
  89. package/dist/utils/transform.js +13 -36
  90. package/dist/utils/transform.js.map +1 -1
  91. package/dist/utils/use-isomorphic-layout-effect.d.ts +1 -1
  92. package/dist/utils/use-isomorphic-layout-effect.js +2 -2
  93. package/dist/utils/use-isomorphic-layout-effect.js.map +1 -1
  94. package/package.json +42 -26
  95. package/src/components/attribution-control.ts +40 -16
  96. package/src/components/fullscreen-control.ts +40 -0
  97. package/src/components/geolocate-control.ts +45 -39
  98. package/src/components/layer.ts +37 -29
  99. package/src/components/logo-control.ts +44 -0
  100. package/src/components/map.tsx +86 -75
  101. package/src/components/marker.ts +141 -123
  102. package/src/components/navigation-control.ts +11 -12
  103. package/src/components/popup.ts +94 -97
  104. package/src/components/scale-control.ts +12 -14
  105. package/src/components/source.ts +58 -57
  106. package/src/components/terrain-control.ts +29 -0
  107. package/src/components/use-control.ts +21 -17
  108. package/src/components/use-map.tsx +26 -24
  109. package/src/exports-maplibre-gl.ts +37 -0
  110. package/src/index.ts +3 -2
  111. package/src/maplibre/create-ref.ts +70 -0
  112. package/src/maplibre/maplibre.ts +624 -0
  113. package/src/styles.d.ts +4 -0
  114. package/src/types/common.ts +12 -72
  115. package/src/types/events.ts +102 -42
  116. package/src/types/internal.ts +26 -0
  117. package/src/types/lib.ts +65 -260
  118. package/src/types/style-spec.ts +34 -0
  119. package/src/utils/apply-react-style.ts +7 -3
  120. package/src/utils/compare-class-names.ts +29 -0
  121. package/src/utils/deep-equal.ts +2 -2
  122. package/src/utils/set-globals.ts +22 -28
  123. package/src/utils/style-utils.ts +18 -9
  124. package/src/utils/transform.ts +32 -60
  125. package/src/utils/use-isomorphic-layout-effect.ts +3 -2
  126. package/bkoi-gl/package.json +0 -6
  127. package/dist/exports-bkoi-gl.cjs +0 -1512
  128. package/dist/exports-bkoi-gl.d.ts +0 -89
  129. package/dist/exports-bkoi-gl.js +0 -36
  130. package/dist/exports-bkoi-gl.js.map +0 -1
  131. package/dist/exports-mapbox.d.ts +0 -139
  132. package/dist/exports-mapbox.js +0 -36
  133. package/dist/exports-mapbox.js.map +0 -1
  134. package/dist/mapbox/create-ref.js +0 -64
  135. package/dist/mapbox/create-ref.js.map +0 -1
  136. package/dist/mapbox/mapbox.d.ts +0 -81
  137. package/dist/mapbox/mapbox.js +0 -476
  138. package/dist/mapbox/mapbox.js.map +0 -1
  139. package/dist/types/events-bkoi-gl.d.ts +0 -49
  140. package/dist/types/events-bkoi-gl.js +0 -2
  141. package/dist/types/events-bkoi-gl.js.map +0 -1
  142. package/dist/types/events-mapbox.d.ts +0 -49
  143. package/dist/types/events-mapbox.js +0 -2
  144. package/dist/types/events-mapbox.js.map +0 -1
  145. package/dist/types/index.d.ts +0 -70
  146. package/dist/types/index.js +0 -5
  147. package/dist/types/index.js.map +0 -1
  148. package/dist/types/public.d.ts +0 -2
  149. package/dist/types/public.js +0 -2
  150. package/dist/types/public.js.map +0 -1
  151. package/dist/types/style-spec-bkoi-gl.d.ts +0 -9
  152. package/dist/types/style-spec-bkoi-gl.js +0 -2
  153. package/dist/types/style-spec-bkoi-gl.js.map +0 -1
  154. package/dist/types/style-spec-mapbox.d.ts +0 -7
  155. package/dist/types/style-spec-mapbox.js +0 -2
  156. package/dist/types/style-spec-mapbox.js.map +0 -1
  157. package/src/components/fullscreen-control.tsx +0 -37
  158. package/src/exports-bkoi-gl.ts +0 -156
  159. package/src/exports-mapbox.ts +0 -159
  160. package/src/mapbox/create-ref.ts +0 -118
  161. package/src/mapbox/mapbox.ts +0 -742
  162. package/src/types/events-bkoi-gl.ts +0 -78
  163. package/src/types/events-mapbox.ts +0 -76
  164. package/src/types/index.ts +0 -93
  165. package/src/types/public.ts +0 -9
  166. package/src/types/style-spec-bkoi-gl.ts +0 -81
  167. package/src/types/style-spec-mapbox.ts +0 -80
@@ -1,742 +0,0 @@
1
- import {
2
- transformToViewState,
3
- applyViewStateToTransform,
4
- cloneTransform,
5
- syncProjection
6
- } from '../utils/transform';
7
- import {normalizeStyle} from '../utils/style-utils';
8
- import {deepEqual} from '../utils/deep-equal';
9
-
10
- import type {
11
- Transform,
12
- ViewState,
13
- ViewStateChangeEvent,
14
- Point,
15
- PointLike,
16
- PaddingOptions,
17
- MapStyle,
18
- ImmutableLike,
19
- LngLatBoundsLike,
20
- Callbacks,
21
- MapEvent,
22
- ErrorEvent,
23
- MapMouseEvent,
24
- MapGeoJSONFeature,
25
- MapInstance,
26
- MapInstanceInternal
27
- } from '../types';
28
-
29
- export type MapboxProps<
30
- StyleT extends MapStyle = MapStyle,
31
- CallbacksT extends Callbacks = {}
32
- > = Partial<ViewState> &
33
- CallbacksT & {
34
- // Init options
35
- mapboxAccessToken?: string;
36
-
37
- /** Camera options used when constructing the Map instance */
38
- initialViewState?: Partial<ViewState> & {
39
- /** The initial bounds of the map. If bounds is specified, it overrides longitude, latitude and zoom options. */
40
- bounds?: LngLatBoundsLike;
41
- /** A fitBounds options object to use only when setting the bounds option. */
42
- fitBoundsOptions?: {
43
- offset?: PointLike;
44
- minZoom?: number;
45
- maxZoom?: number;
46
- padding?: number | PaddingOptions;
47
- };
48
- };
49
-
50
- /** If provided, render into an external WebGL context */
51
- gl?: WebGLRenderingContext;
52
-
53
- /** For external controller to override the camera state */
54
- viewState?: ViewState & {
55
- width: number;
56
- height: number;
57
- };
58
-
59
- // Styling
60
-
61
- /** Mapbox style */
62
- mapStyle?: string | StyleT | ImmutableLike<StyleT>;
63
- /** Enable diffing when the map style changes
64
- * @default true
65
- */
66
- styleDiffing?: boolean;
67
- /** The fog property of the style. Must conform to the Fog Style Specification .
68
- * If `undefined` is provided, removes the fog from the map. */
69
- fog?: StyleT['fog'];
70
- /** Light properties of the map. */
71
- light?: StyleT['light'];
72
- /** Terrain property of the style. Must conform to the Terrain Style Specification .
73
- * If `undefined` is provided, removes terrain from the map. */
74
- terrain?: StyleT['terrain'];
75
-
76
- /** Default layers to query on pointer events */
77
- interactiveLayerIds?: string[];
78
- /** CSS cursor */
79
- cursor?: string;
80
- };
81
-
82
- const DEFAULT_STYLE = {version: 8, sources: {}, layers: []} as MapStyle;
83
-
84
- const pointerEvents = {
85
- mousedown: 'onMouseDown',
86
- mouseup: 'onMouseUp',
87
- mouseover: 'onMouseOver',
88
- mousemove: 'onMouseMove',
89
- click: 'onClick',
90
- dblclick: 'onDblClick',
91
- mouseenter: 'onMouseEnter',
92
- mouseleave: 'onMouseLeave',
93
- mouseout: 'onMouseOut',
94
- contextmenu: 'onContextMenu',
95
- touchstart: 'onTouchStart',
96
- touchend: 'onTouchEnd',
97
- touchmove: 'onTouchMove',
98
- touchcancel: 'onTouchCancel'
99
- };
100
- const cameraEvents = {
101
- movestart: 'onMoveStart',
102
- move: 'onMove',
103
- moveend: 'onMoveEnd',
104
- dragstart: 'onDragStart',
105
- drag: 'onDrag',
106
- dragend: 'onDragEnd',
107
- zoomstart: 'onZoomStart',
108
- zoom: 'onZoom',
109
- zoomend: 'onZoomEnd',
110
- rotatestart: 'onRotateStart',
111
- rotate: 'onRotate',
112
- rotateend: 'onRotateEnd',
113
- pitchstart: 'onPitchStart',
114
- pitch: 'onPitch',
115
- pitchend: 'onPitchEnd'
116
- };
117
- const otherEvents = {
118
- wheel: 'onWheel',
119
- boxzoomstart: 'onBoxZoomStart',
120
- boxzoomend: 'onBoxZoomEnd',
121
- boxzoomcancel: 'onBoxZoomCancel',
122
- resize: 'onResize',
123
- load: 'onLoad',
124
- render: 'onRender',
125
- idle: 'onIdle',
126
- remove: 'onRemove',
127
- data: 'onData',
128
- styledata: 'onStyleData',
129
- sourcedata: 'onSourceData',
130
- error: 'onError'
131
- };
132
- const settingNames = [
133
- 'minZoom',
134
- 'maxZoom',
135
- 'minPitch',
136
- 'maxPitch',
137
- 'maxBounds',
138
- 'projection',
139
- 'renderWorldCopies'
140
- ];
141
- const handlerNames = [
142
- 'scrollZoom',
143
- 'boxZoom',
144
- 'dragRotate',
145
- 'dragPan',
146
- 'keyboard',
147
- 'doubleClickZoom',
148
- 'touchZoomRotate',
149
- 'touchPitch'
150
- ];
151
-
152
- /**
153
- * A wrapper for mapbox-gl's Map class
154
- */
155
- export default class Mapbox<
156
- StyleT extends MapStyle = MapStyle,
157
- CallbacksT extends Callbacks = {},
158
- MapT extends MapInstance = MapInstance
159
- > {
160
- private _MapClass: {new (options: any): MapInstance};
161
- // mapboxgl.Map instance
162
- private _map: MapInstanceInternal<MapT> = null;
163
- // User-supplied props
164
- props: MapboxProps<StyleT, CallbacksT>;
165
-
166
- // Mapbox map is stateful.
167
- // During method calls/user interactions, map.transform is mutated and
168
- // deviate from user-supplied props.
169
- // In order to control the map reactively, we shadow the transform
170
- // with the one below, which reflects the view state resolved from
171
- // both user-supplied props and the underlying state
172
- private _renderTransform: Transform;
173
-
174
- // Internal states
175
- private _internalUpdate: boolean = false;
176
- private _inRender: boolean = false;
177
- private _hoveredFeatures: MapGeoJSONFeature[] = null;
178
- private _deferredEvents: {
179
- move: boolean;
180
- zoom: boolean;
181
- pitch: boolean;
182
- rotate: boolean;
183
- } = {
184
- move: false,
185
- zoom: false,
186
- pitch: false,
187
- rotate: false
188
- };
189
-
190
- static savedMaps: Mapbox[] = [];
191
-
192
- constructor(
193
- MapClass: {new (options: any): MapInstance},
194
- props: MapboxProps<StyleT, CallbacksT>,
195
- container: HTMLDivElement
196
- ) {
197
- this._MapClass = MapClass;
198
- this.props = props;
199
- this._initialize(container);
200
- }
201
-
202
- get map(): MapT {
203
- return this._map;
204
- }
205
-
206
- get transform(): Transform {
207
- return this._renderTransform;
208
- }
209
-
210
- setProps(props: MapboxProps<StyleT, CallbacksT>) {
211
- const oldProps = this.props;
212
- this.props = props;
213
-
214
- const settingsChanged = this._updateSettings(props, oldProps);
215
- if (settingsChanged) {
216
- this._createShadowTransform(this._map);
217
- }
218
- const sizeChanged = this._updateSize(props);
219
- const viewStateChanged = this._updateViewState(props, true);
220
- this._updateStyle(props, oldProps);
221
- this._updateStyleComponents(props, oldProps);
222
- this._updateHandlers(props, oldProps);
223
-
224
- // If 1) view state has changed to match props and
225
- // 2) the props change is not triggered by map events,
226
- // it's driven by an external state change. Redraw immediately
227
- if (settingsChanged || sizeChanged || (viewStateChanged && !this._map.isMoving())) {
228
- this.redraw();
229
- }
230
- }
231
-
232
- static reuse<StyleT extends MapStyle, CallbacksT extends Callbacks, MapT extends MapInstance>(
233
- props: MapboxProps<StyleT, CallbacksT>,
234
- container: HTMLDivElement
235
- ): Mapbox<StyleT, CallbacksT, MapT> {
236
- const that = Mapbox.savedMaps.pop() as Mapbox<StyleT, CallbacksT, MapT>;
237
- if (!that) {
238
- return null;
239
- }
240
-
241
- const map = that.map;
242
- // When reusing the saved map, we need to reparent the map(canvas) and other child nodes
243
- // intoto the new container from the props.
244
- // Step 1: reparenting child nodes from old container to new container
245
- const oldContainer = map.getContainer();
246
- container.className = oldContainer.className;
247
- while (oldContainer.childNodes.length > 0) {
248
- container.appendChild(oldContainer.childNodes[0]);
249
- }
250
- // Step 2: replace the internal container with new container from the react component
251
- // @ts-ignore
252
- map._container = container;
253
-
254
- // With maplibre-gl as mapLib, map uses ResizeObserver to observe when its container resizes.
255
- // When reusing the saved map, we need to disconnect the observer and observe the new container.
256
- // Step 3: telling the ResizeObserver to disconnect and observe the new container
257
- // @ts-ignore
258
- const resizeObserver = map._resizeObserver;
259
- if (resizeObserver) {
260
- resizeObserver.disconnect();
261
- resizeObserver.observe(container);
262
- }
263
-
264
- // Step 4: apply new props
265
- that.setProps({...props, styleDiffing: false});
266
- map.resize();
267
- const {initialViewState} = props;
268
- if (initialViewState) {
269
- if (initialViewState.bounds) {
270
- map.fitBounds(initialViewState.bounds, {...initialViewState.fitBoundsOptions, duration: 0});
271
- } else {
272
- that._updateViewState(initialViewState, false);
273
- }
274
- }
275
-
276
- // Simulate load event
277
- if (map.isStyleLoaded()) {
278
- map.fire('load');
279
- } else {
280
- map.once('styledata', () => map.fire('load'));
281
- }
282
-
283
- // Force reload
284
- // @ts-ignore
285
- map._update();
286
- return that;
287
- }
288
-
289
- /* eslint-disable complexity,max-statements */
290
- _initialize(container: HTMLDivElement) {
291
- const {props} = this;
292
- const {mapStyle = DEFAULT_STYLE} = props;
293
- const mapOptions = {
294
- ...props,
295
- ...props.initialViewState,
296
- accessToken: props.mapboxAccessToken || getAccessTokenFromEnv() || null,
297
- container,
298
- style: normalizeStyle(mapStyle)
299
- };
300
-
301
- const viewState = mapOptions.initialViewState || mapOptions.viewState || mapOptions;
302
- Object.assign(mapOptions, {
303
- center: [viewState.longitude || 0, viewState.latitude || 0],
304
- zoom: viewState.zoom || 0,
305
- pitch: viewState.pitch || 0,
306
- bearing: viewState.bearing || 0
307
- });
308
-
309
- if (props.gl) {
310
- // eslint-disable-next-line
311
- const getContext = HTMLCanvasElement.prototype.getContext;
312
- // Hijack canvas.getContext to return our own WebGLContext
313
- // This will be called inside the mapboxgl.Map constructor
314
- // @ts-expect-error
315
- HTMLCanvasElement.prototype.getContext = () => {
316
- // Unhijack immediately
317
- HTMLCanvasElement.prototype.getContext = getContext;
318
- return props.gl;
319
- };
320
- }
321
-
322
- const map = new this._MapClass(mapOptions) as MapInstanceInternal<MapT>;
323
- // Props that are not part of constructor options
324
- if (viewState.padding) {
325
- map.setPadding(viewState.padding);
326
- }
327
- if (props.cursor) {
328
- map.getCanvas().style.cursor = props.cursor;
329
- }
330
- this._createShadowTransform(map);
331
-
332
- // Hack
333
- // Insert code into map's render cycle
334
- const renderMap = map._render;
335
- map._render = (arg: number) => {
336
- this._inRender = true;
337
- renderMap.call(map, arg);
338
- this._inRender = false;
339
- };
340
- const runRenderTaskQueue = map._renderTaskQueue.run;
341
- map._renderTaskQueue.run = (arg: number) => {
342
- runRenderTaskQueue.call(map._renderTaskQueue, arg);
343
- this._onBeforeRepaint();
344
- };
345
- map.on('render', () => this._onAfterRepaint());
346
- // Insert code into map's event pipeline
347
- // eslint-disable-next-line @typescript-eslint/unbound-method
348
- const fireEvent = map.fire;
349
- map.fire = this._fireEvent.bind(this, fireEvent);
350
-
351
- // add listeners
352
- map.on('resize', () => {
353
- this._renderTransform.resize(map.transform.width, map.transform.height);
354
- });
355
- map.on('styledata', () => {
356
- this._updateStyleComponents(this.props, {});
357
- // Projection can be set in stylesheet
358
- syncProjection(map.transform, this._renderTransform);
359
- });
360
- map.on('sourcedata', () => this._updateStyleComponents(this.props, {}));
361
- for (const eventName in pointerEvents) {
362
- map.on(eventName, this._onPointerEvent);
363
- }
364
- for (const eventName in cameraEvents) {
365
- map.on(eventName, this._onCameraEvent);
366
- }
367
- for (const eventName in otherEvents) {
368
- map.on(eventName, this._onEvent);
369
- }
370
- this._map = map;
371
- }
372
- /* eslint-enable complexity,max-statements */
373
-
374
- recycle() {
375
- // Clean up unnecessary elements before storing for reuse.
376
- const container = this.map.getContainer();
377
- const children = container.querySelector('[mapboxgl-children]');
378
- children?.remove();
379
-
380
- Mapbox.savedMaps.push(this);
381
- }
382
-
383
- destroy() {
384
- this._map.remove();
385
- }
386
-
387
- // Force redraw the map now. Typically resize() and jumpTo() is reflected in the next
388
- // render cycle, which is managed by Mapbox's animation loop.
389
- // This removes the synchronization issue caused by requestAnimationFrame.
390
- redraw() {
391
- const map = this._map as any;
392
- // map._render will throw error if style does not exist
393
- // https://github.com/mapbox/mapbox-gl-js/blob/fb9fc316da14e99ff4368f3e4faa3888fb43c513
394
- // /src/ui/map.js#L1834
395
- if (!this._inRender && map.style) {
396
- // cancel the scheduled update
397
- if (map._frame) {
398
- map._frame.cancel();
399
- map._frame = null;
400
- }
401
- // the order is important - render() may schedule another update
402
- map._render();
403
- }
404
- }
405
-
406
- _createShadowTransform(map: any) {
407
- const renderTransform = cloneTransform(map.transform);
408
- map.painter.transform = renderTransform;
409
-
410
- this._renderTransform = renderTransform;
411
- }
412
-
413
- /* Trigger map resize if size is controlled
414
- @param {object} nextProps
415
- @returns {bool} true if size has changed
416
- */
417
- _updateSize(nextProps: MapboxProps<StyleT>): boolean {
418
- // Check if size is controlled
419
- const {viewState} = nextProps;
420
- if (viewState) {
421
- const map = this._map;
422
- if (viewState.width !== map.transform.width || viewState.height !== map.transform.height) {
423
- map.resize();
424
- return true;
425
- }
426
- }
427
- return false;
428
- }
429
-
430
- // Adapted from map.jumpTo
431
- /* Update camera to match props
432
- @param {object} nextProps
433
- @param {bool} triggerEvents - should fire camera events
434
- @returns {bool} true if anything is changed
435
- */
436
- _updateViewState(nextProps: MapboxProps<StyleT>, triggerEvents: boolean): boolean {
437
- if (this._internalUpdate) {
438
- return false;
439
- }
440
- const map = this._map;
441
-
442
- const tr = this._renderTransform;
443
- // Take a snapshot of the transform before mutation
444
- const {zoom, pitch, bearing} = tr;
445
- const isMoving = map.isMoving();
446
-
447
- if (isMoving) {
448
- // All movement of the camera is done relative to the sea level
449
- tr.cameraElevationReference = 'sea';
450
- }
451
- const changed = applyViewStateToTransform(tr, {
452
- ...transformToViewState(map.transform),
453
- ...nextProps
454
- });
455
- if (isMoving) {
456
- // Reset camera reference
457
- tr.cameraElevationReference = 'ground';
458
- }
459
-
460
- if (changed && triggerEvents) {
461
- const deferredEvents = this._deferredEvents;
462
- // Delay DOM control updates to the next render cycle
463
- deferredEvents.move = true;
464
- deferredEvents.zoom ||= zoom !== tr.zoom;
465
- deferredEvents.rotate ||= bearing !== tr.bearing;
466
- deferredEvents.pitch ||= pitch !== tr.pitch;
467
- }
468
-
469
- // Avoid manipulating the real transform when interaction/animation is ongoing
470
- // as it would interfere with Mapbox's handlers
471
- if (!isMoving) {
472
- applyViewStateToTransform(map.transform, nextProps);
473
- }
474
-
475
- return changed;
476
- }
477
-
478
- /* Update camera constraints and projection settings to match props
479
- @param {object} nextProps
480
- @param {object} currProps
481
- @returns {bool} true if anything is changed
482
- */
483
- _updateSettings(nextProps: MapboxProps<StyleT>, currProps: MapboxProps<StyleT>): boolean {
484
- const map = this._map;
485
- let changed = false;
486
- for (const propName of settingNames) {
487
- if (propName in nextProps && !deepEqual(nextProps[propName], currProps[propName])) {
488
- changed = true;
489
- const setter = map[`set${propName[0].toUpperCase()}${propName.slice(1)}`];
490
- setter?.call(map, nextProps[propName]);
491
- }
492
- }
493
- return changed;
494
- }
495
-
496
- /* Update map style to match props
497
- @param {object} nextProps
498
- @param {object} currProps
499
- @returns {bool} true if style is changed
500
- */
501
- _updateStyle(nextProps: MapboxProps<StyleT>, currProps: MapboxProps<StyleT>): boolean {
502
- if (nextProps.cursor !== currProps.cursor) {
503
- this._map.getCanvas().style.cursor = nextProps.cursor || '';
504
- }
505
- if (nextProps.mapStyle !== currProps.mapStyle) {
506
- const {mapStyle = DEFAULT_STYLE, styleDiffing = true} = nextProps;
507
- const options: any = {
508
- diff: styleDiffing
509
- };
510
- if ('localIdeographFontFamily' in nextProps) {
511
- // @ts-ignore Mapbox specific prop
512
- options.localIdeographFontFamily = nextProps.localIdeographFontFamily;
513
- }
514
- this._map.setStyle(normalizeStyle(mapStyle), options);
515
- return true;
516
- }
517
- return false;
518
- }
519
-
520
- /* Update fog, light and terrain to match props
521
- @param {object} nextProps
522
- @param {object} currProps
523
- @returns {bool} true if anything is changed
524
- */
525
- _updateStyleComponents(nextProps: MapboxProps<StyleT>, currProps: MapboxProps<StyleT>): boolean {
526
- const map = this._map;
527
- let changed = false;
528
- if (map.isStyleLoaded()) {
529
- if ('light' in nextProps && map.setLight && !deepEqual(nextProps.light, currProps.light)) {
530
- changed = true;
531
- map.setLight(nextProps.light);
532
- }
533
- if ('fog' in nextProps && map.setFog && !deepEqual(nextProps.fog, currProps.fog)) {
534
- changed = true;
535
- map.setFog(nextProps.fog);
536
- }
537
- if (
538
- 'terrain' in nextProps &&
539
- map.setTerrain &&
540
- !deepEqual(nextProps.terrain, currProps.terrain)
541
- ) {
542
- if (!nextProps.terrain || map.getSource(nextProps.terrain.source)) {
543
- changed = true;
544
- map.setTerrain(nextProps.terrain);
545
- }
546
- }
547
- }
548
- return changed;
549
- }
550
-
551
- /* Update interaction handlers to match props
552
- @param {object} nextProps
553
- @param {object} currProps
554
- @returns {bool} true if anything is changed
555
- */
556
- _updateHandlers(nextProps: MapboxProps<StyleT>, currProps: MapboxProps<StyleT>): boolean {
557
- const map = this._map;
558
- let changed = false;
559
- for (const propName of handlerNames) {
560
- const newValue = nextProps[propName] ?? true;
561
- const oldValue = currProps[propName] ?? true;
562
- if (!deepEqual(newValue, oldValue)) {
563
- changed = true;
564
- if (newValue) {
565
- map[propName].enable(newValue);
566
- } else {
567
- map[propName].disable();
568
- }
569
- }
570
- }
571
- return changed;
572
- }
573
-
574
- _onEvent = (e: MapEvent<MapT>) => {
575
- // @ts-ignore
576
- const cb = this.props[otherEvents[e.type]];
577
- if (cb) {
578
- cb(e);
579
- } else if (e.type === 'error') {
580
- console.error((e as ErrorEvent<MapT>).error); // eslint-disable-line
581
- }
582
- };
583
-
584
- private _queryRenderedFeatures(point: Point) {
585
- const map = this._map;
586
- const tr = map.transform;
587
- const {interactiveLayerIds = []} = this.props;
588
- try {
589
- map.transform = this._renderTransform;
590
- return map.queryRenderedFeatures(point, {
591
- layers: interactiveLayerIds.filter(map.getLayer.bind(map))
592
- });
593
- } catch {
594
- // May fail if style is not loaded
595
- return [];
596
- } finally {
597
- map.transform = tr;
598
- }
599
- }
600
-
601
- _updateHover(e: MapMouseEvent<MapT>) {
602
- const {props} = this;
603
- const shouldTrackHoveredFeatures =
604
- props.interactiveLayerIds && (props.onMouseMove || props.onMouseEnter || props.onMouseLeave);
605
-
606
- if (shouldTrackHoveredFeatures) {
607
- const eventType = e.type;
608
- const wasHovering = this._hoveredFeatures?.length > 0;
609
- const features = this._queryRenderedFeatures(e.point);
610
- const isHovering = features.length > 0;
611
-
612
- if (!isHovering && wasHovering) {
613
- e.type = 'mouseleave';
614
- this._onPointerEvent(e);
615
- }
616
- this._hoveredFeatures = features;
617
- if (isHovering && !wasHovering) {
618
- e.type = 'mouseenter';
619
- this._onPointerEvent(e);
620
- }
621
- e.type = eventType;
622
- } else {
623
- this._hoveredFeatures = null;
624
- }
625
- }
626
-
627
- _onPointerEvent = (e: MapMouseEvent<MapT> | MapMouseEvent<MapT>) => {
628
- if (e.type === 'mousemove' || e.type === 'mouseout') {
629
- this._updateHover(e);
630
- }
631
-
632
- // @ts-ignore
633
- const cb = this.props[pointerEvents[e.type]];
634
- if (cb) {
635
- if (this.props.interactiveLayerIds && e.type !== 'mouseover' && e.type !== 'mouseout') {
636
- e.features = this._hoveredFeatures || this._queryRenderedFeatures(e.point);
637
- }
638
- cb(e);
639
- delete e.features;
640
- }
641
- };
642
-
643
- _onCameraEvent = (e: ViewStateChangeEvent<MapT>) => {
644
- if (!this._internalUpdate) {
645
- // @ts-ignore
646
- const cb = this.props[cameraEvents[e.type]];
647
- if (cb) {
648
- cb(e);
649
- }
650
- }
651
- if (e.type in this._deferredEvents) {
652
- this._deferredEvents[e.type] = false;
653
- }
654
- };
655
-
656
- _fireEvent(baseFire: Function, event: string | MapEvent<MapT>, properties?: object) {
657
- const map = this._map;
658
- const tr = map.transform;
659
-
660
- const eventType = typeof event === 'string' ? event : event.type;
661
- if (eventType === 'move') {
662
- this._updateViewState(this.props, false);
663
- }
664
- if (eventType in cameraEvents) {
665
- if (typeof event === 'object') {
666
- (event as unknown as ViewStateChangeEvent<MapT>).viewState = transformToViewState(tr);
667
- }
668
- if (this._map.isMoving()) {
669
- // Replace map.transform with ours during the callbacks
670
- map.transform = this._renderTransform;
671
- baseFire.call(map, event, properties);
672
- map.transform = tr;
673
-
674
- return map;
675
- }
676
- }
677
- baseFire.call(map, event, properties);
678
-
679
- return map;
680
- }
681
-
682
- // All camera manipulations are complete, ready to repaint
683
- _onBeforeRepaint() {
684
- const map = this._map;
685
-
686
- // If there are camera changes driven by props, invoke camera events so that DOM controls are synced
687
- this._internalUpdate = true;
688
- for (const eventType in this._deferredEvents) {
689
- if (this._deferredEvents[eventType]) {
690
- map.fire(eventType);
691
- }
692
- }
693
- this._internalUpdate = false;
694
-
695
- const tr = this._map.transform;
696
- // Make sure camera matches the current props
697
- map.transform = this._renderTransform;
698
-
699
- this._onAfterRepaint = () => {
700
- // Mapbox transitions between non-mercator projection and mercator during render time
701
- // Copy it back to the other
702
- syncProjection(this._renderTransform, tr);
703
- // Restores camera state before render/load events are fired
704
- map.transform = tr;
705
- };
706
- }
707
-
708
- _onAfterRepaint: () => void;
709
- }
710
-
711
- /**
712
- * Access token can be provided via one of:
713
- * mapboxAccessToken prop
714
- * access_token query parameter
715
- * MapboxAccessToken environment variable
716
- * REACT_APP_MAPBOX_ACCESS_TOKEN environment variable
717
- * @returns access token
718
- */
719
- function getAccessTokenFromEnv(): string {
720
- let accessToken = null;
721
-
722
- /* global location, process */
723
- if (typeof location !== 'undefined') {
724
- const match = /access_token=([^&\/]*)/.exec(location.search);
725
- accessToken = match && match[1];
726
- }
727
-
728
- // Note: This depends on bundler plugins (e.g. webpack) importing environment correctly
729
- try {
730
- accessToken = accessToken || process.env.MapboxAccessToken;
731
- } catch {
732
- // ignore
733
- }
734
-
735
- try {
736
- accessToken = accessToken || process.env.REACT_APP_MAPBOX_ACCESS_TOKEN;
737
- } catch {
738
- // ignore
739
- }
740
-
741
- return accessToken;
742
- }