@ttoss/google-maps 2.0.9 → 2.1.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/README.md +62 -2
- package/dist/esm/index.js +53 -25
- package/dist/index.d.ts +8 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -10,13 +10,19 @@ Install `@ttoss/google-maps` in your project:
|
|
|
10
10
|
$ pnpm add @ttoss/google-maps
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
If you use TypeScript,
|
|
13
|
+
If you use TypeScript, install the types for Google Maps:
|
|
14
|
+
|
|
15
|
+
```shell
|
|
16
|
+
$ pnpm add -D @types/google.maps
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Then, add the following to a declaration file (generally `typings.d.ts`):
|
|
14
20
|
|
|
15
21
|
```typescript title="typings.d.ts"
|
|
16
22
|
/// <reference types="google.maps" />
|
|
17
23
|
```
|
|
18
24
|
|
|
19
|
-
##
|
|
25
|
+
## Getting Started
|
|
20
26
|
|
|
21
27
|
### Configuring `GoogleMapsProvider`
|
|
22
28
|
|
|
@@ -83,6 +89,8 @@ const MyComponent = () => {
|
|
|
83
89
|
|
|
84
90
|
With this, you can perform any operation that the `google.maps` object allows, such as creating markers, drawing polygons, etc.
|
|
85
91
|
|
|
92
|
+
## Advanced Usage
|
|
93
|
+
|
|
86
94
|
### Using with Next.js (custom Script component)
|
|
87
95
|
|
|
88
96
|
If you use Next.js, you can use the `GoogleMapsProvider` passing [Next.js `Script`](https://nextjs.org/docs/app/api-reference/components/script) component as a prop:
|
|
@@ -105,6 +113,44 @@ const App = ({ children }) => {
|
|
|
105
113
|
};
|
|
106
114
|
```
|
|
107
115
|
|
|
116
|
+
### Reusing `map` object
|
|
117
|
+
|
|
118
|
+
If you need to access the `map` object in multiple components, you can use `MapProvider` to share it:
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
import { MapProvider, useMap } from '@ttoss/google-maps';
|
|
122
|
+
|
|
123
|
+
const ChildComponent = () => {
|
|
124
|
+
// Access the map object created by the parent component
|
|
125
|
+
const { map } = useMap();
|
|
126
|
+
|
|
127
|
+
React.useEffect(() => {
|
|
128
|
+
if (map) {
|
|
129
|
+
map.setOptions({
|
|
130
|
+
center: { lat: -34.397, lng: 150.644 },
|
|
131
|
+
zoom: 8,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}, [map]);
|
|
135
|
+
|
|
136
|
+
return null;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const ParentComponent = () => {
|
|
140
|
+
const { ref, map } = useMap();
|
|
141
|
+
|
|
142
|
+
return (
|
|
143
|
+
<MapProvider map={map} ref={ref}>
|
|
144
|
+
<Box>
|
|
145
|
+
<Text>My Map</Text>
|
|
146
|
+
<Box ref={ref} sx={{ height, width }} />
|
|
147
|
+
<ChildComponent />
|
|
148
|
+
</Box>
|
|
149
|
+
</MapProvider>
|
|
150
|
+
);
|
|
151
|
+
};
|
|
152
|
+
```
|
|
153
|
+
|
|
108
154
|
## API
|
|
109
155
|
|
|
110
156
|
### `GoogleMapsProvider`
|
|
@@ -117,8 +163,18 @@ const App = ({ children }) => {
|
|
|
117
163
|
- `Script`: React.ComponentType - Custom `Script` component to use.
|
|
118
164
|
- `onError`: (error: Error) => void - Callback to handle script loading errors.
|
|
119
165
|
|
|
166
|
+
### `MapProvider`
|
|
167
|
+
|
|
168
|
+
#### Props
|
|
169
|
+
|
|
170
|
+
- `map`: google.maps.Map | null - Google Maps object.
|
|
171
|
+
- `children`: React.ReactNode - Children to render.
|
|
172
|
+
- `ref`: React.RefObject<HTMLDivElement> - Reference to the map container.
|
|
173
|
+
|
|
120
174
|
### `useMap`
|
|
121
175
|
|
|
176
|
+
`useMap` is a hook that returns a reference to the map container and the Google Maps object. It creates a new map object if it doesn't exist or returns the existing map if `MapProvider` wraps the component tree.
|
|
177
|
+
|
|
122
178
|
#### Returns
|
|
123
179
|
|
|
124
180
|
- `ref`: `React.RefObject<HTMLDivElement>` - Reference to the map container.
|
|
@@ -131,3 +187,7 @@ const App = ({ children }) => {
|
|
|
131
187
|
- `google`: typeof google - `google.maps` object.
|
|
132
188
|
- `status`: 'idle' | 'error' | 'loading' | 'ready' - Status of the script loading.
|
|
133
189
|
- `isReady`: boolean - Whether the script is ready. The same as `status === 'ready'`.
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
```
|
package/dist/esm/index.js
CHANGED
|
@@ -27,13 +27,17 @@ var DefaultScript = ({
|
|
|
27
27
|
var GoogleMapsProvider = ({
|
|
28
28
|
children,
|
|
29
29
|
apiKey,
|
|
30
|
+
loading = "async",
|
|
30
31
|
libraries,
|
|
31
32
|
language,
|
|
32
33
|
Script = DefaultScript,
|
|
33
34
|
onError
|
|
34
35
|
}) => {
|
|
35
36
|
const src = (() => {
|
|
36
|
-
let srcTemp = `https://maps.googleapis.com/maps/api/js?key=${apiKey}
|
|
37
|
+
let srcTemp = `https://maps.googleapis.com/maps/api/js?key=${apiKey}`;
|
|
38
|
+
if (loading) {
|
|
39
|
+
srcTemp = srcTemp + `&loading=${loading}`;
|
|
40
|
+
}
|
|
37
41
|
if (libraries) {
|
|
38
42
|
srcTemp = srcTemp + `&libraries=${libraries.join(",")}`;
|
|
39
43
|
}
|
|
@@ -79,16 +83,39 @@ var GoogleMapsProvider = ({
|
|
|
79
83
|
});
|
|
80
84
|
};
|
|
81
85
|
|
|
86
|
+
// src/MapProvider.tsx
|
|
87
|
+
import * as React2 from "react";
|
|
88
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
89
|
+
var MapContext = React2.createContext({
|
|
90
|
+
map: null,
|
|
91
|
+
ref: {
|
|
92
|
+
current: null
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
var MapProvider = React2.forwardRef(({
|
|
96
|
+
children,
|
|
97
|
+
map
|
|
98
|
+
}, ref) => {
|
|
99
|
+
return /* @__PURE__ */jsx2(MapContext.Provider, {
|
|
100
|
+
value: {
|
|
101
|
+
map,
|
|
102
|
+
ref
|
|
103
|
+
},
|
|
104
|
+
children
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
MapProvider.displayName = "MapProvider";
|
|
108
|
+
|
|
82
109
|
// src/useGeocoder.ts
|
|
83
|
-
import * as
|
|
110
|
+
import * as React4 from "react";
|
|
84
111
|
|
|
85
112
|
// src/useGoogleMaps.ts
|
|
86
|
-
import * as
|
|
113
|
+
import * as React3 from "react";
|
|
87
114
|
var useGoogleMaps = () => {
|
|
88
115
|
const {
|
|
89
116
|
status,
|
|
90
117
|
google
|
|
91
|
-
} =
|
|
118
|
+
} = React3.useContext(GoogleMapsContext);
|
|
92
119
|
const isReady = status === "ready";
|
|
93
120
|
return {
|
|
94
121
|
isReady,
|
|
@@ -106,8 +133,8 @@ var useGeocoder = () => {
|
|
|
106
133
|
const {
|
|
107
134
|
google
|
|
108
135
|
} = useGoogleMaps();
|
|
109
|
-
const [isGeocoderInitialized, setIsGeocoderInitialized] =
|
|
110
|
-
const geocoder =
|
|
136
|
+
const [isGeocoderInitialized, setIsGeocoderInitialized] = React4.useState(false);
|
|
137
|
+
const geocoder = React4.useMemo(() => {
|
|
111
138
|
if (google.maps) {
|
|
112
139
|
const googleMapsGeocoder = new google.maps.Geocoder();
|
|
113
140
|
setIsGeocoderInitialized(true);
|
|
@@ -122,10 +149,10 @@ var useGeocoder = () => {
|
|
|
122
149
|
};
|
|
123
150
|
|
|
124
151
|
// src/useMap.ts
|
|
125
|
-
import * as
|
|
152
|
+
import * as React5 from "react";
|
|
126
153
|
import { useCallbackRef } from "use-callback-ref";
|
|
127
154
|
var useMap = (options = {}) => {
|
|
128
|
-
const [, forceUpdate] =
|
|
155
|
+
const [, forceUpdate] = React5.useState(0);
|
|
129
156
|
const ref = useCallbackRef(null, () => {
|
|
130
157
|
return forceUpdate(n => {
|
|
131
158
|
return n + 1;
|
|
@@ -135,8 +162,9 @@ var useMap = (options = {}) => {
|
|
|
135
162
|
google,
|
|
136
163
|
isReady
|
|
137
164
|
} = useGoogleMaps();
|
|
138
|
-
const
|
|
139
|
-
|
|
165
|
+
const mapContext = React5.useContext(MapContext);
|
|
166
|
+
const [map, setMap] = React5.useState(mapContext.map);
|
|
167
|
+
React5.useEffect(() => {
|
|
140
168
|
if (map) {
|
|
141
169
|
return;
|
|
142
170
|
}
|
|
@@ -152,7 +180,7 @@ var useMap = (options = {}) => {
|
|
|
152
180
|
setMap(new google.maps.Map(ref.current, options));
|
|
153
181
|
}, [map, isReady, ref, google.maps, options]);
|
|
154
182
|
const optionsStringify = JSON.stringify(options);
|
|
155
|
-
|
|
183
|
+
React5.useEffect(() => {
|
|
156
184
|
if (map) {
|
|
157
185
|
const parsedOptions = JSON.parse(optionsStringify);
|
|
158
186
|
map.setOptions(parsedOptions);
|
|
@@ -172,12 +200,12 @@ var useMap = (options = {}) => {
|
|
|
172
200
|
};
|
|
173
201
|
|
|
174
202
|
// src/usePlacesAutocomplete/index.ts
|
|
175
|
-
import * as
|
|
203
|
+
import * as React7 from "react";
|
|
176
204
|
|
|
177
205
|
// src/usePlacesAutocomplete/useLatest.ts
|
|
178
|
-
import * as
|
|
206
|
+
import * as React6 from "react";
|
|
179
207
|
var useLatest = val => {
|
|
180
|
-
const ref =
|
|
208
|
+
const ref = React6.useRef(val);
|
|
181
209
|
ref.current = val;
|
|
182
210
|
return ref;
|
|
183
211
|
};
|
|
@@ -206,21 +234,21 @@ var usePlacesAutocomplete = ({
|
|
|
206
234
|
defaultValue = "",
|
|
207
235
|
initOnMount = true
|
|
208
236
|
} = {}) => {
|
|
209
|
-
const [ready, setReady] =
|
|
210
|
-
const [value, setVal] =
|
|
211
|
-
const [suggestions, setSuggestions] =
|
|
237
|
+
const [ready, setReady] = React7.useState(false);
|
|
238
|
+
const [value, setVal] = React7.useState(defaultValue);
|
|
239
|
+
const [suggestions, setSuggestions] = React7.useState({
|
|
212
240
|
loading: false,
|
|
213
241
|
status: "",
|
|
214
242
|
data: []
|
|
215
243
|
});
|
|
216
|
-
const asRef =
|
|
244
|
+
const asRef = React7.useRef(null);
|
|
217
245
|
const requestOptionsRef = useLatest(requestOptions);
|
|
218
246
|
const {
|
|
219
247
|
google
|
|
220
248
|
} = useGoogleMaps();
|
|
221
249
|
const googleMapsRef = useLatest(google.maps);
|
|
222
250
|
const upaCacheKey = cacheKey ? `upa-${cacheKey}` : "upa";
|
|
223
|
-
const init =
|
|
251
|
+
const init = React7.useCallback(() => {
|
|
224
252
|
if (asRef.current) {
|
|
225
253
|
return;
|
|
226
254
|
}
|
|
@@ -237,19 +265,19 @@ var usePlacesAutocomplete = ({
|
|
|
237
265
|
asRef.current = new placesLib.AutocompleteService();
|
|
238
266
|
setReady(true);
|
|
239
267
|
}, [google.maps]);
|
|
240
|
-
const clearSuggestions =
|
|
268
|
+
const clearSuggestions = React7.useCallback(() => {
|
|
241
269
|
setSuggestions({
|
|
242
270
|
loading: false,
|
|
243
271
|
status: "",
|
|
244
272
|
data: []
|
|
245
273
|
});
|
|
246
274
|
}, []);
|
|
247
|
-
const clearCache =
|
|
275
|
+
const clearCache = React7.useCallback(() => {
|
|
248
276
|
try {
|
|
249
277
|
sessionStorage.removeItem(upaCacheKey);
|
|
250
278
|
} catch (error) {}
|
|
251
279
|
}, []);
|
|
252
|
-
const fetchPredictions =
|
|
280
|
+
const fetchPredictions = React7.useCallback(debounce_default(val => {
|
|
253
281
|
if (!val) {
|
|
254
282
|
clearSuggestions();
|
|
255
283
|
return;
|
|
@@ -300,13 +328,13 @@ var usePlacesAutocomplete = ({
|
|
|
300
328
|
}
|
|
301
329
|
});
|
|
302
330
|
}, debounce2), [debounce2, clearSuggestions]);
|
|
303
|
-
const setValue =
|
|
331
|
+
const setValue = React7.useCallback((val, shouldFetchData = true) => {
|
|
304
332
|
setVal(val);
|
|
305
333
|
if (asRef.current && shouldFetchData) {
|
|
306
334
|
fetchPredictions(val);
|
|
307
335
|
}
|
|
308
336
|
}, [fetchPredictions]);
|
|
309
|
-
|
|
337
|
+
React7.useEffect(() => {
|
|
310
338
|
if (!initOnMount) {
|
|
311
339
|
return () => {
|
|
312
340
|
return null;
|
|
@@ -333,4 +361,4 @@ var usePlacesAutocomplete = ({
|
|
|
333
361
|
init
|
|
334
362
|
};
|
|
335
363
|
};
|
|
336
|
-
export { GoogleMapsProvider, useGeocoder, useGoogleMaps, useMap, usePlacesAutocomplete };
|
|
364
|
+
export { GoogleMapsProvider, MapProvider, useGeocoder, useGoogleMaps, useMap, usePlacesAutocomplete };
|
package/dist/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ type ScriptProps = {
|
|
|
8
8
|
onReady: () => void;
|
|
9
9
|
onError?: (e: Error) => void;
|
|
10
10
|
};
|
|
11
|
-
declare const GoogleMapsProvider: ({ children, apiKey, libraries, language, Script, onError, }: {
|
|
11
|
+
declare const GoogleMapsProvider: ({ children, apiKey, loading, libraries, language, Script, onError, }: {
|
|
12
12
|
children: React.ReactNode;
|
|
13
13
|
apiKey: string;
|
|
14
14
|
libraries?: Libraries[];
|
|
@@ -16,10 +16,16 @@ declare const GoogleMapsProvider: ({ children, apiKey, libraries, language, Scri
|
|
|
16
16
|
* https://developers.google.com/maps/faq#languagesupport
|
|
17
17
|
*/
|
|
18
18
|
language?: string;
|
|
19
|
+
loading?: "async" | false;
|
|
19
20
|
Script?: React.ComponentType<ScriptProps>;
|
|
20
21
|
onError?: (e: Error) => void;
|
|
21
22
|
}) => react_jsx_runtime.JSX.Element;
|
|
22
23
|
|
|
24
|
+
declare const MapProvider: React.ForwardRefExoticComponent<{
|
|
25
|
+
children: React.ReactNode;
|
|
26
|
+
map: google.maps.Map | null;
|
|
27
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
28
|
+
|
|
23
29
|
declare const useGeocoder: () => {
|
|
24
30
|
geocoder: google.maps.Geocoder | null;
|
|
25
31
|
isGeocoderInitialized: boolean;
|
|
@@ -87,4 +93,4 @@ declare const useGoogleMaps: () => {
|
|
|
87
93
|
googleMaps: typeof google.maps | null;
|
|
88
94
|
};
|
|
89
95
|
|
|
90
|
-
export { GoogleMapsProvider, useGeocoder, useGoogleMaps, useMap, usePlacesAutocomplete };
|
|
96
|
+
export { GoogleMapsProvider, MapProvider, useGeocoder, useGoogleMaps, useMap, usePlacesAutocomplete };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ttoss/google-maps",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "ttoss",
|
|
6
6
|
"contributors": [
|
|
@@ -23,7 +23,6 @@
|
|
|
23
23
|
"dist"
|
|
24
24
|
],
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@types/google.maps": "^3.58.1",
|
|
27
26
|
"use-callback-ref": "^1.3.2",
|
|
28
27
|
"@ttoss/react-hooks": "^2.0.4"
|
|
29
28
|
},
|
|
@@ -32,6 +31,7 @@
|
|
|
32
31
|
"react-dom": ">=16.8.0"
|
|
33
32
|
},
|
|
34
33
|
"devDependencies": {
|
|
34
|
+
"@types/google.maps": "^3.58.1",
|
|
35
35
|
"@types/react": "^18.3.7",
|
|
36
36
|
"jest": "^29.7.0",
|
|
37
37
|
"react": "^18.3.1",
|