@maplibre/maplibre-react-native 10.0.0-alpha.5 → 10.0.0-alpha.7

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 (54) hide show
  1. package/.eslintrc.js +3 -1
  2. package/.yarn/sdks/eslint/bin/eslint.js +8 -1
  3. package/.yarn/sdks/eslint/lib/api.js +8 -1
  4. package/.yarn/sdks/eslint/lib/unsupported-api.js +8 -1
  5. package/.yarn/sdks/prettier/bin/prettier.cjs +8 -1
  6. package/.yarn/sdks/prettier/index.cjs +8 -1
  7. package/.yarn/sdks/typescript/bin/tsc +8 -1
  8. package/.yarn/sdks/typescript/bin/tsserver +8 -1
  9. package/.yarn/sdks/typescript/lib/tsc.js +8 -1
  10. package/.yarn/sdks/typescript/lib/tsserver.js +20 -6
  11. package/.yarn/sdks/typescript/lib/tsserverlibrary.js +20 -6
  12. package/.yarn/sdks/typescript/lib/typescript.js +8 -1
  13. package/CHANGELOG.md +57 -48
  14. package/CONTRIBUTING.md +10 -9
  15. package/android/rctmln/src/main/java/com/maplibre/rctmln/components/annotation/MarkerViewManager.java +5 -3
  16. package/android/rctmln/src/main/java/com/maplibre/rctmln/components/mapview/RCTMLNMapView.java +7 -7
  17. package/docs/Camera.md +3 -3
  18. package/docs/MapView.md +9 -33
  19. package/docs/UserLocation.md +10 -2
  20. package/docs/docs.json +17 -32
  21. package/docs/offlineManager.md +246 -0
  22. package/javascript/Maplibre.ts +5 -1
  23. package/javascript/components/BackgroundLayer.tsx +27 -20
  24. package/javascript/components/Callout.tsx +40 -40
  25. package/javascript/components/Camera.tsx +421 -478
  26. package/javascript/components/CircleLayer.tsx +29 -22
  27. package/javascript/components/FillExtrusionLayer.tsx +23 -23
  28. package/javascript/components/FillLayer.tsx +22 -19
  29. package/javascript/components/HeatmapLayer.tsx +21 -19
  30. package/javascript/components/ImageSource.tsx +25 -32
  31. package/javascript/components/Images.tsx +36 -35
  32. package/javascript/components/Light.tsx +20 -47
  33. package/javascript/components/LineLayer.tsx +23 -20
  34. package/javascript/components/MapView.tsx +604 -554
  35. package/javascript/components/MarkerView.tsx +23 -38
  36. package/javascript/components/NativeUserLocation.tsx +3 -5
  37. package/javascript/components/PointAnnotation.tsx +111 -87
  38. package/javascript/components/RasterLayer.tsx +21 -18
  39. package/javascript/components/RasterSource.tsx +39 -42
  40. package/javascript/components/ShapeSource.tsx +287 -239
  41. package/javascript/components/Style.tsx +1 -1
  42. package/javascript/components/SymbolLayer.tsx +34 -28
  43. package/javascript/components/UserLocation.tsx +164 -151
  44. package/javascript/components/VectorSource.tsx +128 -117
  45. package/javascript/components/annotations/Annotation.tsx +105 -79
  46. package/javascript/{components/AbstractLayer.tsx → hooks/useAbstractLayer.ts} +54 -37
  47. package/javascript/hooks/useAbstractSource.ts +34 -0
  48. package/javascript/hooks/useNativeBridge.ts +125 -0
  49. package/javascript/hooks/useNativeRef.ts +13 -0
  50. package/javascript/hooks/useOnce.ts +12 -0
  51. package/javascript/utils/Logger.ts +3 -3
  52. package/package.json +2 -1
  53. package/javascript/components/AbstractSource.tsx +0 -27
  54. package/javascript/components/NativeBridgeComponent.tsx +0 -117
@@ -1,32 +1,43 @@
1
- import {ExpressionField, FilterExpression} from '../utils/MaplibreStyles';
2
- import {getFilter} from '../utils/filterUtils';
1
+ import useNativeBridge from '../hooks/useNativeBridge';
2
+ import BaseProps from '../types/BaseProps';
3
+ import OnPressEvent from '../types/OnPressEvent';
3
4
  import {
4
- toJSONString,
5
5
  cloneReactChildrenWithProps,
6
- isFunction,
7
6
  isAndroid,
7
+ isFunction,
8
+ toJSONString,
8
9
  } from '../utils';
10
+ import {ExpressionField, FilterExpression} from '../utils/MaplibreStyles';
9
11
  import {copyPropertiesAsDeprecated} from '../utils/deprecation';
10
- import OnPressEvent from '../types/OnPressEvent';
11
- import BaseProps from '../types/BaseProps';
12
-
13
- import AbstractSource from './AbstractSource';
14
- import NativeBridgeComponent from './NativeBridgeComponent';
12
+ import {getFilter} from '../utils/filterUtils';
15
13
 
16
- import React, {Component, ReactElement} from 'react';
17
14
  import {
18
15
  NativeMethods,
19
16
  NativeModules,
20
17
  NativeSyntheticEvent,
21
18
  requireNativeComponent,
22
19
  } from 'react-native';
20
+ import React, {
21
+ Component,
22
+ ReactElement,
23
+ memo,
24
+ useImperativeHandle,
25
+ useRef,
26
+ } from 'react';
23
27
  import {Feature, FeatureCollection} from '@turf/helpers';
24
28
 
25
29
  const MapLibreGL = NativeModules.MLNModule;
26
-
27
30
  export const NATIVE_MODULE_NAME = 'RCTMLNShapeSource';
31
+ export const SHAPE_SOURCE_NATIVE_ASSETS_KEY = 'assets';
32
+
33
+ interface NativeProps {
34
+ shape?: string;
35
+ }
28
36
 
29
- interface ShapeSourceProps extends BaseProps {
37
+ type RCTMLNShapeSourceRefType = Component<NativeProps> &
38
+ Readonly<NativeMethods>;
39
+
40
+ export interface ShapeSourceProps extends BaseProps {
30
41
  /**
31
42
  * A string that uniquely identifies the source.
32
43
  */
@@ -125,257 +136,294 @@ interface ShapeSourceProps extends BaseProps {
125
136
  children?: ReactElement | ReactElement[];
126
137
  }
127
138
 
128
- interface NativeProps {
129
- shape?: string;
139
+ export interface ShapeSourceRef {
140
+ features(filter?: FilterExpression): Promise<FeatureCollection>;
141
+ getClusterExpansionZoom(feature: Feature): Promise<number>;
142
+ getClusterLeaves(
143
+ feature: Feature,
144
+ limit: number,
145
+ offset: number,
146
+ ): Promise<FeatureCollection>;
147
+ getClusterChildren(feature: Feature): Promise<FeatureCollection>;
148
+ setNativeProps: (props: NativeProps) => void;
149
+ onPress: (event: NativeSyntheticEvent<{payload: OnPressEvent}>) => void;
150
+
151
+ // this was required by existing test __tests__/utils/animated/AnimatedCoordinatesArray.test.js
152
+ _nativeRef: RCTMLNShapeSourceRefType | undefined;
130
153
  }
131
154
 
132
155
  /**
133
156
  * ShapeSource is a map content source that supplies vector shapes to be shown on the map.
134
157
  * The shape may be a url or a GeoJSON object
135
158
  */
136
- class ShapeSource extends NativeBridgeComponent(
137
- AbstractSource<ShapeSourceProps, NativeProps>,
138
- NATIVE_MODULE_NAME,
139
- ) {
140
- static NATIVE_ASSETS_KEY = 'assets';
141
-
142
- static defaultProps = {
143
- id: MapLibreGL.StyleSource.DefaultSourceID,
144
- };
159
+ const ShapeSource = memo(
160
+ React.forwardRef(
161
+ (
162
+ {
163
+ id: shapeId = MapLibreGL.StyleSource.DefaultSourceID,
164
+ ...props
165
+ }: ShapeSourceProps,
166
+ ref,
167
+ ) => {
168
+ useImperativeHandle(
169
+ ref,
170
+ (): ShapeSourceRef => ({
171
+ /**
172
+ * Returns all features from the source that match the query parameters regardless of whether or not the feature is
173
+ * currently rendered on the map.
174
+ *
175
+ * @example
176
+ * shapeSource.features()
177
+ *
178
+ * @param {Array=} filter - an optional filter statement to filter the returned Features.
179
+ * @return {FeatureCollection}
180
+ */
181
+ features,
182
+ /**
183
+ * Returns the zoom needed to expand the cluster.
184
+ *
185
+ * @example
186
+ * const zoom = await shapeSource.getClusterExpansionZoom(clusterId);
187
+ *
188
+ * @param {Feature} feature - The feature cluster to expand.
189
+ * @return {number}
190
+ */
191
+ getClusterExpansionZoom,
192
+ /**
193
+ * Returns the FeatureCollection from the cluster.
194
+ *
195
+ * @example
196
+ * const collection = await shapeSource.getClusterLeaves(clusterId, limit, offset);
197
+ *
198
+ * @param {Feature} feature - The feature cluster to expand.
199
+ * @param {number} limit - The number of points to return.
200
+ * @param {number} offset - The amount of points to skip (for pagination).
201
+ * @return {FeatureCollection}
202
+ */
203
+ getClusterLeaves,
204
+ /**
205
+ * Returns the FeatureCollection from the cluster (on the next zoom level).
206
+ *
207
+ * @example
208
+ * const collection = await shapeSource.getClusterChildren(clusterId);
209
+ *
210
+ * @param {Feature} feature - The feature cluster to expand.
211
+ * @return {FeatureCollection}
212
+ */
213
+ getClusterChildren,
214
+ setNativeProps,
215
+ onPress,
216
+ _nativeRef: _nativeRef.current,
217
+ }),
218
+ );
145
219
 
146
- constructor(props: ShapeSourceProps) {
147
- super(props);
148
- }
220
+ const _nativeRef = useRef<RCTMLNShapeSourceRefType>();
149
221
 
150
- _setNativeRef(
151
- nativeRef: Component<NativeProps> & Readonly<NativeMethods>,
152
- ): void {
153
- this.setNativeRef(nativeRef);
154
- super._runPendingNativeCommands(nativeRef);
155
- }
222
+ const {_runNativeCommand, _runPendingNativeCommands, _onAndroidCallback} =
223
+ useNativeBridge(NATIVE_MODULE_NAME);
156
224
 
157
- /**
158
- * Returns all features from the source that match the query parameters regardless of whether or not the feature is
159
- * currently rendered on the map.
160
- *
161
- * @example
162
- * shapeSource.features()
163
- *
164
- * @param {Array=} filter - an optional filter statement to filter the returned Features.
165
- * @return {FeatureCollection}
166
- */
167
- async features(filter?: FilterExpression): Promise<FeatureCollection> {
168
- const res: {data: string | FeatureCollection} =
169
- await this._runNativeCommand('features', this._nativeRef, [
170
- getFilter(filter),
171
- ]);
225
+ const _setNativeRef = (nativeRef: RCTMLNShapeSourceRefType): void => {
226
+ _nativeRef.current = nativeRef;
227
+ _runPendingNativeCommands(nativeRef);
228
+ };
172
229
 
173
- if (isAndroid()) {
174
- return JSON.parse(res.data as string);
175
- }
230
+ async function features(
231
+ filter?: FilterExpression,
232
+ ): Promise<FeatureCollection> {
233
+ const res: {data: string | FeatureCollection} = await _runNativeCommand(
234
+ 'features',
235
+ _nativeRef.current,
236
+ [getFilter(filter)],
237
+ );
176
238
 
177
- return res.data as FeatureCollection;
178
- }
239
+ if (isAndroid()) {
240
+ return JSON.parse(res.data as string);
241
+ }
179
242
 
180
- /**
181
- * Returns the zoom needed to expand the cluster.
182
- *
183
- * @example
184
- * const zoom = await shapeSource.getClusterExpansionZoom(clusterId);
185
- *
186
- * @param {Feature} feature - The feature cluster to expand.
187
- * @return {number}
188
- */
189
- async getClusterExpansionZoom(feature: Feature): Promise<number> {
190
- if (typeof feature === 'number') {
191
- console.warn(
192
- 'Using cluster_id is deprecated and will be removed from the future releases. Please use cluster as an argument instead.',
193
- );
194
- const res: {data: number} = await this._runNativeCommand(
195
- 'getClusterExpansionZoomById',
196
- this._nativeRef,
197
- [feature],
198
- );
199
- return res.data;
200
- }
243
+ return res.data as FeatureCollection;
244
+ }
201
245
 
202
- const res: {data: number} = await this._runNativeCommand(
203
- 'getClusterExpansionZoom',
204
- this._nativeRef,
205
- [JSON.stringify(feature)],
206
- );
207
- return res.data;
208
- }
246
+ async function getClusterExpansionZoom(
247
+ feature: Feature,
248
+ ): Promise<number> {
249
+ if (typeof feature === 'number') {
250
+ console.warn(
251
+ 'Using cluster_id is deprecated and will be removed from the future releases. Please use cluster as an argument instead.',
252
+ );
253
+ const res: {data: number} = await _runNativeCommand(
254
+ 'getClusterExpansionZoomById',
255
+ _nativeRef.current,
256
+ [feature],
257
+ );
258
+ return res.data;
259
+ }
260
+
261
+ const res: {data: number} = await _runNativeCommand(
262
+ 'getClusterExpansionZoom',
263
+ _nativeRef.current,
264
+ [JSON.stringify(feature)],
265
+ );
266
+ return res.data;
267
+ }
209
268
 
210
- /**
211
- * Returns the FeatureCollection from the cluster.
212
- *
213
- * @example
214
- * const collection = await shapeSource.getClusterLeaves(clusterId, limit, offset);
215
- *
216
- * @param {Feature} feature - The feature cluster to expand.
217
- * @param {number} limit - The number of points to return.
218
- * @param {number} offset - The amount of points to skip (for pagination).
219
- * @return {FeatureCollection}
220
- */
221
- async getClusterLeaves(
222
- feature: Feature,
223
- limit: number,
224
- offset: number,
225
- ): Promise<FeatureCollection> {
226
- if (typeof feature === 'number') {
227
- console.warn(
228
- 'Using cluster_id is deprecated and will be removed from the future releases. Please use cluster as an argument instead.',
229
- );
230
- const res: {data: string | FeatureCollection} =
231
- await this._runNativeCommand('getClusterLeavesById', this._nativeRef, [
232
- feature,
233
- limit,
234
- offset,
235
- ]);
236
-
237
- if (isAndroid()) {
238
- return JSON.parse(res.data as string);
269
+ async function getClusterLeaves(
270
+ feature: Feature,
271
+ limit: number,
272
+ offset: number,
273
+ ): Promise<FeatureCollection> {
274
+ if (typeof feature === 'number') {
275
+ console.warn(
276
+ 'Using cluster_id is deprecated and will be removed from the future releases. Please use cluster as an argument instead.',
277
+ );
278
+ const res: {data: string | FeatureCollection} =
279
+ await _runNativeCommand(
280
+ 'getClusterLeavesById',
281
+ _nativeRef.current,
282
+ [feature, limit, offset],
283
+ );
284
+
285
+ if (isAndroid()) {
286
+ return JSON.parse(res.data as string);
287
+ }
288
+
289
+ return res.data as FeatureCollection;
290
+ }
291
+
292
+ const res: {data: string | FeatureCollection} = await _runNativeCommand(
293
+ 'getClusterLeaves',
294
+ _nativeRef.current,
295
+ [JSON.stringify(feature), limit, offset],
296
+ );
297
+
298
+ if (isAndroid()) {
299
+ return JSON.parse(res.data as string);
300
+ }
301
+
302
+ return res.data as FeatureCollection;
239
303
  }
240
304
 
241
- return res.data as FeatureCollection;
242
- }
305
+ async function getClusterChildren(
306
+ feature: Feature,
307
+ ): Promise<FeatureCollection> {
308
+ if (typeof feature === 'number') {
309
+ console.warn(
310
+ 'Using cluster_id is deprecated and will be removed from the future releases. Please use cluster as an argument instead.',
311
+ );
312
+ const res: {data: string | FeatureCollection} =
313
+ await _runNativeCommand(
314
+ 'getClusterChildrenById',
315
+ _nativeRef.current,
316
+ [feature],
317
+ );
318
+
319
+ if (isAndroid()) {
320
+ return JSON.parse(res.data as string);
321
+ }
322
+
323
+ return res.data as FeatureCollection;
324
+ }
325
+
326
+ const res: {data: string | FeatureCollection} = await _runNativeCommand(
327
+ 'getClusterChildren',
328
+ _nativeRef.current,
329
+ [JSON.stringify(feature)],
330
+ );
243
331
 
244
- const res: {data: string | FeatureCollection} =
245
- await this._runNativeCommand('getClusterLeaves', this._nativeRef, [
246
- JSON.stringify(feature),
247
- limit,
248
- offset,
249
- ]);
332
+ if (isAndroid()) {
333
+ return JSON.parse(res.data as string);
334
+ }
250
335
 
251
- if (isAndroid()) {
252
- return JSON.parse(res.data as string);
253
- }
336
+ return res.data as FeatureCollection;
337
+ }
254
338
 
255
- return res.data as FeatureCollection;
256
- }
339
+ function setNativeProps(nativeProps: NativeProps): void {
340
+ if (!_nativeRef.current) {
341
+ return;
342
+ }
257
343
 
258
- /**
259
- * Returns the FeatureCollection from the cluster (on the next zoom level).
260
- *
261
- * @example
262
- * const collection = await shapeSource.getClusterChildren(clusterId);
263
- *
264
- * @param {Feature} feature - The feature cluster to expand.
265
- * @return {FeatureCollection}
266
- */
267
- async getClusterChildren(feature: Feature): Promise<FeatureCollection> {
268
- if (typeof feature === 'number') {
269
- console.warn(
270
- 'Using cluster_id is deprecated and will be removed from the future releases. Please use cluster as an argument instead.',
271
- );
272
- const res: {data: string | FeatureCollection} =
273
- await this._runNativeCommand(
274
- 'getClusterChildrenById',
275
- this._nativeRef,
276
- [feature],
277
- );
344
+ const shallowProps = Object.assign({}, nativeProps);
345
+
346
+ // Adds support for Animated
347
+ if (shallowProps.shape && typeof shallowProps !== 'string') {
348
+ shallowProps.shape = JSON.stringify(shallowProps.shape);
349
+ }
278
350
 
279
- if (isAndroid()) {
280
- return JSON.parse(res.data as string);
351
+ _nativeRef.current.setNativeProps(shallowProps);
281
352
  }
282
353
 
283
- return res.data as FeatureCollection;
284
- }
285
-
286
- const res: {data: string | FeatureCollection} =
287
- await this._runNativeCommand('getClusterChildren', this._nativeRef, [
288
- JSON.stringify(feature),
289
- ]);
290
-
291
- if (isAndroid()) {
292
- return JSON.parse(res.data as string);
293
- }
294
-
295
- return res.data as FeatureCollection;
296
- }
297
-
298
- setNativeProps(props: NativeProps): void {
299
- const shallowProps = Object.assign({}, props);
300
-
301
- // Adds support for Animated
302
- if (shallowProps.shape && typeof shallowProps !== 'string') {
303
- shallowProps.shape = JSON.stringify(shallowProps.shape);
304
- }
305
-
306
- super.setNativeProps(shallowProps);
307
- }
308
-
309
- _getShape(): string | undefined {
310
- if (!this.props.shape) {
311
- return;
312
- }
313
- return toJSONString(this.props.shape);
314
- }
315
-
316
- onPress(event: NativeSyntheticEvent<{payload: OnPressEvent}>): void {
317
- const {
318
- nativeEvent: {
319
- payload: {features, coordinates, point},
320
- },
321
- } = event;
322
- let newEvent = {
323
- features,
324
- coordinates,
325
- point,
326
- };
327
- newEvent = copyPropertiesAsDeprecated(
328
- event,
329
- newEvent,
330
- (key: string): void => {
331
- console.warn(
332
- `event.${key} is deprecated on ShapeSource#onPress, please use event.features`,
354
+ function _getShape(): string | undefined {
355
+ if (!props.shape) {
356
+ return;
357
+ }
358
+ return toJSONString(props.shape);
359
+ }
360
+
361
+ function onPress(
362
+ event: NativeSyntheticEvent<{payload: OnPressEvent}>,
363
+ ): void {
364
+ const {
365
+ nativeEvent: {
366
+ payload: {features, coordinates, point},
367
+ },
368
+ } = event;
369
+ let newEvent = {
370
+ features,
371
+ coordinates,
372
+ point,
373
+ };
374
+ newEvent = copyPropertiesAsDeprecated(
375
+ event,
376
+ newEvent,
377
+ (key: string): void => {
378
+ console.warn(
379
+ `event.${key} is deprecated on ShapeSource#onPress, please use event.features`,
380
+ );
381
+ },
382
+ {
383
+ nativeEvent: (
384
+ origNativeEvent: NativeSyntheticEvent<{payload: OnPressEvent}>,
385
+ ) => ({
386
+ ...origNativeEvent,
387
+ payload: features[0],
388
+ }),
389
+ },
333
390
  );
334
- },
335
- {
336
- nativeEvent: (
337
- origNativeEvent: NativeSyntheticEvent<{payload: OnPressEvent}>,
338
- ) => ({
339
- ...origNativeEvent,
340
- payload: features[0],
341
- }),
342
- },
343
- );
344
- if (this.props.onPress) {
345
- this.props.onPress(newEvent);
346
- }
347
- }
348
-
349
- render(): ReactElement {
350
- const props = {
351
- id: this.props.id,
352
- url: this.props.url,
353
- shape: this._getShape(),
354
- hitbox: this.props.hitbox,
355
- hasPressListener: isFunction(this.props.onPress),
356
- onMapboxShapeSourcePress: this.onPress.bind(this),
357
- cluster: this.props.cluster ? 1 : 0,
358
- clusterRadius: this.props.clusterRadius,
359
- clusterMaxZoomLevel: this.props.clusterMaxZoomLevel,
360
- clusterProperties: this.props.clusterProperties,
361
- maxZoomLevel: this.props.maxZoomLevel,
362
- buffer: this.props.buffer,
363
- tolerance: this.props.tolerance,
364
- lineMetrics: this.props.lineMetrics,
365
- onPress: undefined,
366
- ref: this.setNativeRef,
367
- onAndroidCallback: isAndroid() ? this._onAndroidCallback : undefined,
368
- };
369
-
370
- return (
371
- <RCTMLNShapeSource {...props}>
372
- {cloneReactChildrenWithProps(this.props.children, {
373
- sourceID: this.props.id,
374
- })}
375
- </RCTMLNShapeSource>
376
- );
377
- }
378
- }
391
+
392
+ if (props.onPress) {
393
+ props.onPress(newEvent);
394
+ }
395
+ }
396
+
397
+ const shapeProps = {
398
+ id: shapeId,
399
+ url: props.url,
400
+ shape: _getShape(),
401
+ hitbox: props.hitbox,
402
+ hasPressListener: isFunction(props.onPress),
403
+ onMapboxShapeSourcePress: onPress.bind(this),
404
+ cluster: props.cluster ? 1 : 0,
405
+ clusterRadius: props.clusterRadius,
406
+ clusterMaxZoomLevel: props.clusterMaxZoomLevel,
407
+ clusterProperties: props.clusterProperties,
408
+ maxZoomLevel: props.maxZoomLevel,
409
+ buffer: props.buffer,
410
+ tolerance: props.tolerance,
411
+ lineMetrics: props.lineMetrics,
412
+ onPress: undefined,
413
+ ref: _setNativeRef,
414
+ onAndroidCallback: isAndroid() ? _onAndroidCallback : undefined,
415
+ };
416
+
417
+ return (
418
+ <RCTMLNShapeSource {...shapeProps}>
419
+ {cloneReactChildrenWithProps(props.children, {
420
+ sourceID: shapeId,
421
+ })}
422
+ </RCTMLNShapeSource>
423
+ );
424
+ },
425
+ ),
426
+ );
379
427
 
380
428
  const RCTMLNShapeSource =
381
429
  requireNativeComponent<NativeProps>(NATIVE_MODULE_NAME);
@@ -1,4 +1,5 @@
1
1
  import {ExpressionField, FilterExpression} from '../utils/MaplibreStyles';
2
+ import {BaseLayerProps} from '../hooks/useAbstractLayer';
2
3
 
3
4
  import CircleLayer from './CircleLayer';
4
5
  import RasterLayer from './RasterLayer';
@@ -12,7 +13,6 @@ import VectorSource from './VectorSource';
12
13
  import RasterSource from './RasterSource';
13
14
  import ImageSource from './ImageSource';
14
15
  import ShapeSource from './ShapeSource';
15
- import {BaseLayerProps} from './AbstractLayer';
16
16
 
17
17
  import React, {
18
18
  useMemo,