react-native-leaflet-kit 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +410 -0
  3. package/dist/components/Circle.d.ts +4 -0
  4. package/dist/components/Circle.d.ts.map +1 -0
  5. package/dist/components/Circle.js +15 -0
  6. package/dist/components/Circle.js.map +1 -0
  7. package/dist/components/GeoJSON.d.ts +4 -0
  8. package/dist/components/GeoJSON.d.ts.map +1 -0
  9. package/dist/components/GeoJSON.js +14 -0
  10. package/dist/components/GeoJSON.js.map +1 -0
  11. package/dist/components/Heatmap.d.ts +4 -0
  12. package/dist/components/Heatmap.d.ts.map +1 -0
  13. package/dist/components/Heatmap.js +14 -0
  14. package/dist/components/Heatmap.js.map +1 -0
  15. package/dist/components/MapContainer.d.ts +9 -0
  16. package/dist/components/MapContainer.d.ts.map +1 -0
  17. package/dist/components/MapContainer.js +86 -0
  18. package/dist/components/MapContainer.js.map +1 -0
  19. package/dist/components/Marker.d.ts +7 -0
  20. package/dist/components/Marker.d.ts.map +1 -0
  21. package/dist/components/Marker.js +20 -0
  22. package/dist/components/Marker.js.map +1 -0
  23. package/dist/components/MarkerCluster.d.ts +4 -0
  24. package/dist/components/MarkerCluster.d.ts.map +1 -0
  25. package/dist/components/MarkerCluster.js +14 -0
  26. package/dist/components/MarkerCluster.js.map +1 -0
  27. package/dist/components/Polygon.d.ts +4 -0
  28. package/dist/components/Polygon.d.ts.map +1 -0
  29. package/dist/components/Polygon.js +15 -0
  30. package/dist/components/Polygon.js.map +1 -0
  31. package/dist/components/Polyline.d.ts +4 -0
  32. package/dist/components/Polyline.d.ts.map +1 -0
  33. package/dist/components/Polyline.js +14 -0
  34. package/dist/components/Polyline.js.map +1 -0
  35. package/dist/components/Popup.d.ts +4 -0
  36. package/dist/components/Popup.d.ts.map +1 -0
  37. package/dist/components/Popup.js +27 -0
  38. package/dist/components/Popup.js.map +1 -0
  39. package/dist/components/TileLayer.d.ts +4 -0
  40. package/dist/components/TileLayer.d.ts.map +1 -0
  41. package/dist/components/TileLayer.js +14 -0
  42. package/dist/components/TileLayer.js.map +1 -0
  43. package/dist/components/UserMarker.d.ts +4 -0
  44. package/dist/components/UserMarker.d.ts.map +1 -0
  45. package/dist/components/UserMarker.js +15 -0
  46. package/dist/components/UserMarker.js.map +1 -0
  47. package/dist/context/MapContext.d.ts +11 -0
  48. package/dist/context/MapContext.d.ts.map +1 -0
  49. package/dist/context/MapContext.js +11 -0
  50. package/dist/context/MapContext.js.map +1 -0
  51. package/dist/index.d.ts +14 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +14 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/templates/LeafletHTML.d.ts +2 -0
  56. package/dist/templates/LeafletHTML.d.ts.map +1 -0
  57. package/dist/templates/LeafletHTML.js +539 -0
  58. package/dist/templates/LeafletHTML.js.map +1 -0
  59. package/dist/types/index.d.ts +155 -0
  60. package/dist/types/index.d.ts.map +1 -0
  61. package/dist/types/index.js +15 -0
  62. package/dist/types/index.js.map +1 -0
  63. package/dist/utils/deepEqual.d.ts +2 -0
  64. package/dist/utils/deepEqual.d.ts.map +1 -0
  65. package/dist/utils/deepEqual.js +22 -0
  66. package/dist/utils/deepEqual.js.map +1 -0
  67. package/package.json +52 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 React Native Leaflet Kit Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,410 @@
1
+ # React Native Leaflet Kit 🗺️
2
+
3
+ A professional, pluggable, and declarative Map library for React Native built on top of Leaflet, WebView, and OpenStreetMap tiles. Designed with a Compound Component pattern for maximum flexibility and performance.
4
+
5
+ ## ✨ Features
6
+
7
+ - **Declarative API**: Build maps using clean, modular JSX components.
8
+ - **Compound Component Pattern**: Easily compose layers, markers, and polylines.
9
+ - **Surgical Updates**: Only modified elements are updated, preventing full map re-renders.
10
+ - **Premium User Location**: Integrated high-performance user marker with direction cone and pulse animation.
11
+ - **TypeScript Support**: Fully typed for a superior developer experience.
12
+ - **Theming**: Seamless support for Light and Dark modes.
13
+
14
+ ---
15
+
16
+ ## 🚀 Installation
17
+
18
+ Install the library and its peer dependency:
19
+
20
+ ```bash
21
+ npm install react-native-leaflet-kit react-native-webview
22
+ # or
23
+ yarn add react-native-leaflet-kit react-native-webview
24
+ ```
25
+
26
+ ---
27
+
28
+ ## 🛠️ Quick Start
29
+
30
+ Wrap your map elements inside the `MapContainer` and add layers as needed.
31
+
32
+ ```tsx
33
+ import { MapContainer, TileLayer, Marker, Polyline } from '@/components/map-library';
34
+
35
+ const MyMap = () => {
36
+ return (
37
+ <MapContainer
38
+ center={{ lat: 28.7041, lng: 77.1025 }}
39
+ zoom={13}
40
+ isDark={true}
41
+ fitBounds={true}
42
+ >
43
+ <TileLayer />
44
+
45
+ <Marker
46
+ id="station-1"
47
+ position={{ lat: 28.7041, lng: 77.1025 }}
48
+ title="Delhi Station"
49
+ />
50
+ </MapContainer>
51
+ );
52
+ };
53
+ ```
54
+
55
+ ### 🏎️ Using the Metride Wrapper
56
+ For the most streamlined experience, use the `MetrideMap` component which handles all boilerplate:
57
+
58
+ ```tsx
59
+ import { MetrideMap } from '@/components/metro/MetrideMap';
60
+
61
+ <MetrideMap
62
+ markers={myStations}
63
+ paths={myRouteLines}
64
+ userMarker={currentUserLocation}
65
+ fitBounds={true}
66
+ isDark={true}
67
+ />
68
+ ```
69
+
70
+ ---
71
+
72
+ ---
73
+
74
+ ## 🧩 Component Documentation
75
+
76
+ ### 1. `<MapContainer />`
77
+ The primary wrapper that initializes the WebView and provides the Map Context.
78
+
79
+ | Prop | Type | Default | Description |
80
+ | :--- | :--- | :--- | :--- |
81
+ | `center` | `LatLng` | - | Initial center coordinates `{ lat, lng }`. |
82
+ | `zoom` | `number` | `13` | Initial zoom level. |
83
+ | `isDark` | `boolean` | `false` | Toggles dark mode tiles filter. |
84
+ | `backgroundColor` | `string` | `#ffffff` | WebView background color. |
85
+ | `fitBounds` | `boolean` | `false` | Enables automatic framing of the map content. |
86
+ | `onMapReady` | `() => void` | - | Called when the map is fully loaded. |
87
+ | `onUserGesture`| `() => void` | - | Called when the user manually pans or zooms (disables fitBounds). |
88
+ | `onMapClick` | `(pos: LatLng) => void` | - | Called when the map is tapped. |
89
+
90
+ **Example:**
91
+ ```tsx
92
+ <MapContainer
93
+ ref={mapRef}
94
+ center={{ lat: 28.6139, lng: 77.2090 }}
95
+ onMapClick={(pos) => console.log('Tapped at:', pos)}
96
+ >
97
+ {/* Children go here */}
98
+ </MapContainer>
99
+ ```
100
+
101
+ ---
102
+
103
+ ### 2. `<TileLayer />`
104
+ Defines the source of the map tiles.
105
+
106
+ | Prop | Type | Default | Description |
107
+ | :--- | :--- | :--- | :--- |
108
+ | `url` | `string` | `OSM Standard` | Standard Tile URL pattern. Defaults to OpenStreetMap. |
109
+ | `attribution` | `string` | - | Small text displayed at footer for credits. |
110
+
111
+ **Example (Default):**
112
+ ```tsx
113
+ <TileLayer />
114
+ ```
115
+
116
+ **Example (Custom Source):**
117
+ ```tsx
118
+ <TileLayer
119
+ url="https://{s}.tile.thunderforest.com/transport/{z}/{x}/{y}.png"
120
+ attribution='&copy; Thunderforest'
121
+ />
122
+ ```
123
+
124
+ ---
125
+
126
+ ### 3. `<Marker />`
127
+ Adds a standard or custom icon marker to the map.
128
+
129
+ | Prop | Type | Default | Description |
130
+ | :--- | :--- | :--- | :--- |
131
+ | `id` | `string` | - | Unique identifier for the marker. |
132
+ | `position` | `LatLng` | - | Coordinates for placement. |
133
+ | `title` | `string` | - | Text shown in a popup when tapped. |
134
+ | `icon` | `string` | - | Can be an Emoji, remote URL, or HTML string. |
135
+ | `size` | `[number, number]` | `[32, 32]` | Icon dimensions. |
136
+
137
+ **Example:**
138
+ ```tsx
139
+ <Marker
140
+ id="main-pin"
141
+ position={{ lat: 28.6139, lng: 77.2090 }}
142
+ icon="⭐"
143
+ title="New Delhi Capital"
144
+ size={[40, 40]}
145
+ />
146
+ ```
147
+
148
+ ---
149
+
150
+ ### 4. `<Polyline />`
151
+ Draws paths or routes on the map.
152
+
153
+ | Prop | Type | Default | Description |
154
+ | :--- | :--- | :--- | :--- |
155
+ | `id` | `string` | - | Unique identifier. |
156
+ | `positions` | `LatLng[]` | - | Array of coordinates defining the path. |
157
+ | `color` | `string` | `#3388ff` | Hex or RGBA color. |
158
+ | `weight` | `number` | `3` | Thickness of the line. |
159
+ | `opacity` | `number` | `1.0` | Transparency (0 to 1). |
160
+ | `dashArray` | `string` | - | CSS dash pattern (e.g. "5, 10"). |
161
+ | `isAnimated` | `boolean` | `false` | Enable a flowing route animation. |
162
+
163
+ **Regular Example:**
164
+ ```tsx
165
+ <Polyline
166
+ id="route-1"
167
+ positions={pathCoordinates}
168
+ color="#e74c3c"
169
+ weight={5}
170
+ />
171
+ ```
172
+
173
+ **Animated (Flowing) Example:**
174
+ ```tsx
175
+ <Polyline
176
+ id="moving-route"
177
+ positions={pathCoordinates}
178
+ color="#2ecc71"
179
+ isAnimated={true}
180
+ />
181
+ ```
182
+
183
+ ---
184
+
185
+ ### 5. `<UserMarker />`
186
+ A specialized premium component for real-time user positioning.
187
+
188
+ | Prop | Type | Description |
189
+ | :--- | :--- | :--- |
190
+ | `position` | `LatLng` | Real-time coordinates. |
191
+ | `heading` | `number` | Heading in degrees (0 = North). |
192
+ | `accuracy` | `number` | Circular accuracy radius in meters. |
193
+ | `markerColor`| `string` | The primary theme color for the pulse and cone. |
194
+ | `style` | `UserLocationStyle` | Deep customization (see below). |
195
+
196
+ **Example:**
197
+ ```tsx
198
+ <UserMarker
199
+ position={userPos}
200
+ heading={90}
201
+ accuracy={25}
202
+ markerColor="#2ecc71"
203
+ style={{
204
+ markerSize: 15,
205
+ showPulse: true,
206
+ pulseMaxScale: 3,
207
+ showDirectionCone: true,
208
+ coneOpacity: 0.4
209
+ }}
210
+ />
211
+ ```
212
+
213
+ ---
214
+
215
+ ### 6. `<Popup />`
216
+ Enables rich HTML content and professional styling inside a `Marker`. Must be a child of `<Marker />`.
217
+
218
+ | Prop | Type | Default | Description |
219
+ | :--- | :--- | :--- | :--- |
220
+ | `content` | `string` | - | (Optional) HTML string content. |
221
+ | `style` | `PopupStyle`| - | Nested object for visual styling (see below). |
222
+ | `autoPan` | `boolean` | `true` | Whether the map should pan to fit the popup. |
223
+ | `offset` | `[number, number]` | `[0, 7]` | Tip-to-anchor offset. |
224
+
225
+ #### `PopupStyle` Properties
226
+ | Property | Type | Description |
227
+ | :--- | :--- | :--- |
228
+ | `backgroundColor` | `string` | Popup background color. |
229
+ | `textColor` | `string` | Text color. |
230
+ | `borderRadius` | `number` | Corner roundness in pixels. |
231
+ | `padding` | `number` | Inner spacing in pixels. |
232
+ | `fontSize` | `number` | Text size in pixels. |
233
+ | `fontWeight` | `string/number`| Text weight. |
234
+ | `maxWidth` | `number` | Maximum width of the popup. |
235
+ | `closeButtonColor`| `string` | Color of the close 'X' button. |
236
+
237
+ **Example:**
238
+ ```tsx
239
+ <Marker id="premium-shop" position={pos}>
240
+ <Popup
241
+ style={{
242
+ backgroundColor: "#2c3e50",
243
+ textColor: "#ecf0f1",
244
+ borderRadius: 8,
245
+ padding: 12,
246
+ fontSize: 14
247
+ }}
248
+ offset={[0, 10]}
249
+ >
250
+ <b>Metride Premium Hub</b><br/>
251
+ Authorized Reseller
252
+ </Popup>
253
+ </Marker>
254
+ ```
255
+
256
+ ---
257
+
258
+ ### 7. `<Circle />`
259
+ Highlights a circular radius on the map.
260
+
261
+ | Prop | Type | Description |
262
+ | :--- | :--- | :--- |
263
+ | `id` | `string` | Unique ID. |
264
+ | `center` | `LatLng` | Center of the circle. |
265
+ | `radius` | `number` | Radius in meters. |
266
+ | `color` | `string` | Border color. |
267
+ | `fillColor` | `string` | Fill color. |
268
+
269
+ **Example:**
270
+ ```tsx
271
+ <Circle
272
+ id="danger-zone"
273
+ center={{ lat: 28.7041, lng: 77.1025 }}
274
+ radius={500}
275
+ color="red"
276
+ fillColor="rgba(255, 0, 0, 0.2)"
277
+ />
278
+ ```
279
+
280
+ ---
281
+
282
+ ### 8. `<Polygon />`
283
+ Defines a specific area or boundary.
284
+
285
+ | Prop | Type | Description |
286
+ | :--- | :--- | :--- |
287
+ | `id` | `string` | Unique ID. |
288
+ | `positions` | `LatLng[]` | Array of coordinates defining the area. |
289
+ | `color` | `string` | Border color. |
290
+ | `fillColor` | `string` | Fill color. |
291
+
292
+ **Example:**
293
+ ```
294
+
295
+ ---
296
+
297
+ ### 9. `<GeoJSON />`
298
+ The standard for complex spatial data. Renders entire datasets (lines, points, polygons) from a single JSON.
299
+
300
+ | Prop | Type | Description |
301
+ | :--- | :--- | :--- |
302
+ | `id` | `string` | Unique ID. |
303
+ | `data` | `object` | The GeoJSON object/file content. |
304
+ | `style` | `object` | Styling function or object for the features. |
305
+
306
+ **Example:**
307
+ ```tsx
308
+ <GeoJSON
309
+ id="metro-network"
310
+ data={delhiMetroGeoJSON}
311
+ style={{ color: '#ff7800', weight: 5, opacity: 0.65 }}
312
+ />
313
+ ```
314
+
315
+ ---
316
+
317
+ ### 10. `<MarkerCluster />`
318
+ Optimizes performance and readability by grouping nearby markers.
319
+
320
+ | Prop | Type | Description |
321
+ | :--- | :--- | :--- |
322
+ | `options` | `object` | Leaflet.markercluster configuration. |
323
+ | `children` | `ReactNode` | The markers to be clustered. |
324
+
325
+ **Example:**
326
+ ```tsx
327
+ <MarkerCluster options={{ maxClusterRadius: 80 }}>
328
+ {stations.map(s => <Marker key={s.id} {...s} />)}
329
+ </MarkerCluster>
330
+ ```
331
+
332
+ ---
333
+
334
+ ### 11. `<Heatmap />`
335
+ Visualizes data density (e.g., peak hour congestion).
336
+
337
+ | Prop | Type | Description |
338
+ | :--- | :--- | :--- |
339
+ | `id` | `string` | Unique ID. |
340
+ | `points` | `LatlngIntensity[]` | Array of `{ lat, lng, intensity }`. |
341
+ | `radius` | `number` | Size of the heat points. |
342
+ | `blur` | `number` | Softness of the heat edges. |
343
+
344
+ **Example:**
345
+ ```tsx
346
+ <Heatmap
347
+ id="congestion-map"
348
+ points={trafficData}
349
+ radius={30}
350
+ blur={15}
351
+ />
352
+ ```
353
+
354
+ ---
355
+
356
+ ## 🎨 Professional Customization (UserLocationStyle)
357
+
358
+ | Property | Default | Description |
359
+ | :--- | :--- | :--- |
360
+ | `markerSize` | `12` | Inner dot size in pixels. |
361
+ | `showPulse` | `true` | Toggles the radiating pulse animation. |
362
+ | `pulseDuration` | `2.5s` | Speed of the pulse animation. |
363
+ | `pulseMaxScale` | `2.5` | How large the pulse expands. |
364
+ | `showDirectionCone`| `true` | Toggles the field-of-view cone. |
365
+ | `coneWidth` | `60` | Width of the direction cone. |
366
+ | `coneHeight` | `50` | Length of the direction cone. |
367
+
368
+ ---
369
+
370
+ ## 🎥 Camera & Interaction Model
371
+
372
+ Our map utilizes a professional state-driven camera system designed to balance automation with user control.
373
+
374
+ ### 1. The Priority Priority Engine
375
+ When `fitBounds` is active, the map follows a context-aware hierarchy during initial load:
376
+ - **Priority 1: The Route (Hero)** - If markers or paths exist, the map frames them perfectly while excluding the user (if distant) to keep the journey as the main focus.
377
+ - **Priority 2: The User (Fallback)** - If the map is empty, it centers on the user at a comfortable street-level zoom (Level 15).
378
+
379
+ ### 2. Gesture-Aware Automation
380
+ - **Auto-Pause**: If a user performs a manual gesture (pan, zoom, pinch), the map **immediately disables** automatic camera movements to prevent "fighting" the user.
381
+ - **Recenter Pattern**: Developers can use the `onUserGesture` callback to show a "Recenter" button. When clicked, setting `fitBounds={true}` will snap the camera back to the optimal view.
382
+
383
+ ### 3. Debounced Handshake
384
+ To prevent "jitter" during data loading, the camera wait **200ms** after the first piece of data arrives before performing the initial fit. This ensures that all markers and polylines have registered through the bridge for a perfect single-frame fit.
385
+
386
+ ---
387
+
388
+ ## 📜 License
389
+
390
+ MIT License
391
+
392
+ Copyright (c) 2026 Ashish Pradhan
393
+
394
+ Permission is hereby granted, free of charge, to any person obtaining a copy
395
+ of this software and associated documentation files (the "Software"), to deal
396
+ in the Software without restriction, including without limitation the rights
397
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
398
+ copies of the Software, and to permit persons to whom the Software is
399
+ furnished to do so, subject to the following conditions:
400
+
401
+ The above copyright notice and this permission notice shall be included in all
402
+ copies or substantial portions of the Software.
403
+
404
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
405
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
406
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
407
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
408
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
409
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
410
+ SOFTWARE.
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { CircleProps } from '../types';
3
+ export declare const Circle: React.FC<CircleProps>;
4
+ //# sourceMappingURL=Circle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Circle.d.ts","sourceRoot":"","sources":["../../src/components/Circle.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAEzC,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEvC,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAcxC,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { useEffect } from 'react';
2
+ import { useMap } from '../context/MapContext';
3
+ export const Circle = (props) => {
4
+ const { registerLayer, unregisterLayer, updateLayer } = useMap();
5
+ const { id, center, radius, color, fillColor, fillOpacity, weight } = props;
6
+ useEffect(() => {
7
+ registerLayer('circle', id, { center, radius, color, fillColor, fillOpacity, weight });
8
+ return () => unregisterLayer('circle', id);
9
+ }, []);
10
+ useEffect(() => {
11
+ updateLayer('circle', id, { center, radius, color, fillColor, fillOpacity, weight });
12
+ }, [id, center.lat, center.lng, radius, color, fillColor, fillOpacity, weight]);
13
+ return null;
14
+ };
15
+ //# sourceMappingURL=Circle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Circle.js","sourceRoot":"","sources":["../../src/components/Circle.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAG/C,MAAM,CAAC,MAAM,MAAM,GAA0B,CAAC,KAAK,EAAE,EAAE;IACnD,MAAM,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,GAAG,MAAM,EAAE,CAAC;IACjE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IAE5E,SAAS,CAAC,GAAG,EAAE;QACX,aAAa,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;QACvF,OAAO,GAAG,EAAE,CAAC,eAAe,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC/C,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,SAAS,CAAC,GAAG,EAAE;QACX,WAAW,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;IACzF,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;IAEhF,OAAO,IAAI,CAAC;AAChB,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { GeoJSONProps } from '../types';
3
+ export declare const GeoJSON: React.FC<GeoJSONProps>;
4
+ //# sourceMappingURL=GeoJSON.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GeoJSON.d.ts","sourceRoot":"","sources":["../../src/components/GeoJSON.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAEzC,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,eAAO,MAAM,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CAa1C,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { useEffect } from 'react';
2
+ import { useMap } from '../context/MapContext';
3
+ export const GeoJSON = ({ id, data, style, onPress }) => {
4
+ const { registerLayer, unregisterLayer, updateLayer } = useMap();
5
+ useEffect(() => {
6
+ registerLayer('geojson', id, { data, style });
7
+ return () => unregisterLayer('geojson', id);
8
+ }, []);
9
+ useEffect(() => {
10
+ updateLayer('geojson', id, { data, style });
11
+ }, [id, data, style]);
12
+ return null;
13
+ };
14
+ //# sourceMappingURL=GeoJSON.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GeoJSON.js","sourceRoot":"","sources":["../../src/components/GeoJSON.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAG/C,MAAM,CAAC,MAAM,OAAO,GAA2B,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE;IAC5E,MAAM,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,GAAG,MAAM,EAAE,CAAC;IAEjE,SAAS,CAAC,GAAG,EAAE;QACX,aAAa,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC9C,OAAO,GAAG,EAAE,CAAC,eAAe,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAChD,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,SAAS,CAAC,GAAG,EAAE;QACX,WAAW,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAChD,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;IAEtB,OAAO,IAAI,CAAC;AAChB,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { HeatmapProps } from '../types';
3
+ export declare const Heatmap: React.FC<HeatmapProps>;
4
+ //# sourceMappingURL=Heatmap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Heatmap.d.ts","sourceRoot":"","sources":["../../src/components/Heatmap.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAEzC,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,eAAO,MAAM,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CAa1C,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { useEffect } from 'react';
2
+ import { useMap } from '../context/MapContext';
3
+ export const Heatmap = ({ id, points, radius, blur, max }) => {
4
+ const { registerLayer, unregisterLayer, updateLayer } = useMap();
5
+ useEffect(() => {
6
+ registerLayer('heatmap', id, { points, radius, blur, max });
7
+ return () => unregisterLayer('heatmap', id);
8
+ }, []);
9
+ useEffect(() => {
10
+ updateLayer('heatmap', id, { points, radius, blur, max });
11
+ }, [id, points, radius, blur, max]);
12
+ return null;
13
+ };
14
+ //# sourceMappingURL=Heatmap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Heatmap.js","sourceRoot":"","sources":["../../src/components/Heatmap.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAG/C,MAAM,CAAC,MAAM,OAAO,GAA2B,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE;IACjF,MAAM,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,GAAG,MAAM,EAAE,CAAC;IAEjE,SAAS,CAAC,GAAG,EAAE;QACX,aAAa,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5D,OAAO,GAAG,EAAE,CAAC,eAAe,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAChD,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,SAAS,CAAC,GAAG,EAAE;QACX,WAAW,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;IAC9D,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;IAEpC,OAAO,IAAI,CAAC;AAChB,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { MapContainerProps, LatLng } from '../types';
3
+ export interface MapContainerHandles {
4
+ fitBounds: (options?: any) => void;
5
+ centerToUserPosition: (position: LatLng) => void;
6
+ isUserPositionCentered: (position: LatLng) => boolean;
7
+ }
8
+ export declare const MapContainer: React.ForwardRefExoticComponent<MapContainerProps & React.RefAttributes<MapContainerHandles>>;
9
+ //# sourceMappingURL=MapContainer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MapContainer.d.ts","sourceRoot":"","sources":["../../src/components/MapContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAMxE,OAAO,EAAE,iBAAiB,EAA6B,MAAM,EAAE,MAAM,UAAU,CAAC;AAGhF,MAAM,WAAW,mBAAmB;IAChC,SAAS,EAAE,CAAC,OAAO,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IACnC,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,sBAAsB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;CACzD;AAED,eAAO,MAAM,YAAY,+FA6GvB,CAAC"}
@@ -0,0 +1,86 @@
1
+ import React, { useState, useRef, useCallback } from 'react';
2
+ import { StyleSheet, View } from 'react-native';
3
+ import { WebView } from 'react-native-webview';
4
+ import MapContext from '../context/MapContext';
5
+ import { LEAFLET_HTML_CONTENT } from '../templates/LeafletHTML';
6
+ import { isEqual } from '../utils/deepEqual';
7
+ import { MapViewEvents } from '../types';
8
+ export const MapContainer = React.forwardRef(({ center, zoom = 13, isDark = false, backgroundColor = '#ffffff', dragEnabled = true, zoomEnabled = true, fitBounds = false, style, children, onMapReady, onMapClick, onMarkerClick, onUserGesture, onMoveEnd, }, ref) => {
9
+ const webViewRef = useRef(null);
10
+ const [isReady, setIsReady] = useState(false);
11
+ const [mapCenter, setMapCenter] = useState(center || null);
12
+ const sendMessage = useCallback((payload) => {
13
+ webViewRef.current?.injectJavaScript(`window.postMessage(${JSON.stringify(payload)}, '*');`);
14
+ }, []);
15
+ React.useImperativeHandle(ref, () => ({
16
+ fitBounds: (options) => {
17
+ sendMessage({ type: 'fitBounds', options });
18
+ },
19
+ centerToUserPosition: (pos) => {
20
+ sendMessage({ type: 'center', position: pos });
21
+ },
22
+ isUserPositionCentered: (pos) => {
23
+ if (!mapCenter)
24
+ return false;
25
+ return isEqual(mapCenter, pos);
26
+ }
27
+ }));
28
+ const handleMessage = (event) => {
29
+ try {
30
+ const data = JSON.parse(event.nativeEvent.data);
31
+ switch (data.event) {
32
+ case MapViewEvents.MAP_READY:
33
+ setIsReady(true);
34
+ sendMessage({ type: 'init', center, zoom, isDark, background: backgroundColor, fitBounds });
35
+ onMapReady?.();
36
+ break;
37
+ case MapViewEvents.ON_MOVE_END:
38
+ setMapCenter(data.payload.mapCenterPosition);
39
+ onMoveEnd?.(data.payload.mapCenterPosition, data.payload.zoom, data.payload.bounds);
40
+ break;
41
+ case MapViewEvents.ON_MAP_CLICK:
42
+ onMapClick?.(data.payload.latlng);
43
+ break;
44
+ case MapViewEvents.ON_MARKER_CLICK:
45
+ onMarkerClick?.(data.payload.id);
46
+ break;
47
+ case MapViewEvents.ON_USER_GESTURE:
48
+ onUserGesture?.();
49
+ break;
50
+ }
51
+ }
52
+ catch (e) {
53
+ console.error('Error parsing map message:', e);
54
+ }
55
+ };
56
+ const registerLayer = (type, id, props) => {
57
+ sendMessage({ type, id, ...props });
58
+ };
59
+ const unregisterLayer = (type, id) => {
60
+ sendMessage({ type: `remove_${type}`, id });
61
+ };
62
+ const updateLayer = (type, id, props) => {
63
+ sendMessage({ type, id, ...props });
64
+ };
65
+ React.useEffect(() => {
66
+ if (isReady) {
67
+ sendMessage({ type: 'theme', isDark, background: backgroundColor });
68
+ sendMessage({ type: 'fit_bounds_toggle', enabled: fitBounds });
69
+ }
70
+ }, [isDark, backgroundColor, fitBounds, isReady]);
71
+ return (<MapContext.Provider value={{ registerLayer, unregisterLayer, updateLayer, sendMessage }}>
72
+ <View style={[styles.container, style]}>
73
+ <WebView ref={webViewRef} source={{ html: LEAFLET_HTML_CONTENT }} style={[styles.webview, { backgroundColor: backgroundColor || 'transparent' }]} containerStyle={{ backgroundColor: backgroundColor || 'transparent' }} onMessage={handleMessage} javaScriptEnabled={true} domStorageEnabled={true} startInLoadingState={true} mixedContentMode="always" originWhitelist={['*']} bounces={false} scrollEnabled={false} overScrollMode="never"/>
74
+ {isReady && children}
75
+ </View>
76
+ </MapContext.Provider>);
77
+ });
78
+ const styles = StyleSheet.create({
79
+ container: {
80
+ flex: 1,
81
+ },
82
+ webview: {
83
+ flex: 1,
84
+ },
85
+ });
86
+ //# sourceMappingURL=MapContainer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MapContainer.js","sourceRoot":"","sources":["../../src/components/MapContainer.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { MarkerProps, PopupProps } from '../types';
3
+ export declare const useMarker: () => {
4
+ setPopupOptions: (options: Partial<PopupProps>) => void;
5
+ } | null;
6
+ export declare const Marker: React.FC<MarkerProps>;
7
+ //# sourceMappingURL=Marker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Marker.d.ts","sourceRoot":"","sources":["../../src/components/Marker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyD,MAAM,OAAO,CAAC;AAE9E,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAMnD,eAAO,MAAM,SAAS;qBAHD,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,KAAK,IAAI;QAGH,CAAC;AAEzD,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAoBxC,CAAC"}
@@ -0,0 +1,20 @@
1
+ import React, { useEffect, useState, createContext, useContext } from 'react';
2
+ import { useMap } from '../context/MapContext';
3
+ const MarkerContext = createContext(null);
4
+ export const useMarker = () => useContext(MarkerContext);
5
+ export const Marker = ({ id, position, icon, size, anchor, title, children }) => {
6
+ const { registerLayer, unregisterLayer, updateLayer } = useMap();
7
+ const [popupOptions, setPopupOptions] = useState({});
8
+ useEffect(() => {
9
+ registerLayer('marker', id, { position, icon, size, anchor, title, ...popupOptions });
10
+ return () => unregisterLayer('marker', id);
11
+ }, []);
12
+ useEffect(() => {
13
+ updateLayer('marker', id, { position, icon, size, anchor, title, ...popupOptions });
14
+ }, [position.lat, position.lng, icon, size, anchor, title, JSON.stringify(popupOptions)]);
15
+ const contextValue = React.useMemo(() => ({ setPopupOptions }), [setPopupOptions]);
16
+ return (<MarkerContext.Provider value={contextValue}>
17
+ {children}
18
+ </MarkerContext.Provider>);
19
+ };
20
+ //# sourceMappingURL=Marker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Marker.js","sourceRoot":"","sources":["../../src/components/Marker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAC9E,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAG/C,MAAM,aAAa,GAAG,aAAa,CAEzB,IAAI,CAAC,CAAC;AAEhB,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAEzD,MAAM,CAAC,MAAM,MAAM,GAA0B,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE;IACnG,MAAM,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,GAAG,MAAM,EAAE,CAAC;IACjE,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAsB,EAAE,CAAC,CAAC;IAE1E,SAAS,CAAC,GAAG,EAAE;QACX,aAAa,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,YAAY,EAAE,CAAC,CAAC;QACtF,OAAO,GAAG,EAAE,CAAC,eAAe,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC/C,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,SAAS,CAAC,GAAG,EAAE;QACX,WAAW,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,YAAY,EAAE,CAAC,CAAC;IACxF,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAE1F,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;IAEnF,OAAO,CACH,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CACxC;YAAA,CAAC,QAAQ,CACb;QAAA,EAAE,aAAa,CAAC,QAAQ,CAAC,CAC5B,CAAC;AACN,CAAC,CAAC"}