@revivejs/react-google-maps 17.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.
- package/LICENSE +21 -0
- package/README.md +271 -0
- package/dist/index.cjs +1834 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +457 -0
- package/dist/index.d.ts +457 -0
- package/dist/index.js +1797 -0
- package/dist/index.js.map +1 -0
- package/package.json +78 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alexandro Marques
|
|
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,271 @@
|
|
|
1
|
+
# @revivejs/react-google-maps
|
|
2
|
+
|
|
3
|
+
> A maintained **React 17 wrapper for Google Maps** with declarative maps, markers, advanced markers, clustering, overlays, directions, geocoding hooks, and versioned live demos.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@revivejs/react-google-maps)
|
|
6
|
+
[](https://www.npmjs.com/package/@revivejs/react-google-maps)
|
|
7
|
+
[](https://github.com/alexandroit/react-google-maps/blob/main/LICENSE)
|
|
8
|
+
[](https://react.dev)
|
|
9
|
+
[](https://developers.google.com/maps/documentation/javascript)
|
|
10
|
+
|
|
11
|
+
**[Documentation & Live Demos](https://alexandroit.github.io/react-google-maps/)** | **[npm](https://www.npmjs.com/package/@revivejs/react-google-maps)** | **[Issues](https://github.com/alexandroit/react-google-maps/issues)** | **[Repository](https://github.com/alexandroit/react-google-maps)**
|
|
12
|
+
|
|
13
|
+
**Latest version:** `17.0.0`
|
|
14
|
+
|
|
15
|
+
## Why this library?
|
|
16
|
+
|
|
17
|
+
`@revivejs/react-google-maps` is built for teams that want the same clarity people liked in the Angular Google Maps package, but in React:
|
|
18
|
+
|
|
19
|
+
- a single provider that loads the Google Maps JavaScript API once
|
|
20
|
+
- a declarative `<GoogleMap>` shell with familiar props like `center`, `zoom`, `mapId`, and `options`
|
|
21
|
+
- component wrappers for markers, advanced markers, info windows, overlays, layers, controls, and directions
|
|
22
|
+
- hooks for service-style flows like geocoding
|
|
23
|
+
- official marker clustering support through `@googlemaps/markerclusterer`
|
|
24
|
+
|
|
25
|
+
The result is intentionally migration-friendly. A complex Angular or imperative Google Maps codebase can usually move over one feature at a time without giving up access to the native map instances.
|
|
26
|
+
|
|
27
|
+
## Extension-friendly by design
|
|
28
|
+
|
|
29
|
+
This package is not a "locked box" wrapper. The components are meant to stay declarative for common usage, while still giving you the same escape hatches teams rely on in Angular:
|
|
30
|
+
|
|
31
|
+
- `ref` handles on `GoogleMap`, `MapMarker`, `MapInfoWindow`, `MapMarkerClusterer`, `MapPolyline`, `MapPolygon`, `MapRectangle`, `MapCircle`, `MapGroundOverlay`, and `MapDirectionsRenderer`
|
|
32
|
+
- `onLoad` callbacks that expose the native Google Maps instances directly
|
|
33
|
+
- `useGoogleMap()` to access the current native `google.maps.Map` from nested React components
|
|
34
|
+
- `useMapGeocoder()` and `useDirectionsService()` for service-style integrations
|
|
35
|
+
|
|
36
|
+
That means you can keep a typed React API for the 90% case and still drop to native Google Maps methods when a complex application needs something custom.
|
|
37
|
+
|
|
38
|
+
## React Version Compatibility
|
|
39
|
+
|
|
40
|
+
| Package version | React version | Google Maps support | Demo link |
|
|
41
|
+
| :---: | :---: | :---: | :--- |
|
|
42
|
+
| **17.0.0** | **17.0.x** | Maps, markers, advanced markers, clustering, shapes, layers, directions, geocoder | [React 17 demo](https://alexandroit.github.io/react-google-maps/react-17/) |
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm install @revivejs/react-google-maps
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Basic Usage
|
|
51
|
+
|
|
52
|
+
```tsx
|
|
53
|
+
import {
|
|
54
|
+
GoogleMap,
|
|
55
|
+
GoogleMapsProvider,
|
|
56
|
+
MapMarker
|
|
57
|
+
} from '@revivejs/react-google-maps';
|
|
58
|
+
|
|
59
|
+
const center = { lat: 40.7128, lng: -74.006 };
|
|
60
|
+
|
|
61
|
+
export function App() {
|
|
62
|
+
return (
|
|
63
|
+
<GoogleMapsProvider apiKey={import.meta.env.VITE_GOOGLE_MAPS_API_KEY} mapIds={['DEMO_MAP_ID']}>
|
|
64
|
+
<GoogleMap center={center} zoom={11} height={420}>
|
|
65
|
+
<MapMarker position={center} title="New York City" />
|
|
66
|
+
</GoogleMap>
|
|
67
|
+
</GoogleMapsProvider>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Advanced Markers
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
import {
|
|
76
|
+
GoogleMap,
|
|
77
|
+
GoogleMapsProvider,
|
|
78
|
+
MapAdvancedMarker
|
|
79
|
+
} from '@revivejs/react-google-maps';
|
|
80
|
+
|
|
81
|
+
export function CapitalMap() {
|
|
82
|
+
return (
|
|
83
|
+
<GoogleMapsProvider apiKey={import.meta.env.VITE_GOOGLE_MAPS_API_KEY} mapIds={['DEMO_MAP_ID']}>
|
|
84
|
+
<GoogleMap center={{ lat: 45.4215, lng: -75.6972 }} zoom={6} mapId="DEMO_MAP_ID" height={420}>
|
|
85
|
+
<MapAdvancedMarker position={{ lat: 45.4215, lng: -75.6972 }}>
|
|
86
|
+
<div style={{ padding: 12, borderRadius: 12, background: 'white' }}>
|
|
87
|
+
<strong>Ottawa</strong>
|
|
88
|
+
<div>Advanced marker content</div>
|
|
89
|
+
</div>
|
|
90
|
+
</MapAdvancedMarker>
|
|
91
|
+
</GoogleMap>
|
|
92
|
+
</GoogleMapsProvider>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Marker Clustering
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
import {
|
|
101
|
+
createClusterRenderer,
|
|
102
|
+
GoogleMap,
|
|
103
|
+
GoogleMapsProvider,
|
|
104
|
+
MapAdvancedMarker,
|
|
105
|
+
MapMarker,
|
|
106
|
+
MapMarkerClusterer
|
|
107
|
+
} from '@revivejs/react-google-maps';
|
|
108
|
+
|
|
109
|
+
const points = [
|
|
110
|
+
{ lat: 37.782, lng: -122.447 },
|
|
111
|
+
{ lat: 37.789, lng: -122.405 },
|
|
112
|
+
{ lat: 37.766, lng: -122.438 }
|
|
113
|
+
];
|
|
114
|
+
|
|
115
|
+
export function ClusteredMap() {
|
|
116
|
+
return (
|
|
117
|
+
<GoogleMapsProvider apiKey={import.meta.env.VITE_GOOGLE_MAPS_API_KEY}>
|
|
118
|
+
<GoogleMap center={{ lat: 37.7749, lng: -122.4194 }} zoom={10} height={420}>
|
|
119
|
+
<MapMarkerClusterer>
|
|
120
|
+
{points.map((point, index) => (
|
|
121
|
+
<MapMarker key={index} position={point} />
|
|
122
|
+
))}
|
|
123
|
+
</MapMarkerClusterer>
|
|
124
|
+
</GoogleMap>
|
|
125
|
+
</GoogleMapsProvider>
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
If you need branded cluster visuals, the wrapper also exposes a helper for HTML or advanced-marker-based cluster rendering:
|
|
131
|
+
|
|
132
|
+
```tsx
|
|
133
|
+
const renderer = createClusterRenderer({
|
|
134
|
+
render: ({ count }) => {
|
|
135
|
+
const element = document.createElement('div');
|
|
136
|
+
element.className = 'cluster-card';
|
|
137
|
+
element.innerHTML = `<strong>${count}</strong><span>places</span>`;
|
|
138
|
+
return element;
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
<MapMarkerClusterer renderer={renderer}>
|
|
143
|
+
<MapAdvancedMarker position={point}>...</MapAdvancedMarker>
|
|
144
|
+
</MapMarkerClusterer>
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Directions
|
|
148
|
+
|
|
149
|
+
```tsx
|
|
150
|
+
import { useState } from 'react';
|
|
151
|
+
import {
|
|
152
|
+
GoogleMap,
|
|
153
|
+
GoogleMapsProvider,
|
|
154
|
+
MapDirectionsRenderer,
|
|
155
|
+
MapDirectionsService
|
|
156
|
+
} from '@revivejs/react-google-maps';
|
|
157
|
+
|
|
158
|
+
export function DirectionsDemo() {
|
|
159
|
+
const [directions, setDirections] = useState<google.maps.DirectionsResult | null>(null);
|
|
160
|
+
|
|
161
|
+
return (
|
|
162
|
+
<GoogleMapsProvider apiKey={import.meta.env.VITE_GOOGLE_MAPS_API_KEY}>
|
|
163
|
+
<GoogleMap center={{ lat: 45.4215, lng: -75.6972 }} zoom={6} height={420}>
|
|
164
|
+
<MapDirectionsService
|
|
165
|
+
request={{
|
|
166
|
+
origin: 'Toronto, ON',
|
|
167
|
+
destination: 'Montreal, QC',
|
|
168
|
+
travelMode: 'DRIVING' as google.maps.TravelMode
|
|
169
|
+
}}
|
|
170
|
+
onResult={({ result }) => setDirections(result ?? null)}
|
|
171
|
+
/>
|
|
172
|
+
<MapDirectionsRenderer directions={directions} />
|
|
173
|
+
</GoogleMap>
|
|
174
|
+
</GoogleMapsProvider>
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Geocoding Hook
|
|
180
|
+
|
|
181
|
+
```tsx
|
|
182
|
+
import { useState } from 'react';
|
|
183
|
+
import {
|
|
184
|
+
GoogleMap,
|
|
185
|
+
GoogleMapsProvider,
|
|
186
|
+
MapMarker,
|
|
187
|
+
useMapGeocoder
|
|
188
|
+
} from '@revivejs/react-google-maps';
|
|
189
|
+
|
|
190
|
+
function GeocoderInner() {
|
|
191
|
+
const geocoder = useMapGeocoder();
|
|
192
|
+
const [center, setCenter] = useState({ lat: 43.6532, lng: -79.3832 });
|
|
193
|
+
|
|
194
|
+
async function geocodeAddress() {
|
|
195
|
+
const response = await geocoder?.geocode({ address: 'Toronto City Hall' });
|
|
196
|
+
const first = response?.results[0];
|
|
197
|
+
if (first?.geometry.location) {
|
|
198
|
+
setCenter(first.geometry.location.toJSON());
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return (
|
|
203
|
+
<>
|
|
204
|
+
<button onClick={geocodeAddress}>Geocode</button>
|
|
205
|
+
<GoogleMap center={center} zoom={14} height={420}>
|
|
206
|
+
<MapMarker position={center} />
|
|
207
|
+
</GoogleMap>
|
|
208
|
+
</>
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export function GeocoderDemo() {
|
|
213
|
+
return (
|
|
214
|
+
<GoogleMapsProvider apiKey={import.meta.env.VITE_GOOGLE_MAPS_API_KEY}>
|
|
215
|
+
<GeocoderInner />
|
|
216
|
+
</GoogleMapsProvider>
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Main API
|
|
222
|
+
|
|
223
|
+
| Surface | Notes |
|
|
224
|
+
| :--- | :--- |
|
|
225
|
+
| `GoogleMapsProvider` | Loads the API once and shares readiness through context. |
|
|
226
|
+
| `GoogleMap` | Creates the native `google.maps.Map` and supports refs for imperative access. |
|
|
227
|
+
| `MapMarker` | Thin wrapper around `google.maps.Marker`. |
|
|
228
|
+
| `MapAdvancedMarker` | Thin wrapper around `google.maps.marker.AdvancedMarkerElement`. |
|
|
229
|
+
| `MapInfoWindow` | Declarative info window with React content via portal. |
|
|
230
|
+
| `MapMarkerClusterer` | Official clustering through `@googlemaps/markerclusterer`. |
|
|
231
|
+
| `MapPolyline`, `MapPolygon`, `MapRectangle`, `MapCircle` | Declarative shape overlays. |
|
|
232
|
+
| `MapGroundOverlay`, `MapKmlLayer`, `MapHeatmapLayer` | Common overlays and layers. |
|
|
233
|
+
| `MapTrafficLayer`, `MapTransitLayer`, `MapBicyclingLayer` | Built-in transportation layers. |
|
|
234
|
+
| `MapDirectionsService`, `MapDirectionsRenderer` | Declarative routing request + display flow. |
|
|
235
|
+
| `useMapGeocoder()` | Memoized geocoder hook. |
|
|
236
|
+
| `useDirectionsService()` | Memoized directions service hook. |
|
|
237
|
+
| `useGoogleMap()` | Access the native `google.maps.Map` from nested components. |
|
|
238
|
+
| `MapControl` | Mount React UI inside native map control positions. |
|
|
239
|
+
|
|
240
|
+
## Docs Coverage
|
|
241
|
+
|
|
242
|
+
The live docs are intentionally rich and mirror the kinds of workflows developers look for in the official Google Maps documentation:
|
|
243
|
+
|
|
244
|
+
- basic map bootstrapping
|
|
245
|
+
- controlled center and zoom
|
|
246
|
+
- click events
|
|
247
|
+
- markers and info windows
|
|
248
|
+
- advanced markers
|
|
249
|
+
- draggable markers
|
|
250
|
+
- marker clustering
|
|
251
|
+
- polylines, polygons, rectangles, circles
|
|
252
|
+
- ground overlays
|
|
253
|
+
- traffic, transit, and bicycling layers
|
|
254
|
+
- KML layers
|
|
255
|
+
- heatmaps
|
|
256
|
+
- directions
|
|
257
|
+
- geocoding
|
|
258
|
+
- custom map controls
|
|
259
|
+
|
|
260
|
+
## Changelog
|
|
261
|
+
|
|
262
|
+
### 19.0.0
|
|
263
|
+
- Initial React 19 line
|
|
264
|
+
- Added versioned docs for React 17, 18, and 19
|
|
265
|
+
- Added declarative wrappers for maps, markers, advanced markers, clustering, shapes, layers, directions, and geocoding
|
|
266
|
+
|
|
267
|
+
### 18.0.0
|
|
268
|
+
- React 18 compatibility line
|
|
269
|
+
|
|
270
|
+
### 17.0.0
|
|
271
|
+
- React 17 compatibility line
|