@maydon_tech/react-native-nitro-maps 0.1.3 → 0.2.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 (218) hide show
  1. package/LICENSE +1 -1
  2. package/NitroMap.podspec +1 -1
  3. package/README.md +82 -9
  4. package/android/CMakeLists.txt +4 -1
  5. package/android/gradle.properties +4 -4
  6. package/android/src/main/cpp/ClusterEngineJNI.cpp +198 -0
  7. package/android/src/main/kotlin/com/margelo/nitro/nitromap/NitroMap.kt +397 -0
  8. package/android/src/main/kotlin/com/margelo/nitro/nitromap/NitroMapConfig.kt +53 -0
  9. package/android/src/main/{java → kotlin}/com/margelo/nitro/nitromap/NitroMapPackage.kt +4 -4
  10. package/android/src/main/kotlin/com/margelo/nitro/nitromap/NitroMapView.kt +73 -0
  11. package/android/src/main/kotlin/com/margelo/nitro/nitromap/UserLocationManager.kt +295 -0
  12. package/android/src/main/kotlin/com/margelo/nitro/nitromap/clustering/ClusterIconRenderer.kt +111 -0
  13. package/android/src/main/kotlin/com/margelo/nitro/nitromap/clustering/ClusteringManager.kt +104 -0
  14. package/android/src/main/kotlin/com/margelo/nitro/nitromap/clustering/NitroClusterEngine.kt +166 -0
  15. package/android/src/main/kotlin/com/margelo/nitro/nitromap/markers/MarkerIconFactory.kt +303 -0
  16. package/android/src/main/kotlin/com/margelo/nitro/nitromap/markers/MarkerSelectionHandler.kt +72 -0
  17. package/android/src/main/kotlin/com/margelo/nitro/nitromap/markers/PriceMarkerRenderer.kt +159 -0
  18. package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/MapProviderFactory.kt +24 -0
  19. package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/MapProviderInterface.kt +128 -0
  20. package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/GoogleMapDelegate.kt +317 -0
  21. package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/GoogleMapProvider+Clustering.kt +524 -0
  22. package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/GoogleMapProvider+Markers.kt +358 -0
  23. package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/GoogleMapProvider+Overlays.kt +272 -0
  24. package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/GoogleMapProvider+UserLocation.kt +296 -0
  25. package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/GoogleMapProvider.kt +815 -0
  26. package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/MarkerTagData.kt +19 -0
  27. package/ios/Clustering/ClusterIconRenderer.swift +3 -3
  28. package/ios/Location/NitroLocationManager.swift +116 -0
  29. package/ios/MarkerRenderer/MarkerIconFactory.swift +1 -3
  30. package/ios/MarkerRenderer/PriceMarkerRenderer.swift +10 -6
  31. package/ios/NitroMap.swift +279 -13
  32. package/ios/NitroMapConfig/NitroMapConfig.swift +45 -0
  33. package/ios/Providers/{GoogleMapDelegate.swift → Google/GoogleMapDelegate.swift} +48 -23
  34. package/ios/Providers/Google/GoogleMapProvider+Camera.swift +180 -0
  35. package/ios/Providers/Google/GoogleMapProvider+Clustering.swift +541 -0
  36. package/ios/Providers/Google/GoogleMapProvider+Markers.swift +270 -0
  37. package/ios/Providers/Google/GoogleMapProvider+Overlays.swift +245 -0
  38. package/ios/Providers/Google/GoogleMapProvider+UserLocation.swift +180 -0
  39. package/ios/Providers/Google/GoogleMapProvider.swift +342 -0
  40. package/ios/Providers/MapProviderFactory.swift +17 -0
  41. package/ios/Providers/MapProviderProtocol.swift +48 -1
  42. package/ios/Shared/ClusterConfig+Factory.swift +2 -2
  43. package/ios/Shared/MapStyleProvider.swift +6 -4
  44. package/ios/Shared/MarkerSelectionHandler.swift +4 -1
  45. package/ios/Utils/ColorValueExtension.swift +46 -67
  46. package/lib/module/components/ImageMarker.js +39 -29
  47. package/lib/module/components/ImageMarker.js.map +1 -1
  48. package/lib/module/components/Marker.js +118 -0
  49. package/lib/module/components/Marker.js.map +1 -0
  50. package/lib/module/components/NitroCircle.js +92 -0
  51. package/lib/module/components/NitroCircle.js.map +1 -0
  52. package/lib/module/components/NitroMap.js +216 -76
  53. package/lib/module/components/NitroMap.js.map +1 -1
  54. package/lib/module/components/NitroPolygon.js +135 -0
  55. package/lib/module/components/NitroPolygon.js.map +1 -0
  56. package/lib/module/components/NitroPolyline.js +115 -0
  57. package/lib/module/components/NitroPolyline.js.map +1 -0
  58. package/lib/module/components/PriceMarker.js +16 -29
  59. package/lib/module/components/PriceMarker.js.map +1 -1
  60. package/lib/module/context/NitroMapContext.js.map +1 -1
  61. package/lib/module/hooks/useNitroCircle.js +18 -0
  62. package/lib/module/hooks/useNitroCircle.js.map +1 -0
  63. package/lib/module/hooks/useNitroMarker.js +26 -9
  64. package/lib/module/hooks/useNitroMarker.js.map +1 -1
  65. package/lib/module/hooks/useNitroOverlay.js +59 -0
  66. package/lib/module/hooks/useNitroOverlay.js.map +1 -0
  67. package/lib/module/hooks/useNitroPolygon.js +18 -0
  68. package/lib/module/hooks/useNitroPolygon.js.map +1 -0
  69. package/lib/module/hooks/useNitroPolyline.js +18 -0
  70. package/lib/module/hooks/useNitroPolyline.js.map +1 -0
  71. package/lib/module/index.js +5 -0
  72. package/lib/module/index.js.map +1 -1
  73. package/lib/module/types/overlay.js +4 -0
  74. package/lib/module/types/overlay.js.map +1 -0
  75. package/lib/module/types/theme.js +4 -0
  76. package/lib/module/types/theme.js.map +1 -0
  77. package/lib/module/utils/colors.js +41 -13
  78. package/lib/module/utils/colors.js.map +1 -1
  79. package/lib/module/utils/validation.js +45 -0
  80. package/lib/module/utils/validation.js.map +1 -0
  81. package/lib/typescript/src/components/ImageMarker.d.ts.map +1 -1
  82. package/lib/typescript/src/components/Marker.d.ts +34 -0
  83. package/lib/typescript/src/components/Marker.d.ts.map +1 -0
  84. package/lib/typescript/src/components/NitroCircle.d.ts +70 -0
  85. package/lib/typescript/src/components/NitroCircle.d.ts.map +1 -0
  86. package/lib/typescript/src/components/NitroMap.d.ts +60 -3
  87. package/lib/typescript/src/components/NitroMap.d.ts.map +1 -1
  88. package/lib/typescript/src/components/NitroPolygon.d.ts +86 -0
  89. package/lib/typescript/src/components/NitroPolygon.d.ts.map +1 -0
  90. package/lib/typescript/src/components/NitroPolyline.d.ts +84 -0
  91. package/lib/typescript/src/components/NitroPolyline.d.ts.map +1 -0
  92. package/lib/typescript/src/components/PriceMarker.d.ts +0 -5
  93. package/lib/typescript/src/components/PriceMarker.d.ts.map +1 -1
  94. package/lib/typescript/src/context/NitroMapContext.d.ts +2 -0
  95. package/lib/typescript/src/context/NitroMapContext.d.ts.map +1 -1
  96. package/lib/typescript/src/hooks/useNitroCircle.d.ts +7 -0
  97. package/lib/typescript/src/hooks/useNitroCircle.d.ts.map +1 -0
  98. package/lib/typescript/src/hooks/useNitroMarker.d.ts +20 -0
  99. package/lib/typescript/src/hooks/useNitroMarker.d.ts.map +1 -1
  100. package/lib/typescript/src/hooks/useNitroOverlay.d.ts +26 -0
  101. package/lib/typescript/src/hooks/useNitroOverlay.d.ts.map +1 -0
  102. package/lib/typescript/src/hooks/useNitroPolygon.d.ts +7 -0
  103. package/lib/typescript/src/hooks/useNitroPolygon.d.ts.map +1 -0
  104. package/lib/typescript/src/hooks/useNitroPolyline.d.ts +7 -0
  105. package/lib/typescript/src/hooks/useNitroPolyline.d.ts.map +1 -0
  106. package/lib/typescript/src/index.d.ts +15 -2
  107. package/lib/typescript/src/index.d.ts.map +1 -1
  108. package/lib/typescript/src/specs/NitroMap.nitro.d.ts +248 -6
  109. package/lib/typescript/src/specs/NitroMap.nitro.d.ts.map +1 -1
  110. package/lib/typescript/src/types/map.d.ts +34 -4
  111. package/lib/typescript/src/types/map.d.ts.map +1 -1
  112. package/lib/typescript/src/types/marker.d.ts +24 -36
  113. package/lib/typescript/src/types/marker.d.ts.map +1 -1
  114. package/lib/typescript/src/types/overlay.d.ts +75 -0
  115. package/lib/typescript/src/types/overlay.d.ts.map +1 -0
  116. package/lib/typescript/src/types/theme.d.ts +93 -0
  117. package/lib/typescript/src/types/theme.d.ts.map +1 -0
  118. package/lib/typescript/src/utils/colors.d.ts +6 -8
  119. package/lib/typescript/src/utils/colors.d.ts.map +1 -1
  120. package/lib/typescript/src/utils/validation.d.ts +12 -0
  121. package/lib/typescript/src/utils/validation.d.ts.map +1 -0
  122. package/nitrogen/generated/android/c++/JCircleData.hpp +94 -0
  123. package/nitrogen/generated/android/c++/JClusterConfig.hpp +5 -7
  124. package/nitrogen/generated/android/c++/JFunc_void_UserLocationChangeEvent.hpp +79 -0
  125. package/nitrogen/generated/android/c++/JFunc_void_UserTrackingMode.hpp +77 -0
  126. package/nitrogen/generated/android/c++/JFunc_void_std__string.hpp +76 -0
  127. package/nitrogen/generated/android/c++/JHybridNitroMapSpec.cpp +328 -21
  128. package/nitrogen/generated/android/c++/JHybridNitroMapSpec.hpp +53 -2
  129. package/nitrogen/generated/android/c++/JMarkerAnimation.hpp +3 -6
  130. package/nitrogen/generated/android/c++/JMarkerData.hpp +15 -3
  131. package/nitrogen/generated/android/c++/JPolygonData.hpp +149 -0
  132. package/nitrogen/generated/android/c++/JPolylineData.hpp +113 -0
  133. package/nitrogen/generated/android/c++/JUserLocationChangeEvent.hpp +70 -0
  134. package/nitrogen/generated/android/c++/JUserTrackingMode.hpp +62 -0
  135. package/nitrogen/generated/android/c++/views/JHybridNitroMapStateUpdater.cpp +72 -4
  136. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/CircleData.kt +62 -0
  137. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/ClusterConfig.kt +4 -4
  138. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/Func_void_UserLocationChangeEvent.kt +80 -0
  139. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/Func_void_UserTrackingMode.kt +80 -0
  140. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/Func_void_std__string.kt +80 -0
  141. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/HybridNitroMapSpec.kt +228 -2
  142. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/MarkerAnimation.kt +1 -2
  143. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/MarkerData.kt +12 -3
  144. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/PolygonData.kt +62 -0
  145. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/PolylineData.kt +62 -0
  146. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/UserLocationChangeEvent.kt +47 -0
  147. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/{ClusterAnimationStyle.kt → UserTrackingMode.kt} +6 -8
  148. package/nitrogen/generated/android/nitromapOnLoad.cpp +6 -0
  149. package/nitrogen/generated/ios/NitroMap-Swift-Cxx-Bridge.cpp +24 -0
  150. package/nitrogen/generated/ios/NitroMap-Swift-Cxx-Bridge.hpp +175 -17
  151. package/nitrogen/generated/ios/NitroMap-Swift-Cxx-Umbrella.hpp +15 -3
  152. package/nitrogen/generated/ios/c++/HybridNitroMapSpecSwift.hpp +249 -16
  153. package/nitrogen/generated/ios/c++/views/HybridNitroMapComponent.mm +90 -5
  154. package/nitrogen/generated/ios/swift/CircleData.swift +143 -0
  155. package/nitrogen/generated/ios/swift/ClusterConfig.swift +22 -15
  156. package/nitrogen/generated/ios/swift/Func_void_UserLocationChangeEvent.swift +47 -0
  157. package/nitrogen/generated/ios/swift/Func_void_UserTrackingMode.swift +47 -0
  158. package/nitrogen/generated/ios/swift/Func_void_std__string.swift +47 -0
  159. package/nitrogen/generated/ios/swift/HybridNitroMapSpec.swift +35 -1
  160. package/nitrogen/generated/ios/swift/HybridNitroMapSpec_cxx.swift +582 -8
  161. package/nitrogen/generated/ios/swift/MarkerAnimation.swift +4 -8
  162. package/nitrogen/generated/ios/swift/MarkerData.swift +54 -2
  163. package/nitrogen/generated/ios/swift/PolygonData.swift +179 -0
  164. package/nitrogen/generated/ios/swift/PolylineData.swift +155 -0
  165. package/nitrogen/generated/ios/swift/UserLocationChangeEvent.swift +69 -0
  166. package/nitrogen/generated/ios/swift/UserTrackingMode.swift +44 -0
  167. package/nitrogen/generated/shared/c++/CircleData.hpp +113 -0
  168. package/nitrogen/generated/shared/c++/ClusterConfig.hpp +5 -8
  169. package/nitrogen/generated/shared/c++/HybridNitroMapSpec.cpp +53 -2
  170. package/nitrogen/generated/shared/c++/HybridNitroMapSpec.hpp +75 -6
  171. package/nitrogen/generated/shared/c++/MarkerAnimation.hpp +4 -8
  172. package/nitrogen/generated/shared/c++/MarkerData.hpp +14 -2
  173. package/nitrogen/generated/shared/c++/PolygonData.hpp +114 -0
  174. package/nitrogen/generated/shared/c++/PolylineData.hpp +114 -0
  175. package/nitrogen/generated/shared/c++/UserLocationChangeEvent.hpp +88 -0
  176. package/nitrogen/generated/shared/c++/UserTrackingMode.hpp +80 -0
  177. package/nitrogen/generated/shared/c++/views/HybridNitroMapComponent.cpp +216 -12
  178. package/nitrogen/generated/shared/c++/views/HybridNitroMapComponent.hpp +23 -1
  179. package/nitrogen/generated/shared/json/NitroMapConfig.json +18 -1
  180. package/package.json +36 -5
  181. package/src/components/ImageMarker.tsx +58 -42
  182. package/src/components/Marker.tsx +161 -0
  183. package/src/components/NitroCircle.tsx +183 -0
  184. package/src/components/NitroMap.tsx +328 -78
  185. package/src/components/NitroPolygon.tsx +229 -0
  186. package/src/components/NitroPolyline.tsx +208 -0
  187. package/src/components/PriceMarker.tsx +23 -48
  188. package/src/context/NitroMapContext.tsx +4 -0
  189. package/src/hooks/useNitroCircle.ts +25 -0
  190. package/src/hooks/useNitroMarker.ts +49 -10
  191. package/src/hooks/useNitroOverlay.ts +68 -0
  192. package/src/hooks/useNitroPolygon.ts +25 -0
  193. package/src/hooks/useNitroPolyline.ts +25 -0
  194. package/src/index.tsx +23 -2
  195. package/src/specs/NitroMap.nitro.ts +294 -5
  196. package/src/types/map.ts +36 -4
  197. package/src/types/marker.ts +24 -44
  198. package/src/types/overlay.ts +77 -0
  199. package/src/types/theme.ts +101 -0
  200. package/src/utils/colors.ts +48 -16
  201. package/src/utils/validation.ts +69 -0
  202. package/android/src/main/java/com/margelo/nitro/nitromap/ClusterIconGenerator.kt +0 -108
  203. package/android/src/main/java/com/margelo/nitro/nitromap/ColorUtils.kt +0 -63
  204. package/android/src/main/java/com/margelo/nitro/nitromap/HybridNitroMap.kt +0 -408
  205. package/android/src/main/java/com/margelo/nitro/nitromap/HybridNitroMapConfig.kt +0 -68
  206. package/android/src/main/java/com/margelo/nitro/nitromap/MarkerIconCache.kt +0 -176
  207. package/android/src/main/java/com/margelo/nitro/nitromap/MarkerIconFactory.kt +0 -252
  208. package/android/src/main/java/com/margelo/nitro/nitromap/clustering/NitroClusterEngine.kt +0 -252
  209. package/android/src/main/java/com/margelo/nitro/nitromap/clustering/QuadTree.kt +0 -195
  210. package/android/src/main/java/com/margelo/nitro/nitromap/providers/GoogleMapProvider.kt +0 -912
  211. package/android/src/main/java/com/margelo/nitro/nitromap/providers/MapProviderInterface.kt +0 -70
  212. package/cpp/QuadTree.hpp +0 -246
  213. package/ios/NitroMapConfig/HybridNitroMapConfig.swift +0 -33
  214. package/ios/Providers/GoogleMapProvider+Camera.swift +0 -164
  215. package/ios/Providers/GoogleMapProvider.swift +0 -924
  216. package/nitrogen/generated/android/c++/JClusterAnimationStyle.hpp +0 -68
  217. package/nitrogen/generated/ios/swift/ClusterAnimationStyle.swift +0 -52
  218. package/nitrogen/generated/shared/c++/ClusterAnimationStyle.hpp +0 -88
@@ -1,11 +1,12 @@
1
1
  // src/hooks/useNitroMarker.ts
2
- import { useContext, useEffect, useRef, useCallback } from 'react';
2
+ import { useContext, useEffect, useRef, useMemo } from 'react';
3
3
  import {
4
4
  NitroMapContext,
5
5
  type MarkerHandlers,
6
6
  } from '../context/NitroMapContext';
7
7
  import type { MarkerConfig, MarkerAnimation } from '../types/marker';
8
8
  import type { Coordinate, Point } from '../types/map';
9
+ import { validateCoordinate } from '../utils/validation';
9
10
 
10
11
  /**
11
12
  * Base marker data structure for internal use
@@ -22,7 +23,10 @@ export interface BaseMarkerData {
22
23
  anchor: Point;
23
24
  clusteringEnabled: boolean;
24
25
  config: MarkerConfig;
26
+ accessibilityLabel?: string;
25
27
  animation: MarkerAnimation;
28
+ animationDuration: number;
29
+ animateOnReappear: boolean;
26
30
  }
27
31
 
28
32
  /**
@@ -59,9 +63,29 @@ export interface CommonMarkerProps {
59
63
  /** Whether this marker should be included in clustering */
60
64
  clusteringEnabled?: boolean;
61
65
 
66
+ /**
67
+ * Accessibility label read by screen readers (VoiceOver / TalkBack).
68
+ * Falls back to `title` if not set.
69
+ */
70
+ accessibilityLabel?: string;
71
+
62
72
  /** Animation when marker appears on the map */
63
73
  animation?: MarkerAnimation;
64
74
 
75
+ /**
76
+ * Animation duration in seconds
77
+ * @default 0.3
78
+ */
79
+ animationDuration?: number;
80
+
81
+ /**
82
+ * Whether the marker should animate every time it reappears on the map
83
+ * (e.g., emerging from a cluster, scrolling back into viewport).
84
+ * When false, the animation only plays on the initial mount.
85
+ * @default true
86
+ */
87
+ animateOnReappear?: boolean;
88
+
65
89
  /** Called when the marker is tapped */
66
90
  onPress?: () => void;
67
91
 
@@ -75,10 +99,10 @@ export interface CommonMarkerProps {
75
99
  onDragEnd?: (coordinate: Coordinate) => void;
76
100
  }
77
101
 
78
- // ID generator
102
+ // Module-level monotonic counter for generating unique marker IDs.
103
+ // Monotonically increasing — guaranteed unique within a JS runtime session.
79
104
  let markerIdCounter = 0;
80
- const generateMarkerId = (prefix: string) =>
81
- `${prefix}_${++markerIdCounter}_${Date.now()}`;
105
+ const generateMarkerId = (prefix: string) => `${prefix}_${++markerIdCounter}`;
82
106
 
83
107
  /**
84
108
  * Hook options for useNitroMarker
@@ -119,7 +143,9 @@ export function useNitroMarker({
119
143
  // ============ Register Event Handlers ============
120
144
  useEffect(() => {
121
145
  if (!mapContext) {
122
- console.warn(`${idPrefix} must be used inside NitroMap`);
146
+ if (__DEV__) {
147
+ console.warn(`${idPrefix} must be used inside NitroMap`);
148
+ }
123
149
  return;
124
150
  }
125
151
 
@@ -130,7 +156,8 @@ export function useNitroMarker({
130
156
  return () => {
131
157
  mapContext.unregisterMarkerHandler(markerId);
132
158
  };
133
- // We intentionally depend on individual handler properties instead of the handlers object
159
+ // Handlers are spread into individual deps so the effect re-runs
160
+ // only when a specific handler changes, not when the object ref changes.
134
161
  // eslint-disable-next-line react-hooks/exhaustive-deps
135
162
  }, [
136
163
  markerId,
@@ -151,15 +178,25 @@ export function useNitroMarker({
151
178
  return;
152
179
  }
153
180
 
181
+ // Track marker ID for duplicate detection
182
+ mapContext?.trackMarkerId(markerId);
183
+
184
+ // Validate coordinate in dev mode
185
+ const markerData = buildMarkerData(markerId);
186
+ validateCoordinate(markerData.coordinate, `marker "${markerId}"`);
187
+
154
188
  // Add marker on mount
155
- mapRef.addMarker(buildMarkerData(markerId));
189
+ mapRef.addMarker(markerData);
156
190
  isAddedRef.current = true;
157
191
 
158
192
  // Remove marker only on unmount
159
193
  return () => {
194
+ mapContext?.untrackMarkerId(markerId);
160
195
  mapRef?.removeMarker(markerId);
161
196
  isAddedRef.current = false;
162
197
  };
198
+ // buildMarkerData is intentionally excluded — we only want mount/unmount behavior.
199
+ // Updates are handled by the third useEffect below.
163
200
  // eslint-disable-next-line react-hooks/exhaustive-deps
164
201
  }, [mapRef, markerId]); // mapRef is now properly tracked
165
202
 
@@ -171,7 +208,9 @@ export function useNitroMarker({
171
208
  }
172
209
 
173
210
  // Update marker with new data
174
- mapContext.mapRef.updateMarker(buildMarkerData(markerId));
211
+ const updatedData = buildMarkerData(markerId);
212
+ validateCoordinate(updatedData.coordinate, `marker "${markerId}"`);
213
+ mapContext.mapRef.updateMarker(updatedData);
175
214
  }, [mapContext, buildMarkerData, markerId]);
176
215
 
177
216
  return markerId;
@@ -186,7 +225,7 @@ export function useMarkerHandlers(
186
225
  onDrag?: (coordinate: Coordinate) => void,
187
226
  onDragEnd?: (coordinate: Coordinate) => void
188
227
  ): MarkerHandlers {
189
- return useCallback(
228
+ return useMemo(
190
229
  () => ({
191
230
  onPress,
192
231
  onDragStart,
@@ -194,5 +233,5 @@ export function useMarkerHandlers(
194
233
  onDragEnd,
195
234
  }),
196
235
  [onPress, onDragStart, onDrag, onDragEnd]
197
- )();
236
+ );
198
237
  }
@@ -0,0 +1,68 @@
1
+ // src/hooks/useNitroOverlay.ts
2
+ import { useContext, useEffect, useRef } from 'react';
3
+ import { NitroMapContext } from '../context/NitroMapContext';
4
+ import type { NitroMapMethods } from '../specs/NitroMap.nitro';
5
+
6
+ /**
7
+ * Overlay method names used by the generic hook.
8
+ * Maps each overlay type to its add/update/remove native methods.
9
+ */
10
+ interface OverlayMethods<T extends { id: string }> {
11
+ add: (data: T) => void;
12
+ update: (data: T) => void;
13
+ remove: (id: string) => void;
14
+ }
15
+
16
+ /**
17
+ * Generic hook for overlay lifecycle management (polyline, polygon, circle).
18
+ * Adds overlay on mount, updates on prop changes, removes on unmount.
19
+ *
20
+ * Eliminates copy-paste between useNitroPolyline/useNitroPolygon/useNitroCircle.
21
+ *
22
+ * @param buildData - Memoized function that builds the overlay data object.
23
+ * @param getMethods - Function that extracts add/update/remove methods from the map ref.
24
+ */
25
+ export function useNitroOverlay<T extends { id: string }>(
26
+ buildData: () => T,
27
+ getMethods: (mapRef: NitroMapMethods) => OverlayMethods<T>
28
+ ): void {
29
+ const mapContext = useContext(NitroMapContext);
30
+ const isAddedRef = useRef(false);
31
+ const idRef = useRef<string | null>(null);
32
+ const isInitialMount = useRef(true);
33
+
34
+ const mapRef = mapContext?.mapRef;
35
+
36
+ // Add on mount, remove on unmount.
37
+ // buildData is intentionally excluded from deps — we only want mount/unmount behavior.
38
+ // Updates are handled by the second useEffect below.
39
+ useEffect(() => {
40
+ if (!mapRef) return;
41
+
42
+ const data = buildData();
43
+ const methods = getMethods(mapRef);
44
+ idRef.current = data.id;
45
+ methods.add(data);
46
+ isAddedRef.current = true;
47
+
48
+ return () => {
49
+ if (idRef.current) {
50
+ methods.remove(idRef.current);
51
+ }
52
+ isAddedRef.current = false;
53
+ };
54
+ // eslint-disable-next-line react-hooks/exhaustive-deps
55
+ }, [mapRef]);
56
+
57
+ // Update when props change (buildData reference changes on prop changes via useCallback).
58
+ // Skip the initial mount — the first useEffect already added the overlay.
59
+ useEffect(() => {
60
+ if (isInitialMount.current) {
61
+ isInitialMount.current = false;
62
+ return;
63
+ }
64
+ if (!isAddedRef.current || !mapContext?.mapRef) return;
65
+ const methods = getMethods(mapContext.mapRef);
66
+ methods.update(buildData());
67
+ }, [mapContext, buildData, getMethods]);
68
+ }
@@ -0,0 +1,25 @@
1
+ // src/hooks/useNitroPolygon.ts
2
+ import { useCallback } from 'react';
3
+ import { useNitroOverlay } from './useNitroOverlay';
4
+ import type { PolygonData } from '../types/overlay';
5
+
6
+ /**
7
+ * Hook for polygon lifecycle management.
8
+ * Adds polygon on mount, updates on prop changes, removes on unmount.
9
+ */
10
+ export function useNitroPolygon(buildPolygonData: () => PolygonData): void {
11
+ const getMethods = useCallback(
12
+ (mapRef: {
13
+ addPolygon: (d: PolygonData) => void;
14
+ updatePolygon: (d: PolygonData) => void;
15
+ removePolygon: (id: string) => void;
16
+ }) => ({
17
+ add: (data: PolygonData) => mapRef.addPolygon(data),
18
+ update: (data: PolygonData) => mapRef.updatePolygon(data),
19
+ remove: (id: string) => mapRef.removePolygon(id),
20
+ }),
21
+ []
22
+ );
23
+
24
+ useNitroOverlay(buildPolygonData, getMethods);
25
+ }
@@ -0,0 +1,25 @@
1
+ // src/hooks/useNitroPolyline.ts
2
+ import { useCallback } from 'react';
3
+ import { useNitroOverlay } from './useNitroOverlay';
4
+ import type { PolylineData } from '../types/overlay';
5
+
6
+ /**
7
+ * Hook for polyline lifecycle management.
8
+ * Adds polyline on mount, updates on prop changes, removes on unmount.
9
+ */
10
+ export function useNitroPolyline(buildPolylineData: () => PolylineData): void {
11
+ const getMethods = useCallback(
12
+ (mapRef: {
13
+ addPolyline: (d: PolylineData) => void;
14
+ updatePolyline: (d: PolylineData) => void;
15
+ removePolyline: (id: string) => void;
16
+ }) => ({
17
+ add: (data: PolylineData) => mapRef.addPolyline(data),
18
+ update: (data: PolylineData) => mapRef.updatePolyline(data),
19
+ remove: (id: string) => mapRef.removePolyline(id),
20
+ }),
21
+ []
22
+ );
23
+
24
+ useNitroOverlay(buildPolylineData, getMethods);
25
+ }
package/src/index.tsx CHANGED
@@ -6,9 +6,16 @@ export { NitroMap, default } from './components/NitroMap';
6
6
  // New specialized marker components
7
7
  export { PriceMarker } from './components/PriceMarker';
8
8
  export { ImageMarker } from './components/ImageMarker';
9
+ export { Marker } from './components/Marker';
10
+ export { NitroPolyline } from './components/NitroPolyline';
11
+ export { NitroPolygon } from './components/NitroPolygon';
12
+ export { NitroCircle } from './components/NitroCircle';
9
13
 
10
14
  // ============ Types ============
11
15
  export type { NitroMapProps, NitroMapRef } from './components/NitroMap';
16
+ export type { NitroMapMethods } from './specs/NitroMap.nitro';
17
+ export { NitroMapContext } from './context/NitroMapContext';
18
+ export type { NitroMapContextValue } from './context/NitroMapContext';
12
19
 
13
20
  export type {
14
21
  Region,
@@ -25,18 +32,18 @@ export type {
25
32
  MapStyle,
26
33
  MapError,
27
34
  Point,
35
+ UserLocationChangeEvent,
36
+ UserTrackingMode,
28
37
  } from './types/map';
29
38
 
30
39
  export type {
31
40
  MarkerStyle,
32
41
  PriceMarkerStyle,
33
42
  MarkerColor,
34
- PriceMarkerConfig,
35
43
  ImageMarkerConfig,
36
44
  ClusterPressEvent,
37
45
  ClusterConfig,
38
46
  ClusterStrategy,
39
- ClusterAnimationStyle,
40
47
  MarkerAnimation,
41
48
  MarkerConfig,
42
49
  MarkerData,
@@ -44,6 +51,16 @@ export type {
44
51
  MarkerPressEvent,
45
52
  } from './types/marker';
46
53
 
54
+ export type { PolylineData, PolygonData, CircleData } from './types/overlay';
55
+
56
+ export type {
57
+ GoogleMapTheme,
58
+ AppleMapTheme,
59
+ YandexMapTheme,
60
+ ThemeForProvider,
61
+ MapTheme,
62
+ } from './types/theme';
63
+
47
64
  export {
48
65
  NitroMapInitialize,
49
66
  IsNitroMapInitialized,
@@ -55,6 +72,10 @@ export {
55
72
 
56
73
  export type { PriceMarkerProps } from './components/PriceMarker';
57
74
  export type { ImageMarkerProps } from './components/ImageMarker';
75
+ export type { MarkerProps } from './components/Marker';
76
+ export type { NitroPolylineProps } from './components/NitroPolyline';
77
+ export type { NitroPolygonProps } from './components/NitroPolygon';
78
+ export type { NitroCircleProps } from './components/NitroCircle';
58
79
 
59
80
  // ============ Utilities ============
60
81
  // Color helpers - use these to create colors for markers and clusters