@maplibre/maplibre-react-native 10.0.0-alpha.24 → 10.0.0-alpha.26

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 (173) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/CONTRIBUTING.md +1 -1
  3. package/android/build.gradle +51 -16
  4. package/docs/Annotation.md +8 -17
  5. package/docs/BackgroundLayer.md +136 -128
  6. package/docs/Callout.md +5 -4
  7. package/docs/Camera.md +38 -39
  8. package/docs/CircleLayer.md +413 -388
  9. package/docs/FillExtrusionLayer.md +303 -292
  10. package/docs/FillLayer.md +266 -251
  11. package/docs/HeadingIndicator.md +5 -4
  12. package/docs/HeatmapLayer.md +179 -172
  13. package/docs/ImageSource.md +5 -4
  14. package/docs/Images.md +5 -4
  15. package/docs/Light.md +131 -123
  16. package/docs/LineLayer.md +525 -498
  17. package/docs/MapView.md +23 -42
  18. package/docs/MarkerView.md +5 -4
  19. package/docs/NativeUserLocation.md +5 -4
  20. package/docs/PointAnnotation.md +7 -10
  21. package/docs/RasterLayer.md +318 -310
  22. package/docs/RasterSource.md +5 -4
  23. package/docs/ShapeSource.md +16 -15
  24. package/docs/Style.md +5 -4
  25. package/docs/SymbolLayer.md +1501 -1406
  26. package/docs/UserLocation.md +10 -13
  27. package/docs/VectorSource.md +10 -9
  28. package/docs/coordinates.md +4 -3
  29. package/docs/docs.json +49 -88
  30. package/docs/location.md +4 -3
  31. package/docs/offlineManager.md +29 -44
  32. package/docs/snapshotManager.md +7 -6
  33. package/ios/RCTMLN/RCTMLNCamera.h +0 -3
  34. package/ios/RCTMLN/RCTMLNCamera.m +1 -1
  35. package/ios/RCTMLN/RCTMLNCameraManager.m +0 -3
  36. package/javascript/MLNModule.ts +9 -0
  37. package/javascript/Maplibre.ts +1 -1
  38. package/javascript/components/{annotations/Annotation.tsx → Annotation.tsx} +5 -5
  39. package/javascript/components/Camera.tsx +257 -388
  40. package/javascript/components/UserLocation.tsx +1 -1
  41. package/javascript/hooks/useNativeRef.ts +2 -1
  42. package/javascript/types/CameraMode.ts +6 -0
  43. package/package.json +16 -24
  44. package/scripts/codegen.ts +340 -0
  45. package/scripts/templates/MaplibreStyles.ts.ejs +8 -7
  46. package/scripts/templates/RCTMLNStyle.h.ejs +4 -3
  47. package/scripts/templates/RCTMLNStyle.m.ejs +11 -10
  48. package/scripts/templates/RCTMLNStyleFactory.java.ejs +12 -11
  49. package/scripts/templates/component.md.ejs +88 -85
  50. package/scripts/templates/index.d.ts.ejs +2 -1
  51. package/scripts/templates/styleMap.ts.ejs +2 -1
  52. package/scripts/utils/{DocJSONBuilder.js → DocJSONBuilder.ts} +133 -128
  53. package/scripts/utils/{JSDocNodeTree.js → JSDocNodeTree.ts} +14 -13
  54. package/scripts/utils/MarkdownBuilder.ts +44 -0
  55. package/scripts/utils/{template-globals.js → TemplateHelpers.ts} +66 -95
  56. package/scripts/utils/getNativeVersion.ts +53 -0
  57. package/tsconfig.json +2 -3
  58. package/.husky/pre-commit +0 -5
  59. package/android/rctmln/.settings/org.eclipse.buildship.core.prefs +0 -2
  60. package/android/rctmln/build.gradle +0 -64
  61. package/android/rctmln/proguard-rules.pro +0 -25
  62. package/docs/OfflineManager.md +0 -246
  63. package/react-native.config.js +0 -10
  64. package/scripts/download-style-spec.sh +0 -15
  65. package/scripts/generate-docs.js +0 -396
  66. package/scripts/utils/MarkdownBuilder.js +0 -37
  67. package/style-spec/v8.json +0 -6645
  68. /package/android/{rctmln/src → src}/main/AndroidManifest.xml +0 -0
  69. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/RCTMLNPackage.java +0 -0
  70. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/AbstractEvent.java +0 -0
  71. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/AbstractEventEmitter.java +0 -0
  72. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/AbstractMapFeature.java +0 -0
  73. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/annotation/MarkerView.java +0 -0
  74. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/annotation/MarkerViewManager.java +0 -0
  75. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/annotation/RCTMLNCallout.java +0 -0
  76. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/annotation/RCTMLNCalloutManager.java +0 -0
  77. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/annotation/RCTMLNMarkerView.java +0 -0
  78. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/annotation/RCTMLNMarkerViewManager.java +0 -0
  79. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/annotation/RCTMLNPointAnnotation.java +0 -0
  80. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/annotation/RCTMLNPointAnnotationManager.java +0 -0
  81. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/camera/CameraStop.java +0 -0
  82. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/camera/CameraUpdateItem.java +0 -0
  83. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/camera/CameraUpdateQueue.java +0 -0
  84. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/camera/RCTMLNCamera.java +0 -0
  85. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/camera/RCTMLNCameraManager.java +0 -0
  86. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/camera/constants/CameraMode.java +0 -0
  87. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/images/RCTMLNImages.java +0 -0
  88. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/images/RCTMLNImagesManager.java +0 -0
  89. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/location/LocationComponentManager.java +0 -0
  90. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/location/RCTMLNNativeUserLocation.java +0 -0
  91. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/location/RCTMLNNativeUserLocationManager.java +0 -0
  92. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/mapview/LayerSourceInfo.java +0 -0
  93. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/mapview/RCTMLNAndroidTextureMapView.java +0 -0
  94. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/mapview/RCTMLNAndroidTextureMapViewManager.java +0 -0
  95. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/mapview/RCTMLNMapView.java +0 -0
  96. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/mapview/RCTMLNMapViewManager.java +0 -0
  97. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/mapview/helpers/CameraChangeTracker.java +0 -0
  98. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/RCTMLNStyle.java +0 -0
  99. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/RCTMLNStyleFactory.java +0 -0
  100. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/RCTMLNStyleFunctionParser.java +0 -0
  101. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/RCTMLNStyleValue.java +0 -0
  102. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/layers/RCTLayer.java +0 -0
  103. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/layers/RCTMLNBackgroundLayer.java +0 -0
  104. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/layers/RCTMLNBackgroundLayerManager.java +0 -0
  105. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/layers/RCTMLNCircleLayer.java +0 -0
  106. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/layers/RCTMLNCircleLayerManager.java +0 -0
  107. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/layers/RCTMLNFillExtrusionLayer.java +0 -0
  108. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/layers/RCTMLNFillExtrusionLayerManager.java +0 -0
  109. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/layers/RCTMLNFillLayer.java +0 -0
  110. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/layers/RCTMLNFillLayerManager.java +0 -0
  111. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/layers/RCTMLNHeatmapLayer.java +0 -0
  112. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/layers/RCTMLNHeatmapLayerManager.java +0 -0
  113. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/layers/RCTMLNLineLayer.java +0 -0
  114. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/layers/RCTMLNLineLayerManager.java +0 -0
  115. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/layers/RCTMLNRasterLayer.java +0 -0
  116. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/layers/RCTMLNRasterLayerManager.java +0 -0
  117. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/layers/RCTMLNSymbolLayer.java +0 -0
  118. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/layers/RCTMLNSymbolLayerManager.java +0 -0
  119. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/light/RCTMLNLight.java +0 -0
  120. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/light/RCTMLNLightManager.java +0 -0
  121. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/sources/RCTMLNImageSource.java +0 -0
  122. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/sources/RCTMLNImageSourceManager.java +0 -0
  123. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/sources/RCTMLNRasterSource.java +0 -0
  124. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/sources/RCTMLNRasterSourceManager.java +0 -0
  125. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/sources/RCTMLNShapeSource.java +0 -0
  126. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/sources/RCTMLNShapeSourceManager.java +0 -0
  127. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/sources/RCTMLNTileSource.java +0 -0
  128. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/sources/RCTMLNTileSourceManager.java +0 -0
  129. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/sources/RCTMLNVectorSource.java +0 -0
  130. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/sources/RCTMLNVectorSourceManager.java +0 -0
  131. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/components/styles/sources/RCTSource.java +0 -0
  132. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/events/AbstractEvent.java +0 -0
  133. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/events/AndroidCallbackEvent.java +0 -0
  134. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/events/EventEmitter.java +0 -0
  135. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/events/FeatureClickEvent.java +0 -0
  136. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/events/IEvent.java +0 -0
  137. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/events/ImageMissingEvent.java +0 -0
  138. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/events/LocationEvent.java +0 -0
  139. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/events/MapChangeEvent.java +0 -0
  140. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/events/MapClickEvent.java +0 -0
  141. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/events/MapUserTrackingModeEvent.java +0 -0
  142. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/events/OfflineEvent.java +0 -0
  143. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/events/PointAnnotationClickEvent.java +0 -0
  144. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/events/PointAnnotationDragEvent.java +0 -0
  145. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/events/constants/EventKeys.java +0 -0
  146. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/events/constants/EventTypes.java +0 -0
  147. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/http/CustomHeadersInterceptor.java +0 -0
  148. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/location/LocationManager.java +0 -0
  149. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/location/UserLocation.java +0 -0
  150. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/location/UserLocationVerticalAlignment.java +0 -0
  151. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/location/UserTrackingMode.java +0 -0
  152. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/location/UserTrackingState.java +0 -0
  153. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/modules/RCTMLNLocationModule.java +0 -0
  154. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/modules/RCTMLNLogging.java +0 -0
  155. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/modules/RCTMLNModule.java +0 -0
  156. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/modules/RCTMLNOfflineModule.java +0 -0
  157. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/modules/RCTMLNSnapshotModule.java +0 -0
  158. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/utils/BitmapUtils.java +0 -0
  159. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/utils/ClusterPropertyEntry.java +0 -0
  160. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/utils/ConvertUtils.java +0 -0
  161. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/utils/DownloadMapImageTask.java +0 -0
  162. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/utils/ExpressionParser.java +0 -0
  163. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/utils/GeoJSONUtils.java +0 -0
  164. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/utils/GeoViewport.java +0 -0
  165. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/utils/ImageEntry.java +0 -0
  166. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/utils/ResourceUtils.java +0 -0
  167. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/utils/SimpleEventCallback.java +0 -0
  168. /package/android/{rctmln/src → src}/main/java/com/maplibre/rctmln/utils/SphericalMercator.java +0 -0
  169. /package/android/{rctmln/src → src}/main/res/drawable/empty.xml +0 -0
  170. /package/android/{rctmln/src → src}/main/res/drawable/empty_drawable.png +0 -0
  171. /package/android/{rctmln/src → src}/main/res/drawable-xxhdpi/red_marker.png +0 -0
  172. /package/android/{rctmln/src → src}/main/res/layout/annotation.xml +0 -0
  173. /package/android/{rctmln/src → src}/main/res/values/strings.xml +0 -0
@@ -1,21 +1,14 @@
1
1
  import { point } from "@turf/helpers";
2
- import React, {
3
- memo,
4
- RefObject,
5
- useCallback,
6
- useEffect,
7
- useImperativeHandle,
8
- useMemo,
9
- useRef,
10
- } from "react";
11
- import { NativeModules, requireNativeComponent, ViewProps } from "react-native";
2
+ import React, { forwardRef, memo, useImperativeHandle, useMemo } from "react";
3
+ import { requireNativeComponent, ViewProps } from "react-native";
12
4
 
5
+ import { CameraModes } from "../MLNModule";
13
6
  import { useNativeRef } from "../hooks/useNativeRef";
14
7
  import { MaplibreGLEvent } from "../types";
8
+ import BaseProps from "../types/BaseProps";
9
+ import { CameraMode } from "../types/CameraMode";
15
10
  import { makeNativeBounds } from "../utils/makeNativeBounds";
16
11
 
17
- const MapLibreGL = NativeModules.MLNModule;
18
-
19
12
  export const NATIVE_MODULE_NAME = "RCTMLNCamera";
20
13
 
21
14
  export enum UserTrackingMode {
@@ -34,32 +27,91 @@ export type UserTrackingModeChangeCallback = (
34
27
  >,
35
28
  ) => void;
36
29
 
30
+ export function getNativeCameraMode(mode?: CameraAnimationMode): CameraMode {
31
+ switch (mode) {
32
+ case "flyTo":
33
+ return CameraModes.Flight;
34
+ case "moveTo":
35
+ return CameraModes.None;
36
+ case "linearTo":
37
+ return CameraModes.Linear;
38
+ case "easeTo":
39
+ return CameraModes.Ease;
40
+ default:
41
+ return CameraModes.None;
42
+ }
43
+ }
44
+
45
+ function makeNativeCameraStop(stop?: CameraStop): NativeCameraStop | undefined {
46
+ if (!stop) {
47
+ return undefined;
48
+ }
49
+
50
+ const nativeStop: NativeCameraStop = {};
51
+
52
+ if (stop.animationDuration !== undefined) {
53
+ nativeStop.duration = stop.animationDuration;
54
+ }
55
+ if (stop.animationMode !== undefined) {
56
+ nativeStop.mode = getNativeCameraMode(stop.animationMode);
57
+ }
58
+ if (stop.centerCoordinate) {
59
+ nativeStop.centerCoordinate = JSON.stringify(point(stop.centerCoordinate));
60
+ }
61
+ if (stop.heading !== undefined) {
62
+ nativeStop.heading = stop.heading;
63
+ }
64
+ if (stop.pitch !== undefined) {
65
+ nativeStop.pitch = stop.pitch;
66
+ }
67
+ if (stop.zoomLevel !== undefined) {
68
+ nativeStop.zoom = stop.zoomLevel;
69
+ }
70
+
71
+ if (stop.bounds && stop.bounds.ne && stop.bounds.sw) {
72
+ const { ne, sw } = stop.bounds;
73
+ nativeStop.bounds = makeNativeBounds(ne, sw);
74
+ }
75
+
76
+ const paddingTop = stop.padding?.paddingTop ?? stop.bounds?.paddingTop;
77
+ if (paddingTop !== undefined) {
78
+ nativeStop.paddingTop = paddingTop;
79
+ }
80
+
81
+ const paddingRight = stop.padding?.paddingRight ?? stop.bounds?.paddingRight;
82
+ if (paddingRight !== undefined) {
83
+ nativeStop.paddingRight = paddingRight;
84
+ }
85
+
86
+ const paddingBottom =
87
+ stop.padding?.paddingBottom ?? stop.bounds?.paddingBottom;
88
+ if (paddingBottom !== undefined) {
89
+ nativeStop.paddingBottom = paddingBottom;
90
+ }
91
+
92
+ const paddingLeft = stop.padding?.paddingLeft ?? stop.bounds?.paddingLeft;
93
+ if (paddingLeft !== undefined) {
94
+ nativeStop.paddingLeft = paddingLeft;
95
+ }
96
+
97
+ return nativeStop;
98
+ }
99
+
37
100
  export interface CameraRef {
38
101
  setCamera: (config: CameraStop | CameraStops) => void;
102
+
39
103
  fitBounds: (
40
104
  ne: GeoJSON.Position,
41
105
  sw: GeoJSON.Position,
42
106
  paddingConfig?: number | number[],
43
107
  animationDuration?: number,
44
108
  ) => void;
45
- flyTo: (
46
- centerCoordinate: GeoJSON.Position,
47
- animationDuration?: number,
48
- ) => void;
49
- moveTo: (
50
- centerCoordinate: GeoJSON.Position,
51
- animationDuration?: number,
52
- ) => void;
53
- zoomTo: (zoomLevel: number, animationDuration?: number) => void;
54
109
 
55
- _defaultCamera: RefObject<NativeCameraStop | null>;
56
- _getMaxBounds: () => string | null;
57
- _getNativeCameraMode: (config: CameraStop) => NativeAnimationMode;
58
- _createStopConfig: (
59
- config: CameraStop,
60
- ignoreFollowUserLocation?: boolean,
61
- ) => NativeCameraStop | null;
62
- _createDefaultCamera: () => NativeCameraStop | null;
110
+ flyTo: (coordinates: GeoJSON.Position, animationDuration?: number) => void;
111
+
112
+ moveTo: (coordinates: GeoJSON.Position, animationDuration?: number) => void;
113
+
114
+ zoomTo: (zoomLevel: number, animationDuration?: number) => void;
63
115
  }
64
116
 
65
117
  export interface CameraPadding {
@@ -96,14 +148,13 @@ interface CameraBoundsWithPadding
96
148
  extends CameraBounds,
97
149
  Partial<CameraPadding> {}
98
150
 
99
- type NativeAnimationMode = "flight" | "ease" | "linear" | "none" | "move";
100
151
  export type CameraAnimationMode = "flyTo" | "easeTo" | "linearTo" | "moveTo";
101
152
 
102
- export interface NativeCameraStop extends Required<CameraPadding> {
103
- mode: NativeAnimationMode;
153
+ export interface NativeCameraStop extends CameraPadding {
154
+ duration?: number;
155
+ mode?: CameraMode;
104
156
  pitch?: number;
105
157
  heading?: number;
106
- duration: number;
107
158
  zoom?: number;
108
159
  centerCoordinate?: string;
109
160
  bounds?: string;
@@ -133,24 +184,19 @@ export type CameraStops = {
133
184
  stops: CameraStop[];
134
185
  };
135
186
 
136
- interface CameraProps extends Omit<ViewProps, "style">, CameraStop {
137
- /**
138
- * If false, the camera will not send any props to the native module. Intended to be used to prevent unnecessary tile fetching and improve performance when the map is not visible. Defaults to true.
139
- */
140
- allowUpdates?: boolean;
141
-
187
+ export interface CameraProps extends BaseProps, CameraStop {
142
188
  /**
143
189
  * Default view settings applied on camera
144
190
  */
145
191
  defaultSettings?: CameraStop;
146
192
 
147
193
  /**
148
- * The minimun zoom level of the map
194
+ * Minimum zoom level of the map
149
195
  */
150
196
  minZoomLevel?: number;
151
197
 
152
198
  /**
153
- * The maximun zoom level of the map
199
+ * Maximum zoom level of the map
154
200
  */
155
201
  maxZoomLevel?: number;
156
202
 
@@ -185,39 +231,161 @@ interface CameraProps extends Omit<ViewProps, "style">, CameraStop {
185
231
  followHeading?: number;
186
232
 
187
233
  /**
188
- * Manually update the camera - helpful for when props did not update, however you still want the camera to move
234
+ * Triggered when `followUserLocation` or `followUserMode` changes
189
235
  */
190
- triggerKey?: string | number;
191
-
192
- // Triggered when the
193
236
  onUserTrackingModeChange?: UserTrackingModeChangeCallback;
194
237
  }
195
238
 
196
- interface NativeProps extends Omit<CameraProps, "maxBounds"> {
197
- maxBounds: string | null;
198
- stop: NativeCameraStop | null;
199
- defaultStop: NativeCameraStop | null;
239
+ export interface NativeCameraProps
240
+ extends Omit<CameraProps, "maxBounds">,
241
+ ViewProps {
242
+ maxBounds?: string;
243
+ stop?: NativeCameraStop;
244
+ defaultStop?: NativeCameraStop;
200
245
  }
201
246
 
202
247
  const Camera = memo(
203
- React.forwardRef<CameraRef, CameraProps>(
248
+ forwardRef<CameraRef, CameraProps>(
204
249
  (
205
250
  {
206
- allowUpdates = true,
207
- animationMode = "easeTo",
208
- animationDuration = 2000,
209
- ...rest
251
+ animationMode,
252
+ animationDuration,
253
+ bounds,
254
+ centerCoordinate,
255
+ defaultSettings,
256
+ followUserLocation,
257
+ followHeading,
258
+ followPitch,
259
+ followUserMode,
260
+ followZoomLevel,
261
+ heading,
262
+ maxBounds,
263
+ maxZoomLevel,
264
+ minZoomLevel,
265
+ onUserTrackingModeChange,
266
+ padding,
267
+ pitch,
268
+ zoomLevel,
210
269
  }: CameraProps,
211
270
  ref,
212
271
  ) => {
213
- const props = useMemo(() => {
214
- return {
215
- allowUpdates,
272
+ const nativeCamera = useNativeRef<NativeCameraProps>();
273
+
274
+ const nativeStop = useMemo(() => {
275
+ return makeNativeCameraStop({
276
+ animationDuration,
216
277
  animationMode,
278
+ bounds,
279
+ centerCoordinate,
280
+ heading,
281
+ padding,
282
+ pitch,
283
+ zoomLevel,
284
+ });
285
+ }, [
286
+ animationDuration,
287
+ animationMode,
288
+ bounds,
289
+ centerCoordinate,
290
+ heading,
291
+ padding,
292
+ pitch,
293
+ zoomLevel,
294
+ ]);
295
+
296
+ const nativeDefaultStop = useMemo(() => {
297
+ return makeNativeCameraStop(defaultSettings);
298
+ }, [defaultSettings]);
299
+
300
+ const nativeMaxBounds = useMemo(() => {
301
+ if (!maxBounds?.ne || !maxBounds?.sw) {
302
+ return undefined;
303
+ }
304
+ return makeNativeBounds(maxBounds.ne, maxBounds.sw);
305
+ }, [maxBounds]);
306
+
307
+ const setCamera = (config: CameraStop | CameraStops = {}): void => {
308
+ if ("stops" in config) {
309
+ nativeCamera.current?.setNativeProps({
310
+ stop: {
311
+ stops: config.stops
312
+ .map((stopItem) => makeNativeCameraStop(stopItem))
313
+ .filter((stopItem) => !!stopItem),
314
+ },
315
+ });
316
+ } else {
317
+ const nativeStop = makeNativeCameraStop(config);
318
+
319
+ if (nativeStop) {
320
+ nativeCamera.current?.setNativeProps({ stop: nativeStop });
321
+ }
322
+ }
323
+ };
324
+
325
+ const fitBounds = (
326
+ ne: GeoJSON.Position,
327
+ sw: GeoJSON.Position,
328
+ padding?: number | number[],
329
+ animationDuration?: number,
330
+ ): void => {
331
+ const _padding: CameraPadding = {};
332
+
333
+ if (Array.isArray(padding)) {
334
+ if (padding.length === 2) {
335
+ _padding.paddingTop = padding[0];
336
+ _padding.paddingBottom = padding[0];
337
+ _padding.paddingLeft = padding[1];
338
+ _padding.paddingRight = padding[1];
339
+ } else if (padding.length === 4) {
340
+ _padding.paddingTop = padding[0];
341
+ _padding.paddingRight = padding[1];
342
+ _padding.paddingBottom = padding[2];
343
+ _padding.paddingLeft = padding[3];
344
+ }
345
+ } else if (typeof padding === "number") {
346
+ _padding.paddingLeft = padding;
347
+ _padding.paddingRight = padding;
348
+ _padding.paddingTop = padding;
349
+ _padding.paddingBottom = padding;
350
+ }
351
+
352
+ setCamera({
353
+ bounds: { ne, sw },
354
+ padding: _padding,
217
355
  animationDuration,
218
- ...rest,
219
- };
220
- }, [allowUpdates, animationMode, animationDuration, rest]);
356
+ animationMode: "easeTo",
357
+ });
358
+ };
359
+
360
+ const flyTo = (
361
+ coordinates: GeoJSON.Position,
362
+ animationDuration = 2000,
363
+ ): void => {
364
+ setCamera({
365
+ centerCoordinate: coordinates,
366
+ animationDuration,
367
+ animationMode: "flyTo",
368
+ });
369
+ };
370
+
371
+ const moveTo = (
372
+ coordinates: GeoJSON.Position,
373
+ animationDuration = 0,
374
+ ): void => {
375
+ setCamera({
376
+ centerCoordinate: coordinates,
377
+ animationDuration,
378
+ animationMode: "easeTo",
379
+ });
380
+ };
381
+
382
+ const zoomTo = (zoomLevel: number, animationDuration = 2000): void => {
383
+ setCamera({
384
+ zoomLevel,
385
+ animationDuration,
386
+ animationMode: "flyTo",
387
+ });
388
+ };
221
389
 
222
390
  useImperativeHandle(
223
391
  ref,
@@ -226,13 +394,13 @@ const Camera = memo(
226
394
  * Map camera transitions to fit provided bounds
227
395
  *
228
396
  * @example
229
- * this.camera.fitBounds([lng, lat], [lng, lat])
230
- * this.camera.fitBounds([lng, lat], [lng, lat], 20, 1000) // padding for all sides
231
- * this.camera.fitBounds([lng, lat], [lng, lat], [verticalPadding, horizontalPadding], 1000)
232
- * this.camera.fitBounds([lng, lat], [lng, lat], [top, right, bottom, left], 1000)
397
+ * cameraRef.current?.fitBounds([lng, lat], [lng, lat])
398
+ * cameraRef.current?.fitBounds([lng, lat], [lng, lat], 20, 1000) // padding for all sides
399
+ * cameraRef.current?.fitBounds([lng, lat], [lng, lat], [verticalPadding, horizontalPadding], 1000)
400
+ * cameraRef.current?.fitBounds([lng, lat], [lng, lat], [top, right, bottom, left], 1000)
233
401
  *
234
- * @param {Array<Number>} northEastCoordinates - North east coordinate of bound
235
- * @param {Array<Number>} southWestCoordinates - South west coordinate of bound
402
+ * @param {Array<Number>} ne - North east coordinate of bound
403
+ * @param {Array<Number>} sw - South west coordinate of bound
236
404
  * @param {Number|Array<Number>|undefined} padding - Padding for the bounds
237
405
  * @param {Number=} animationDuration - Duration of camera animation
238
406
  * @return {void}
@@ -242,10 +410,10 @@ const Camera = memo(
242
410
  * Map camera will fly to new coordinate
243
411
  *
244
412
  * @example
245
- * this.camera.flyTo([lng, lat])
246
- * this.camera.flyTo([lng, lat], 12000)
413
+ * cameraRef.current?.flyTo([lng, lat])
414
+ * cameraRef.current?.flyTo([lng, lat], 12000)
247
415
  *
248
- * @param {Array<Number>} coordinates - Coordinates that map camera will jump too
416
+ * @param {Array<Number>} coordinates - Coordinates that map camera will jump to
249
417
  * @param {Number=} animationDuration - Duration of camera animation
250
418
  * @return {void}
251
419
  */
@@ -254,8 +422,8 @@ const Camera = memo(
254
422
  * Map camera will move to new coordinate at the same zoom level
255
423
  *
256
424
  * @example
257
- * this.camera.moveTo([lng, lat], 200) // eases camera to new location based on duration
258
- * this.camera.moveTo([lng, lat]) // snaps camera to new location without any easing
425
+ * cameraRef.current?.moveTo([lng, lat], 200) // eases camera to new location based on duration
426
+ * cameraRef.current?.moveTo([lng, lat]) // snaps camera to new location without any easing
259
427
  *
260
428
  * @param {Array<Number>} coordinates - Coordinates that map camera will move too
261
429
  * @param {Number=} animationDuration - Duration of camera animation
@@ -266,8 +434,8 @@ const Camera = memo(
266
434
  * Map camera will zoom to specified level
267
435
  *
268
436
  * @example
269
- * this.camera.zoomTo(16)
270
- * this.camera.zoomTo(16, 100)
437
+ * cameraRef.current?.zoomTo(16)
438
+ * cameraRef.current?.zoomTo(16, 100)
271
439
  *
272
440
  * @param {Number} zoomLevel - Zoom level that the map camera will animate too
273
441
  * @param {Number=} animationDuration - Duration of camera animation
@@ -278,13 +446,13 @@ const Camera = memo(
278
446
  * Map camera will perform updates based on provided config. Advanced use only!
279
447
  *
280
448
  * @example
281
- * this.camera.setCamera({
449
+ * cameraRef.current?.setCamera({
282
450
  * centerCoordinate: [lng, lat],
283
451
  * zoomLevel: 16,
284
452
  * animationDuration: 2000,
285
453
  * })
286
454
  *
287
- * this.camera.setCamera({
455
+ * cameraRef.current?.setCamera({
288
456
  * stops: [
289
457
  * { pitch: 45, animationDuration: 200 },
290
458
  * { heading: 180, animationDuration: 300 },
@@ -294,330 +462,31 @@ const Camera = memo(
294
462
  * @param {Object} config - Camera configuration
295
463
  */
296
464
  setCamera,
297
- _defaultCamera,
298
- _getMaxBounds,
299
- _getNativeCameraMode,
300
- _createStopConfig,
301
- _createDefaultCamera,
302
465
  }),
303
466
  );
304
467
 
305
- const _defaultCamera = useRef<NativeCameraStop | null>(null);
306
-
307
- const cameraRef = useNativeRef<NativeProps>();
308
-
309
- const _createStopConfig = useCallback(
310
- (
311
- config: CameraStop = {},
312
- ignoreFollowUserLocation = false,
313
- ): NativeCameraStop | null => {
314
- if (props.followUserLocation && !ignoreFollowUserLocation) {
315
- return null;
316
- }
317
-
318
- const stopConfig: NativeCameraStop = {
319
- mode: _getNativeCameraMode(config),
320
- pitch: config.pitch,
321
- heading: config.heading,
322
- duration: config.animationDuration || 0,
323
- zoom: config.zoomLevel,
324
- paddingTop:
325
- config.padding?.paddingTop || config.bounds?.paddingTop || 0,
326
- paddingRight:
327
- config.padding?.paddingRight || config.bounds?.paddingRight || 0,
328
- paddingBottom:
329
- config.padding?.paddingBottom ||
330
- config.bounds?.paddingBottom ||
331
- 0,
332
- paddingLeft:
333
- config.padding?.paddingLeft || config.bounds?.paddingLeft || 0,
334
- };
335
-
336
- if (config.centerCoordinate) {
337
- stopConfig.centerCoordinate = JSON.stringify(
338
- point(config.centerCoordinate),
339
- );
340
- }
341
-
342
- if (config.bounds && config.bounds.ne && config.bounds.sw) {
343
- const { ne, sw } = config.bounds;
344
- stopConfig.bounds = makeNativeBounds(ne, sw);
345
- }
346
-
347
- return stopConfig;
348
- },
349
- [props.followUserLocation],
350
- );
351
-
352
- const _setCamera = useCallback(
353
- (config: CameraStop | CameraStops = {}): void => {
354
- if ("stops" in config) {
355
- let nativeStops: NativeCameraStop[] = [];
356
-
357
- for (const stop of config.stops) {
358
- const nativeStop = _createStopConfig(stop);
359
- if (nativeStop) {
360
- nativeStops = [...nativeStops, nativeStop];
361
- }
362
- }
363
- cameraRef.current?.setNativeProps({ stop: { stops: nativeStops } });
364
- } else {
365
- const nativeStop = _createStopConfig(config);
366
-
367
- if (nativeStop) {
368
- cameraRef.current?.setNativeProps({ stop: nativeStop });
369
- }
370
- }
371
- },
372
- [cameraRef.current, _createStopConfig],
373
- );
374
-
375
- const _getMaxBounds = useCallback((): string | null => {
376
- const bounds = props.maxBounds;
377
- if (!bounds || !bounds.ne || !bounds.sw) {
378
- return null;
379
- }
380
- return makeNativeBounds(bounds.ne, bounds.sw);
381
- }, [props.maxBounds]);
382
-
383
- useEffect(() => {
384
- if (!props.allowUpdates) {
385
- return;
386
- }
387
-
388
- cameraRef.current?.setNativeProps({
389
- followUserLocation: props.followUserLocation,
390
- });
391
- }, [cameraRef.current, props.followUserLocation]);
392
-
393
- useEffect(() => {
394
- if (!props.maxBounds || !props.allowUpdates) {
395
- return;
396
- }
397
-
398
- cameraRef.current?.setNativeProps({
399
- maxBounds: _getMaxBounds(),
400
- });
401
- }, [cameraRef.current, props.maxBounds, _getMaxBounds]);
402
-
403
- useEffect(() => {
404
- if (!props.minZoomLevel || !props.allowUpdates) {
405
- return;
406
- }
407
-
408
- cameraRef.current?.setNativeProps({
409
- minZoomLevel: props.minZoomLevel,
410
- });
411
- }, [cameraRef.current, props.minZoomLevel]);
412
-
413
- useEffect(() => {
414
- if (!props.maxZoomLevel || !props.allowUpdates) {
415
- return;
416
- }
417
-
418
- cameraRef.current?.setNativeProps({
419
- maxZoomLevel: props.maxZoomLevel,
420
- });
421
- }, [cameraRef.current, props.maxZoomLevel]);
422
-
423
- useEffect(() => {
424
- if (!props.allowUpdates) {
425
- return;
426
- }
427
-
428
- if (!props.followUserLocation) {
429
- return;
430
- }
431
-
432
- cameraRef.current?.setNativeProps({
433
- followUserMode: props.followUserMode,
434
- followPitch: props.followPitch || props.pitch,
435
- followHeading: props.followHeading || props.heading,
436
- followZoomLevel: props.followZoomLevel || props.zoomLevel,
437
- });
438
- }, [
439
- cameraRef.current,
440
- props.allowUpdates,
441
- props.followUserLocation,
442
- props.followUserMode,
443
- props.followPitch,
444
- props.pitch,
445
- props.followHeading,
446
- props.heading,
447
- props.followZoomLevel,
448
- props.zoomLevel,
449
- ]);
450
-
451
- const cameraConfig: CameraStop = useMemo(() => {
452
- return {
453
- bounds: props.bounds,
454
- centerCoordinate: props.centerCoordinate,
455
- padding: props.padding,
456
- zoomLevel: props.zoomLevel,
457
- minZoomLevel: props.minZoomLevel,
458
- maxZoomLevel: props.maxZoomLevel,
459
- pitch: props.pitch,
460
- heading: props.heading,
461
- animationMode: props.animationMode,
462
- animationDuration: props.animationDuration,
463
- };
464
- }, [
465
- props.bounds,
466
- props.centerCoordinate,
467
- props.padding,
468
- props.zoomLevel,
469
- props.minZoomLevel,
470
- props.maxZoomLevel,
471
- props.pitch,
472
- props.heading,
473
- props.animationMode,
474
- props.animationDuration,
475
- ]);
476
-
477
- useEffect(() => {
478
- if (!props.allowUpdates) {
479
- return;
480
- }
481
-
482
- _setCamera(cameraConfig);
483
- }, [_setCamera, cameraConfig]);
484
-
485
- const fitBounds = (
486
- northEastCoordinates: GeoJSON.Position,
487
- southWestCoordinates: GeoJSON.Position,
488
- padding: number | number[] = 0,
489
- animationDuration: number = 0.0,
490
- ): void => {
491
- const pad = {
492
- paddingLeft: 0,
493
- paddingRight: 0,
494
- paddingTop: 0,
495
- paddingBottom: 0,
496
- };
497
-
498
- if (Array.isArray(padding)) {
499
- if (padding.length === 2) {
500
- pad.paddingTop = padding[0];
501
- pad.paddingBottom = padding[0];
502
- pad.paddingLeft = padding[1];
503
- pad.paddingRight = padding[1];
504
- } else if (padding.length === 4) {
505
- pad.paddingTop = padding[0];
506
- pad.paddingRight = padding[1];
507
- pad.paddingBottom = padding[2];
508
- pad.paddingLeft = padding[3];
509
- }
510
- } else {
511
- pad.paddingLeft = padding;
512
- pad.paddingRight = padding;
513
- pad.paddingTop = padding;
514
- pad.paddingBottom = padding;
515
- }
516
-
517
- setCamera({
518
- bounds: {
519
- ne: northEastCoordinates,
520
- sw: southWestCoordinates,
521
- },
522
- padding: pad,
523
- animationDuration,
524
- animationMode: "easeTo",
525
- });
526
- };
527
-
528
- const flyTo = (
529
- coordinates: GeoJSON.Position,
530
- animationDuration = 2000,
531
- ): void => {
532
- setCamera({
533
- centerCoordinate: coordinates,
534
- animationDuration,
535
- animationMode: "flyTo",
536
- });
537
- };
538
-
539
- const moveTo = (
540
- coordinates: GeoJSON.Position,
541
- animationDuration = 0,
542
- ): void => {
543
- setCamera({
544
- centerCoordinate: coordinates,
545
- animationDuration,
546
- });
547
- };
548
-
549
- const zoomTo = (zoomLevel: number, animationDuration = 2000): void => {
550
- setCamera({
551
- zoomLevel,
552
- animationDuration,
553
- animationMode: "flyTo",
554
- });
555
- };
556
-
557
- const setCamera = (config: CameraStop | CameraStops = {}): void => {
558
- _setCamera(config);
559
- };
560
-
561
- const _createDefaultCamera = (): NativeCameraStop | null => {
562
- if (_defaultCamera.current) {
563
- return _defaultCamera.current;
564
- }
565
- if (!props.defaultSettings) {
566
- return null;
567
- }
568
-
569
- _defaultCamera.current = _createStopConfig(
570
- {
571
- ...props.defaultSettings,
572
- animationMode: "moveTo",
573
- },
574
- true,
575
- );
576
- return _defaultCamera.current;
577
- };
578
-
579
- const _getNativeCameraMode = (
580
- config: CameraStop,
581
- ): NativeAnimationMode => {
582
- switch (config.animationMode) {
583
- case "flyTo":
584
- return MapLibreGL.CameraModes.Flight;
585
- case "moveTo":
586
- return MapLibreGL.CameraModes.None;
587
- case "linearTo":
588
- return MapLibreGL.CameraModes.Linear;
589
- default:
590
- return MapLibreGL.CameraModes.Ease;
591
- }
592
- };
593
-
594
- const nativeProps = Object.assign({}, props);
595
-
596
- const callbacks = {
597
- onUserTrackingModeChange: nativeProps.onUserTrackingModeChange,
598
- };
599
-
600
468
  return (
601
469
  <RCTMLNCamera
602
470
  testID="Camera"
603
- ref={cameraRef}
604
- followUserLocation={props.followUserLocation}
605
- followUserMode={props.followUserMode}
606
- followPitch={props.followPitch}
607
- followHeading={props.followHeading}
608
- followZoomLevel={props.followZoomLevel}
609
- stop={_createStopConfig(nativeProps)}
610
- maxZoomLevel={props.maxZoomLevel}
611
- minZoomLevel={props.minZoomLevel}
612
- maxBounds={_getMaxBounds()}
613
- defaultStop={_createDefaultCamera()}
614
- {...callbacks}
471
+ ref={nativeCamera}
472
+ stop={nativeStop}
473
+ defaultStop={nativeDefaultStop}
474
+ maxBounds={nativeMaxBounds}
475
+ followUserLocation={followUserLocation}
476
+ followHeading={followHeading}
477
+ followPitch={followPitch}
478
+ followUserMode={followUserMode}
479
+ followZoomLevel={followZoomLevel}
480
+ maxZoomLevel={maxZoomLevel}
481
+ minZoomLevel={minZoomLevel}
482
+ onUserTrackingModeChange={onUserTrackingModeChange}
615
483
  />
616
484
  );
617
485
  },
618
486
  ),
619
487
  );
620
488
 
621
- const RCTMLNCamera = requireNativeComponent<NativeProps>(NATIVE_MODULE_NAME);
489
+ const RCTMLNCamera =
490
+ requireNativeComponent<NativeCameraProps>(NATIVE_MODULE_NAME);
622
491
 
623
492
  export default Camera;