@maydon_tech/react-native-nitro-maps 0.1.4 → 0.2.1
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.
- package/LICENSE +1 -1
- package/NitroMap.podspec +1 -1
- package/README.md +82 -9
- package/android/CMakeLists.txt +4 -1
- package/android/build.gradle +6 -2
- package/android/gradle.properties +4 -4
- package/android/src/main/cpp/ClusterEngineJNI.cpp +198 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/NitroMap.kt +397 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/NitroMapConfig.kt +53 -0
- package/android/src/main/{java → kotlin}/com/margelo/nitro/nitromap/NitroMapPackage.kt +4 -4
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/NitroMapView.kt +73 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/UserLocationManager.kt +295 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/clustering/ClusterIconRenderer.kt +111 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/clustering/ClusteringManager.kt +104 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/clustering/NitroClusterEngine.kt +166 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/markers/MarkerIconFactory.kt +303 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/markers/MarkerSelectionHandler.kt +72 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/markers/PriceMarkerRenderer.kt +159 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/MapProviderFactory.kt +24 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/MapProviderInterface.kt +128 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/GoogleMapDelegate.kt +317 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/GoogleMapProvider+Clustering.kt +524 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/GoogleMapProvider+Markers.kt +358 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/GoogleMapProvider+Overlays.kt +272 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/GoogleMapProvider+UserLocation.kt +296 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/GoogleMapProvider.kt +815 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/MarkerTagData.kt +19 -0
- package/ios/Location/NitroLocationManager.swift +116 -0
- package/ios/MarkerRenderer/MarkerIconFactory.swift +1 -3
- package/ios/MarkerRenderer/PriceMarkerRenderer.swift +10 -6
- package/ios/NitroMap.swift +279 -13
- package/ios/NitroMapConfig/NitroMapConfig.swift +45 -0
- package/ios/Providers/{GoogleMapDelegate.swift → Google/GoogleMapDelegate.swift} +48 -23
- package/ios/Providers/Google/GoogleMapProvider+Camera.swift +180 -0
- package/ios/Providers/Google/GoogleMapProvider+Clustering.swift +541 -0
- package/ios/Providers/Google/GoogleMapProvider+Markers.swift +270 -0
- package/ios/Providers/Google/GoogleMapProvider+Overlays.swift +245 -0
- package/ios/Providers/Google/GoogleMapProvider+UserLocation.swift +180 -0
- package/ios/Providers/Google/GoogleMapProvider.swift +342 -0
- package/ios/Providers/MapProviderFactory.swift +17 -0
- package/ios/Providers/MapProviderProtocol.swift +48 -1
- package/ios/Shared/ClusterConfig+Factory.swift +2 -2
- package/ios/Shared/MapStyleProvider.swift +6 -4
- package/ios/Shared/MarkerSelectionHandler.swift +4 -1
- package/ios/Utils/ColorValueExtension.swift +46 -67
- package/lib/module/components/ImageMarker.js +39 -29
- package/lib/module/components/ImageMarker.js.map +1 -1
- package/lib/module/components/Marker.js +118 -0
- package/lib/module/components/Marker.js.map +1 -0
- package/lib/module/components/NitroCircle.js +92 -0
- package/lib/module/components/NitroCircle.js.map +1 -0
- package/lib/module/components/NitroMap.js +216 -76
- package/lib/module/components/NitroMap.js.map +1 -1
- package/lib/module/components/NitroPolygon.js +137 -0
- package/lib/module/components/NitroPolygon.js.map +1 -0
- package/lib/module/components/NitroPolyline.js +115 -0
- package/lib/module/components/NitroPolyline.js.map +1 -0
- package/lib/module/components/PriceMarker.js +16 -29
- package/lib/module/components/PriceMarker.js.map +1 -1
- package/lib/module/context/NitroMapContext.js.map +1 -1
- package/lib/module/hooks/useNitroCircle.js +18 -0
- package/lib/module/hooks/useNitroCircle.js.map +1 -0
- package/lib/module/hooks/useNitroMarker.js +26 -9
- package/lib/module/hooks/useNitroMarker.js.map +1 -1
- package/lib/module/hooks/useNitroOverlay.js +59 -0
- package/lib/module/hooks/useNitroOverlay.js.map +1 -0
- package/lib/module/hooks/useNitroPolygon.js +18 -0
- package/lib/module/hooks/useNitroPolygon.js.map +1 -0
- package/lib/module/hooks/useNitroPolyline.js +18 -0
- package/lib/module/hooks/useNitroPolyline.js.map +1 -0
- package/lib/module/index.js +5 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/types/overlay.js +4 -0
- package/lib/module/types/overlay.js.map +1 -0
- package/lib/module/types/theme.js +4 -0
- package/lib/module/types/theme.js.map +1 -0
- package/lib/module/utils/colors.js +41 -13
- package/lib/module/utils/colors.js.map +1 -1
- package/lib/module/utils/validation.js +45 -0
- package/lib/module/utils/validation.js.map +1 -0
- package/lib/typescript/src/components/ImageMarker.d.ts.map +1 -1
- package/lib/typescript/src/components/Marker.d.ts +34 -0
- package/lib/typescript/src/components/Marker.d.ts.map +1 -0
- package/lib/typescript/src/components/NitroCircle.d.ts +70 -0
- package/lib/typescript/src/components/NitroCircle.d.ts.map +1 -0
- package/lib/typescript/src/components/NitroMap.d.ts +60 -3
- package/lib/typescript/src/components/NitroMap.d.ts.map +1 -1
- package/lib/typescript/src/components/NitroPolygon.d.ts +86 -0
- package/lib/typescript/src/components/NitroPolygon.d.ts.map +1 -0
- package/lib/typescript/src/components/NitroPolyline.d.ts +84 -0
- package/lib/typescript/src/components/NitroPolyline.d.ts.map +1 -0
- package/lib/typescript/src/components/PriceMarker.d.ts +0 -5
- package/lib/typescript/src/components/PriceMarker.d.ts.map +1 -1
- package/lib/typescript/src/context/NitroMapContext.d.ts +2 -0
- package/lib/typescript/src/context/NitroMapContext.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useNitroCircle.d.ts +7 -0
- package/lib/typescript/src/hooks/useNitroCircle.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useNitroMarker.d.ts +20 -0
- package/lib/typescript/src/hooks/useNitroMarker.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useNitroOverlay.d.ts +26 -0
- package/lib/typescript/src/hooks/useNitroOverlay.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useNitroPolygon.d.ts +7 -0
- package/lib/typescript/src/hooks/useNitroPolygon.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useNitroPolyline.d.ts +7 -0
- package/lib/typescript/src/hooks/useNitroPolyline.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +15 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/specs/NitroMap.nitro.d.ts +248 -6
- package/lib/typescript/src/specs/NitroMap.nitro.d.ts.map +1 -1
- package/lib/typescript/src/types/map.d.ts +34 -4
- package/lib/typescript/src/types/map.d.ts.map +1 -1
- package/lib/typescript/src/types/marker.d.ts +24 -36
- package/lib/typescript/src/types/marker.d.ts.map +1 -1
- package/lib/typescript/src/types/overlay.d.ts +84 -0
- package/lib/typescript/src/types/overlay.d.ts.map +1 -0
- package/lib/typescript/src/types/theme.d.ts +93 -0
- package/lib/typescript/src/types/theme.d.ts.map +1 -0
- package/lib/typescript/src/utils/colors.d.ts +6 -8
- package/lib/typescript/src/utils/colors.d.ts.map +1 -1
- package/lib/typescript/src/utils/validation.d.ts +12 -0
- package/lib/typescript/src/utils/validation.d.ts.map +1 -0
- package/nitrogen/generated/android/c++/JCircleData.hpp +94 -0
- package/nitrogen/generated/android/c++/JClusterConfig.hpp +5 -7
- package/nitrogen/generated/android/c++/JCoordinateRing.hpp +77 -0
- package/nitrogen/generated/android/c++/JFunc_void_UserLocationChangeEvent.hpp +79 -0
- package/nitrogen/generated/android/c++/JFunc_void_UserTrackingMode.hpp +77 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__string.hpp +76 -0
- package/nitrogen/generated/android/c++/JHybridNitroMapSpec.cpp +332 -21
- package/nitrogen/generated/android/c++/JHybridNitroMapSpec.hpp +53 -2
- package/nitrogen/generated/android/c++/JMarkerAnimation.hpp +3 -6
- package/nitrogen/generated/android/c++/JMarkerData.hpp +15 -3
- package/nitrogen/generated/android/c++/JPolygonData.hpp +133 -0
- package/nitrogen/generated/android/c++/JPolylineData.hpp +113 -0
- package/nitrogen/generated/android/c++/JUserLocationChangeEvent.hpp +70 -0
- package/nitrogen/generated/android/c++/JUserTrackingMode.hpp +62 -0
- package/nitrogen/generated/android/c++/views/JHybridNitroMapStateUpdater.cpp +72 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/CircleData.kt +62 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/ClusterConfig.kt +4 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/CoordinateRing.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/Func_void_UserLocationChangeEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/Func_void_UserTrackingMode.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/Func_void_std__string.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/HybridNitroMapSpec.kt +228 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/MarkerAnimation.kt +1 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/MarkerData.kt +12 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/PolygonData.kt +62 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/PolylineData.kt +62 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/UserLocationChangeEvent.kt +47 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/{ClusterAnimationStyle.kt → UserTrackingMode.kt} +6 -8
- package/nitrogen/generated/android/nitromapOnLoad.cpp +6 -0
- package/nitrogen/generated/ios/NitroMap-Swift-Cxx-Bridge.cpp +24 -0
- package/nitrogen/generated/ios/NitroMap-Swift-Cxx-Bridge.hpp +178 -17
- package/nitrogen/generated/ios/NitroMap-Swift-Cxx-Umbrella.hpp +18 -3
- package/nitrogen/generated/ios/c++/HybridNitroMapSpecSwift.hpp +252 -16
- package/nitrogen/generated/ios/c++/views/HybridNitroMapComponent.mm +90 -5
- package/nitrogen/generated/ios/swift/CircleData.swift +143 -0
- package/nitrogen/generated/ios/swift/ClusterConfig.swift +22 -15
- package/nitrogen/generated/ios/swift/CoordinateRing.swift +48 -0
- package/nitrogen/generated/ios/swift/Func_void_UserLocationChangeEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_UserTrackingMode.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__string.swift +47 -0
- package/nitrogen/generated/ios/swift/HybridNitroMapSpec.swift +35 -1
- package/nitrogen/generated/ios/swift/HybridNitroMapSpec_cxx.swift +582 -8
- package/nitrogen/generated/ios/swift/MarkerAnimation.swift +4 -8
- package/nitrogen/generated/ios/swift/MarkerData.swift +54 -2
- package/nitrogen/generated/ios/swift/PolygonData.swift +167 -0
- package/nitrogen/generated/ios/swift/PolylineData.swift +155 -0
- package/nitrogen/generated/ios/swift/UserLocationChangeEvent.swift +69 -0
- package/nitrogen/generated/ios/swift/UserTrackingMode.swift +44 -0
- package/nitrogen/generated/shared/c++/CircleData.hpp +113 -0
- package/nitrogen/generated/shared/c++/ClusterConfig.hpp +5 -8
- package/nitrogen/generated/shared/c++/CoordinateRing.hpp +77 -0
- package/nitrogen/generated/shared/c++/HybridNitroMapSpec.cpp +53 -2
- package/nitrogen/generated/shared/c++/HybridNitroMapSpec.hpp +75 -6
- package/nitrogen/generated/shared/c++/MarkerAnimation.hpp +4 -8
- package/nitrogen/generated/shared/c++/MarkerData.hpp +14 -2
- package/nitrogen/generated/shared/c++/PolygonData.hpp +117 -0
- package/nitrogen/generated/shared/c++/PolylineData.hpp +114 -0
- package/nitrogen/generated/shared/c++/UserLocationChangeEvent.hpp +88 -0
- package/nitrogen/generated/shared/c++/UserTrackingMode.hpp +80 -0
- package/nitrogen/generated/shared/c++/views/HybridNitroMapComponent.cpp +216 -12
- package/nitrogen/generated/shared/c++/views/HybridNitroMapComponent.hpp +23 -1
- package/nitrogen/generated/shared/json/NitroMapConfig.json +18 -1
- package/package.json +36 -5
- package/src/components/ImageMarker.tsx +58 -42
- package/src/components/Marker.tsx +161 -0
- package/src/components/NitroCircle.tsx +183 -0
- package/src/components/NitroMap.tsx +328 -78
- package/src/components/NitroPolygon.tsx +229 -0
- package/src/components/NitroPolyline.tsx +208 -0
- package/src/components/PriceMarker.tsx +23 -48
- package/src/context/NitroMapContext.tsx +4 -0
- package/src/hooks/useNitroCircle.ts +25 -0
- package/src/hooks/useNitroMarker.ts +49 -10
- package/src/hooks/useNitroOverlay.ts +68 -0
- package/src/hooks/useNitroPolygon.ts +25 -0
- package/src/hooks/useNitroPolyline.ts +25 -0
- package/src/index.tsx +28 -2
- package/src/specs/NitroMap.nitro.ts +294 -5
- package/src/types/map.ts +36 -4
- package/src/types/marker.ts +24 -44
- package/src/types/overlay.ts +87 -0
- package/src/types/theme.ts +101 -0
- package/src/utils/colors.ts +48 -16
- package/src/utils/validation.ts +69 -0
- package/android/src/main/java/com/margelo/nitro/nitromap/ClusterIconGenerator.kt +0 -108
- package/android/src/main/java/com/margelo/nitro/nitromap/ColorUtils.kt +0 -63
- package/android/src/main/java/com/margelo/nitro/nitromap/HybridNitroMap.kt +0 -408
- package/android/src/main/java/com/margelo/nitro/nitromap/HybridNitroMapConfig.kt +0 -68
- package/android/src/main/java/com/margelo/nitro/nitromap/MarkerIconCache.kt +0 -176
- package/android/src/main/java/com/margelo/nitro/nitromap/MarkerIconFactory.kt +0 -252
- package/android/src/main/java/com/margelo/nitro/nitromap/clustering/NitroClusterEngine.kt +0 -252
- package/android/src/main/java/com/margelo/nitro/nitromap/clustering/QuadTree.kt +0 -195
- package/android/src/main/java/com/margelo/nitro/nitromap/providers/GoogleMapProvider.kt +0 -912
- package/android/src/main/java/com/margelo/nitro/nitromap/providers/MapProviderInterface.kt +0 -70
- package/cpp/QuadTree.hpp +0 -246
- package/ios/NitroMapConfig/HybridNitroMapConfig.swift +0 -33
- package/ios/Providers/GoogleMapProvider+Camera.swift +0 -164
- package/ios/Providers/GoogleMapProvider.swift +0 -924
- package/nitrogen/generated/android/c++/JClusterAnimationStyle.hpp +0 -68
- package/nitrogen/generated/ios/swift/ClusterAnimationStyle.swift +0 -52
- package/nitrogen/generated/shared/c++/ClusterAnimationStyle.hpp +0 -88
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
// src/components/NitroPolygon.tsx
|
|
2
|
+
import { memo, useCallback, useEffect, useRef } from 'react';
|
|
3
|
+
import { useNitroPolygon } from '../hooks/useNitroPolygon';
|
|
4
|
+
import type { Coordinate } from '../types/map';
|
|
5
|
+
import type { MarkerColor } from '../types/marker';
|
|
6
|
+
import {
|
|
7
|
+
parseColor,
|
|
8
|
+
areColorsEqual,
|
|
9
|
+
type ColorValue,
|
|
10
|
+
Colors,
|
|
11
|
+
} from '../utils/colors';
|
|
12
|
+
import { validateCoordinates } from '../utils/validation';
|
|
13
|
+
import type { PolygonData } from '../types/overlay';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Props for the NitroPolygon component
|
|
17
|
+
*/
|
|
18
|
+
export interface NitroPolygonProps {
|
|
19
|
+
/** Unique identifier for the polygon */
|
|
20
|
+
id?: string;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Array of geographic coordinates that form the polygon boundary.
|
|
24
|
+
* At least 3 coordinates are required to render a visible polygon.
|
|
25
|
+
* The polygon is automatically closed (first and last points are connected).
|
|
26
|
+
* @required
|
|
27
|
+
*/
|
|
28
|
+
coordinates: Coordinate[];
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Optional array of holes — each hole is an array of coordinates
|
|
32
|
+
* that will be cut out from the polygon fill.
|
|
33
|
+
* @default []
|
|
34
|
+
*/
|
|
35
|
+
holes?: Coordinate[][];
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Fill color of the polygon (hex string like "#00000040" or MarkerColor object).
|
|
39
|
+
* Use 8-char hex for alpha: "#RRGGBBAA"
|
|
40
|
+
* @default MarkerColor { r: 0, g: 0, b: 0, a: 77 } (~30% opacity black)
|
|
41
|
+
*/
|
|
42
|
+
fillColor?: ColorValue;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Stroke color of the polygon border (hex string or MarkerColor object).
|
|
46
|
+
* @default '#000000'
|
|
47
|
+
*/
|
|
48
|
+
strokeColor?: ColorValue;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Stroke width of the polygon border in pixels.
|
|
52
|
+
* @default 1
|
|
53
|
+
*/
|
|
54
|
+
strokeWidth?: number;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Z-index for controlling overlay stacking order.
|
|
58
|
+
* Higher values render on top.
|
|
59
|
+
* @default 0
|
|
60
|
+
*/
|
|
61
|
+
zIndex?: number;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Whether this polygon responds to tap events.
|
|
65
|
+
* When true, `onPolygonPress` on `<NitroMap>` fires with this polygon's ID.
|
|
66
|
+
* @default false
|
|
67
|
+
*/
|
|
68
|
+
tappable?: boolean;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Accessibility label read by screen readers (VoiceOver / TalkBack).
|
|
72
|
+
*/
|
|
73
|
+
accessibilityLabel?: string;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ID generator — monotonic counter, unique within a JS runtime session
|
|
77
|
+
let polygonIdCounter = 0;
|
|
78
|
+
const generatePolygonId = (): string => `polygon_${++polygonIdCounter}`;
|
|
79
|
+
|
|
80
|
+
// Default colors
|
|
81
|
+
const defaultFillColor: MarkerColor = { r: 0, g: 0, b: 0, a: 77 }; // ~30% opacity black
|
|
82
|
+
const defaultStrokeColor: MarkerColor = Colors.black;
|
|
83
|
+
|
|
84
|
+
// ============ Custom Memo Comparison ============
|
|
85
|
+
const arePropsEqual = (
|
|
86
|
+
prev: NitroPolygonProps,
|
|
87
|
+
next: NitroPolygonProps
|
|
88
|
+
): boolean => {
|
|
89
|
+
// Compare primitives
|
|
90
|
+
if (
|
|
91
|
+
prev.id !== next.id ||
|
|
92
|
+
prev.strokeWidth !== next.strokeWidth ||
|
|
93
|
+
prev.zIndex !== next.zIndex ||
|
|
94
|
+
prev.tappable !== next.tappable ||
|
|
95
|
+
prev.accessibilityLabel !== next.accessibilityLabel
|
|
96
|
+
) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (!areColorsEqual(prev.fillColor, next.fillColor)) return false;
|
|
101
|
+
if (!areColorsEqual(prev.strokeColor, next.strokeColor)) return false;
|
|
102
|
+
|
|
103
|
+
// Compare coordinates array (deep)
|
|
104
|
+
const prevCoords = prev.coordinates;
|
|
105
|
+
const nextCoords = next.coordinates;
|
|
106
|
+
if (prevCoords.length !== nextCoords.length) return false;
|
|
107
|
+
for (let i = 0; i < prevCoords.length; i++) {
|
|
108
|
+
if (
|
|
109
|
+
prevCoords[i]!.latitude !== nextCoords[i]!.latitude ||
|
|
110
|
+
prevCoords[i]!.longitude !== nextCoords[i]!.longitude
|
|
111
|
+
) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Compare holes
|
|
117
|
+
const prevHoles = prev.holes ?? [];
|
|
118
|
+
const nextHoles = next.holes ?? [];
|
|
119
|
+
if (prevHoles.length !== nextHoles.length) return false;
|
|
120
|
+
for (let i = 0; i < prevHoles.length; i++) {
|
|
121
|
+
const ph = prevHoles[i]!;
|
|
122
|
+
const nh = nextHoles[i]!;
|
|
123
|
+
if (ph.length !== nh.length) return false;
|
|
124
|
+
for (let j = 0; j < ph.length; j++) {
|
|
125
|
+
if (
|
|
126
|
+
ph[j]!.latitude !== nh[j]!.latitude ||
|
|
127
|
+
ph[j]!.longitude !== nh[j]!.longitude
|
|
128
|
+
) {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return true;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* NitroPolygon - Draw a closed polygon shape on the map
|
|
139
|
+
*
|
|
140
|
+
* @example Basic polygon
|
|
141
|
+
* ```tsx
|
|
142
|
+
* <NitroPolygon
|
|
143
|
+
* coordinates={[
|
|
144
|
+
* { latitude: 41.29, longitude: 69.24 },
|
|
145
|
+
* { latitude: 41.31, longitude: 69.28 },
|
|
146
|
+
* { latitude: 41.33, longitude: 69.26 },
|
|
147
|
+
* ]}
|
|
148
|
+
* fillColor="#4285F440"
|
|
149
|
+
* strokeColor="#4285F4"
|
|
150
|
+
* strokeWidth={2}
|
|
151
|
+
* />
|
|
152
|
+
* ```
|
|
153
|
+
*
|
|
154
|
+
* @example Polygon with a hole
|
|
155
|
+
* ```tsx
|
|
156
|
+
* <NitroPolygon
|
|
157
|
+
* coordinates={outerBoundary}
|
|
158
|
+
* holes={[innerHole]}
|
|
159
|
+
* fillColor="#FF000040"
|
|
160
|
+
* strokeColor="#FF0000"
|
|
161
|
+
* />
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
export const NitroPolygon = memo(function NitroPolygon({
|
|
165
|
+
id,
|
|
166
|
+
coordinates,
|
|
167
|
+
holes = [],
|
|
168
|
+
fillColor,
|
|
169
|
+
strokeColor,
|
|
170
|
+
strokeWidth = 1,
|
|
171
|
+
zIndex = 0,
|
|
172
|
+
tappable = false,
|
|
173
|
+
accessibilityLabel,
|
|
174
|
+
}: NitroPolygonProps) {
|
|
175
|
+
useEffect(() => {
|
|
176
|
+
if (__DEV__) {
|
|
177
|
+
if (coordinates.length < 3) {
|
|
178
|
+
console.warn(
|
|
179
|
+
'NitroPolygon: at least 3 coordinates are required to render a visible polygon. ' +
|
|
180
|
+
`Received ${coordinates.length}.`
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
validateCoordinates(coordinates, 'NitroPolygon');
|
|
184
|
+
holes.forEach((hole, i) =>
|
|
185
|
+
validateCoordinates(hole, `NitroPolygon hole[${i}]`)
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
189
|
+
}, []);
|
|
190
|
+
|
|
191
|
+
// Generate stable ID
|
|
192
|
+
const polygonId = useRef(id || generatePolygonId()).current;
|
|
193
|
+
|
|
194
|
+
// Build polygon data
|
|
195
|
+
const buildPolygonData = useCallback(
|
|
196
|
+
(): PolygonData => ({
|
|
197
|
+
id: polygonId,
|
|
198
|
+
coordinates,
|
|
199
|
+
holes: holes.map((ring) => ({ coordinates: ring })),
|
|
200
|
+
fillColor: parseColor(fillColor) ?? defaultFillColor,
|
|
201
|
+
strokeColor: parseColor(strokeColor) ?? defaultStrokeColor,
|
|
202
|
+
strokeWidth,
|
|
203
|
+
zIndex,
|
|
204
|
+
tappable,
|
|
205
|
+
accessibilityLabel,
|
|
206
|
+
}),
|
|
207
|
+
[
|
|
208
|
+
polygonId,
|
|
209
|
+
coordinates,
|
|
210
|
+
holes,
|
|
211
|
+
fillColor,
|
|
212
|
+
strokeColor,
|
|
213
|
+
strokeWidth,
|
|
214
|
+
zIndex,
|
|
215
|
+
tappable,
|
|
216
|
+
accessibilityLabel,
|
|
217
|
+
]
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
// Use polygon lifecycle hook
|
|
221
|
+
useNitroPolygon(buildPolygonData);
|
|
222
|
+
|
|
223
|
+
// Render nothing — polygon is rendered natively
|
|
224
|
+
return null;
|
|
225
|
+
},
|
|
226
|
+
arePropsEqual);
|
|
227
|
+
|
|
228
|
+
export { arePropsEqual as arePolygonPropsEqual };
|
|
229
|
+
export default NitroPolygon;
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
// src/components/NitroPolyline.tsx
|
|
2
|
+
import { memo, useCallback, useEffect, useRef } from 'react';
|
|
3
|
+
import { useNitroPolyline } from '../hooks/useNitroPolyline';
|
|
4
|
+
import type { Coordinate } from '../types/map';
|
|
5
|
+
import {
|
|
6
|
+
parseColor,
|
|
7
|
+
areColorsEqual,
|
|
8
|
+
type ColorValue,
|
|
9
|
+
Colors,
|
|
10
|
+
} from '../utils/colors';
|
|
11
|
+
import { validateCoordinates } from '../utils/validation';
|
|
12
|
+
import type { PolylineData } from '../types/overlay';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Props for the NitroPolyline component
|
|
16
|
+
*/
|
|
17
|
+
export interface NitroPolylineProps {
|
|
18
|
+
/** Unique identifier for the polyline */
|
|
19
|
+
id?: string;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Array of geographic coordinates that form the polyline path.
|
|
23
|
+
* At least 2 coordinates are required to render a visible line.
|
|
24
|
+
* @required
|
|
25
|
+
*/
|
|
26
|
+
coordinates: Coordinate[];
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Stroke color of the polyline (hex string like "#4285F4" or MarkerColor object).
|
|
30
|
+
* @default '#000000'
|
|
31
|
+
*/
|
|
32
|
+
strokeColor?: ColorValue;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Stroke width in pixels.
|
|
36
|
+
* @default 1
|
|
37
|
+
*/
|
|
38
|
+
strokeWidth?: number;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Whether the line follows Earth's curvature (great circle path).
|
|
42
|
+
* When true, the line curves on the Mercator projection to represent
|
|
43
|
+
* the shortest path on the sphere. Noticeable on long-distance lines.
|
|
44
|
+
* @default false
|
|
45
|
+
*/
|
|
46
|
+
geodesic?: boolean;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Whether the line is rendered as dashed.
|
|
50
|
+
* @default false
|
|
51
|
+
*/
|
|
52
|
+
dashed?: boolean;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Z-index for controlling overlay stacking order.
|
|
56
|
+
* Higher values render on top.
|
|
57
|
+
* @default 0
|
|
58
|
+
*/
|
|
59
|
+
zIndex?: number;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Whether this polyline responds to tap events.
|
|
63
|
+
* When true, `onPolylinePress` on `<NitroMap>` fires with this polyline's ID.
|
|
64
|
+
* @default false
|
|
65
|
+
*/
|
|
66
|
+
tappable?: boolean;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Accessibility label read by screen readers (VoiceOver / TalkBack).
|
|
70
|
+
*/
|
|
71
|
+
accessibilityLabel?: string;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// ID generator — monotonic counter, unique within a JS runtime session
|
|
75
|
+
let polylineIdCounter = 0;
|
|
76
|
+
const generatePolylineId = (): string => `polyline_${++polylineIdCounter}`;
|
|
77
|
+
|
|
78
|
+
// Default stroke color (black)
|
|
79
|
+
const defaultStrokeColor = Colors.black;
|
|
80
|
+
|
|
81
|
+
// ============ Custom Memo Comparison ============
|
|
82
|
+
const arePropsEqual = (
|
|
83
|
+
prev: NitroPolylineProps,
|
|
84
|
+
next: NitroPolylineProps
|
|
85
|
+
): boolean => {
|
|
86
|
+
// Compare primitives
|
|
87
|
+
if (
|
|
88
|
+
prev.id !== next.id ||
|
|
89
|
+
prev.strokeWidth !== next.strokeWidth ||
|
|
90
|
+
prev.geodesic !== next.geodesic ||
|
|
91
|
+
prev.dashed !== next.dashed ||
|
|
92
|
+
prev.zIndex !== next.zIndex ||
|
|
93
|
+
prev.tappable !== next.tappable ||
|
|
94
|
+
prev.accessibilityLabel !== next.accessibilityLabel
|
|
95
|
+
) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Compare strokeColor
|
|
100
|
+
if (!areColorsEqual(prev.strokeColor, next.strokeColor)) {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Compare coordinates array (deep)
|
|
105
|
+
const prevCoords = prev.coordinates;
|
|
106
|
+
const nextCoords = next.coordinates;
|
|
107
|
+
if (prevCoords.length !== nextCoords.length) return false;
|
|
108
|
+
for (let i = 0; i < prevCoords.length; i++) {
|
|
109
|
+
if (
|
|
110
|
+
prevCoords[i]!.latitude !== nextCoords[i]!.latitude ||
|
|
111
|
+
prevCoords[i]!.longitude !== nextCoords[i]!.longitude
|
|
112
|
+
) {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return true;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* NitroPolyline - Draw a line connecting multiple geographic points on the map
|
|
122
|
+
*
|
|
123
|
+
* @example Basic route line
|
|
124
|
+
* ```tsx
|
|
125
|
+
* <NitroPolyline
|
|
126
|
+
* coordinates={[
|
|
127
|
+
* { latitude: 41.29, longitude: 69.24 },
|
|
128
|
+
* { latitude: 41.31, longitude: 69.28 },
|
|
129
|
+
* ]}
|
|
130
|
+
* strokeColor="#4285F4"
|
|
131
|
+
* strokeWidth={4}
|
|
132
|
+
* />
|
|
133
|
+
* ```
|
|
134
|
+
*
|
|
135
|
+
* @example Geodesic dashed line
|
|
136
|
+
* ```tsx
|
|
137
|
+
* <NitroPolyline
|
|
138
|
+
* coordinates={routeCoordinates}
|
|
139
|
+
* strokeColor="#FF0000"
|
|
140
|
+
* strokeWidth={2}
|
|
141
|
+
* geodesic={true}
|
|
142
|
+
* dashed={true}
|
|
143
|
+
* />
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
export const NitroPolyline = memo(function NitroPolyline({
|
|
147
|
+
id,
|
|
148
|
+
coordinates,
|
|
149
|
+
strokeColor,
|
|
150
|
+
strokeWidth = 1,
|
|
151
|
+
geodesic = false,
|
|
152
|
+
dashed = false,
|
|
153
|
+
zIndex = 0,
|
|
154
|
+
tappable = false,
|
|
155
|
+
accessibilityLabel,
|
|
156
|
+
}: NitroPolylineProps) {
|
|
157
|
+
useEffect(() => {
|
|
158
|
+
if (__DEV__) {
|
|
159
|
+
if (coordinates.length < 2) {
|
|
160
|
+
console.warn(
|
|
161
|
+
'NitroPolyline: at least 2 coordinates are required to render a visible line. ' +
|
|
162
|
+
`Received ${coordinates.length}.`
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
validateCoordinates(coordinates, 'NitroPolyline');
|
|
166
|
+
}
|
|
167
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
168
|
+
}, []);
|
|
169
|
+
|
|
170
|
+
// Generate stable ID
|
|
171
|
+
const polylineId = useRef(id || generatePolylineId()).current;
|
|
172
|
+
|
|
173
|
+
// Build polyline data
|
|
174
|
+
const buildPolylineData = useCallback(
|
|
175
|
+
(): PolylineData => ({
|
|
176
|
+
id: polylineId,
|
|
177
|
+
coordinates,
|
|
178
|
+
strokeColor: parseColor(strokeColor) ?? defaultStrokeColor,
|
|
179
|
+
strokeWidth,
|
|
180
|
+
geodesic,
|
|
181
|
+
dashed,
|
|
182
|
+
zIndex,
|
|
183
|
+
tappable,
|
|
184
|
+
accessibilityLabel,
|
|
185
|
+
}),
|
|
186
|
+
[
|
|
187
|
+
polylineId,
|
|
188
|
+
coordinates,
|
|
189
|
+
strokeColor,
|
|
190
|
+
strokeWidth,
|
|
191
|
+
geodesic,
|
|
192
|
+
dashed,
|
|
193
|
+
zIndex,
|
|
194
|
+
tappable,
|
|
195
|
+
accessibilityLabel,
|
|
196
|
+
]
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
// Use polyline lifecycle hook
|
|
200
|
+
useNitroPolyline(buildPolylineData);
|
|
201
|
+
|
|
202
|
+
// Render nothing — polyline is rendered natively
|
|
203
|
+
return null;
|
|
204
|
+
},
|
|
205
|
+
arePropsEqual);
|
|
206
|
+
|
|
207
|
+
export { arePropsEqual as arePolylinePropsEqual };
|
|
208
|
+
export default NitroPolyline;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// src/components/PriceMarker.tsx
|
|
2
|
-
import { memo, useCallback
|
|
2
|
+
import { memo, useCallback } from 'react';
|
|
3
3
|
import {
|
|
4
4
|
useNitroMarker,
|
|
5
|
+
useMarkerHandlers,
|
|
5
6
|
type CommonMarkerProps,
|
|
6
7
|
} from '../hooks/useNitroMarker';
|
|
7
|
-
import type
|
|
8
|
-
import { parseColor, type ColorValue } from '../utils/colors';
|
|
8
|
+
import { parseColor, areColorsEqual, type ColorValue } from '../utils/colors';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Props for the PriceMarker component
|
|
@@ -48,12 +48,6 @@ export interface PriceMarkerProps extends CommonMarkerProps {
|
|
|
48
48
|
*/
|
|
49
49
|
fontSize?: number;
|
|
50
50
|
|
|
51
|
-
/**
|
|
52
|
-
* Corner radius in pixels (only for simple price style)
|
|
53
|
-
* @default 8
|
|
54
|
-
*/
|
|
55
|
-
cornerRadius?: number;
|
|
56
|
-
|
|
57
51
|
/**
|
|
58
52
|
* Background color when marker is selected (hex string like "#FF0000" or MarkerColor object)
|
|
59
53
|
*/
|
|
@@ -99,11 +93,13 @@ const arePropsEqual = (
|
|
|
99
93
|
prevProps.zIndex !== nextProps.zIndex ||
|
|
100
94
|
prevProps.clusteringEnabled !== nextProps.clusteringEnabled ||
|
|
101
95
|
prevProps.animation !== nextProps.animation ||
|
|
96
|
+
prevProps.animationDuration !== nextProps.animationDuration ||
|
|
97
|
+
prevProps.animateOnReappear !== nextProps.animateOnReappear ||
|
|
102
98
|
prevProps.fontSize !== nextProps.fontSize ||
|
|
103
|
-
prevProps.cornerRadius !== nextProps.cornerRadius ||
|
|
104
99
|
prevProps.paddingHorizontal !== nextProps.paddingHorizontal ||
|
|
105
100
|
prevProps.paddingVertical !== nextProps.paddingVertical ||
|
|
106
|
-
prevProps.shadowOpacity !== nextProps.shadowOpacity
|
|
101
|
+
prevProps.shadowOpacity !== nextProps.shadowOpacity ||
|
|
102
|
+
prevProps.accessibilityLabel !== nextProps.accessibilityLabel
|
|
107
103
|
) {
|
|
108
104
|
return false;
|
|
109
105
|
}
|
|
@@ -124,36 +120,14 @@ const arePropsEqual = (
|
|
|
124
120
|
return false;
|
|
125
121
|
}
|
|
126
122
|
|
|
127
|
-
// Compare colors (handles both hex strings and MarkerColor objects)
|
|
128
|
-
const compareColors = (
|
|
129
|
-
a: ColorValue | undefined,
|
|
130
|
-
b: ColorValue | undefined
|
|
131
|
-
) => {
|
|
132
|
-
if (!a && !b) return true;
|
|
133
|
-
if (!a || !b) return false;
|
|
134
|
-
// If both are strings, compare directly
|
|
135
|
-
if (typeof a === 'string' && typeof b === 'string') return a === b;
|
|
136
|
-
// If types differ, not equal
|
|
137
|
-
if (typeof a !== typeof b) return false;
|
|
138
|
-
// Both are MarkerColor objects
|
|
139
|
-
const aColor = a as MarkerColor;
|
|
140
|
-
const bColor = b as MarkerColor;
|
|
141
|
-
return (
|
|
142
|
-
aColor.r === bColor.r &&
|
|
143
|
-
aColor.g === bColor.g &&
|
|
144
|
-
aColor.b === bColor.b &&
|
|
145
|
-
aColor.a === bColor.a
|
|
146
|
-
);
|
|
147
|
-
};
|
|
148
|
-
|
|
149
123
|
if (
|
|
150
|
-
!
|
|
151
|
-
!
|
|
152
|
-
!
|
|
124
|
+
!areColorsEqual(prevProps.backgroundColor, nextProps.backgroundColor) ||
|
|
125
|
+
!areColorsEqual(prevProps.textColor, nextProps.textColor) ||
|
|
126
|
+
!areColorsEqual(
|
|
153
127
|
prevProps.selectedBackgroundColor,
|
|
154
128
|
nextProps.selectedBackgroundColor
|
|
155
129
|
) ||
|
|
156
|
-
!
|
|
130
|
+
!areColorsEqual(prevProps.selectedTextColor, nextProps.selectedTextColor)
|
|
157
131
|
) {
|
|
158
132
|
return false;
|
|
159
133
|
}
|
|
@@ -197,7 +171,7 @@ export const PriceMarker = memo(function PriceMarker({
|
|
|
197
171
|
backgroundColor,
|
|
198
172
|
textColor,
|
|
199
173
|
fontSize = 14,
|
|
200
|
-
// cornerRadius
|
|
174
|
+
// cornerRadius was removed — not forwarded to native
|
|
201
175
|
selectedBackgroundColor,
|
|
202
176
|
selectedTextColor,
|
|
203
177
|
paddingHorizontal,
|
|
@@ -214,6 +188,9 @@ export const PriceMarker = memo(function PriceMarker({
|
|
|
214
188
|
anchor = { x: 0.5, y: 0.5 },
|
|
215
189
|
clusteringEnabled = true,
|
|
216
190
|
animation = 'none',
|
|
191
|
+
animationDuration = 0.3,
|
|
192
|
+
animateOnReappear = true,
|
|
193
|
+
accessibilityLabel,
|
|
217
194
|
|
|
218
195
|
// Events
|
|
219
196
|
onPress,
|
|
@@ -254,16 +231,8 @@ export const PriceMarker = memo(function PriceMarker({
|
|
|
254
231
|
shadowOpacity,
|
|
255
232
|
]);
|
|
256
233
|
|
|
257
|
-
// Memoize handlers
|
|
258
|
-
const handlers =
|
|
259
|
-
() => ({
|
|
260
|
-
onPress,
|
|
261
|
-
onDragStart,
|
|
262
|
-
onDrag,
|
|
263
|
-
onDragEnd,
|
|
264
|
-
}),
|
|
265
|
-
[onPress, onDragStart, onDrag, onDragEnd]
|
|
266
|
-
);
|
|
234
|
+
// Memoize handlers via shared hook
|
|
235
|
+
const handlers = useMarkerHandlers(onPress, onDragStart, onDrag, onDragEnd);
|
|
267
236
|
|
|
268
237
|
// Build full marker data
|
|
269
238
|
const buildMarkerData = useCallback(
|
|
@@ -279,7 +248,10 @@ export const PriceMarker = memo(function PriceMarker({
|
|
|
279
248
|
anchor,
|
|
280
249
|
clusteringEnabled,
|
|
281
250
|
config: buildMarkerConfig(),
|
|
251
|
+
accessibilityLabel,
|
|
282
252
|
animation,
|
|
253
|
+
animationDuration,
|
|
254
|
+
animateOnReappear,
|
|
283
255
|
}),
|
|
284
256
|
[
|
|
285
257
|
coordinate,
|
|
@@ -292,7 +264,10 @@ export const PriceMarker = memo(function PriceMarker({
|
|
|
292
264
|
anchor,
|
|
293
265
|
clusteringEnabled,
|
|
294
266
|
buildMarkerConfig,
|
|
267
|
+
accessibilityLabel,
|
|
295
268
|
animation,
|
|
269
|
+
animationDuration,
|
|
270
|
+
animateOnReappear,
|
|
296
271
|
]
|
|
297
272
|
);
|
|
298
273
|
|
|
@@ -24,6 +24,10 @@ export interface NitroMapContextValue {
|
|
|
24
24
|
|
|
25
25
|
// Get handlers for a specific marker (used internally)
|
|
26
26
|
getMarkerHandler: (markerId: string) => MarkerHandlers | undefined;
|
|
27
|
+
|
|
28
|
+
// Track active marker IDs for duplicate detection (__DEV__ only)
|
|
29
|
+
trackMarkerId: (markerId: string) => void;
|
|
30
|
+
untrackMarkerId: (markerId: string) => void;
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
// Create context with null default
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// src/hooks/useNitroCircle.ts
|
|
2
|
+
import { useCallback } from 'react';
|
|
3
|
+
import { useNitroOverlay } from './useNitroOverlay';
|
|
4
|
+
import type { CircleData } from '../types/overlay';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Hook for circle lifecycle management.
|
|
8
|
+
* Adds circle on mount, updates on prop changes, removes on unmount.
|
|
9
|
+
*/
|
|
10
|
+
export function useNitroCircle(buildCircleData: () => CircleData): void {
|
|
11
|
+
const getMethods = useCallback(
|
|
12
|
+
(mapRef: {
|
|
13
|
+
addCircle: (d: CircleData) => void;
|
|
14
|
+
updateCircle: (d: CircleData) => void;
|
|
15
|
+
removeCircle: (id: string) => void;
|
|
16
|
+
}) => ({
|
|
17
|
+
add: (data: CircleData) => mapRef.addCircle(data),
|
|
18
|
+
update: (data: CircleData) => mapRef.updateCircle(data),
|
|
19
|
+
remove: (id: string) => mapRef.removeCircle(id),
|
|
20
|
+
}),
|
|
21
|
+
[]
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
useNitroOverlay(buildCircleData, getMethods);
|
|
25
|
+
}
|