@ttoss/google-maps 2.0.8 → 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 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, add the following to a declaration file (generally `typings.d.ts`):
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
- ## Usage
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,11 +163,21 @@ 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
- - `ref`: React.RefObject<HTMLDivElement> - Reference to the map container.
180
+ - `ref`: `React.RefObject<HTMLDivElement>` - Reference to the map container.
125
181
  - `map`: google.maps.Map | null - Google Maps object.
126
182
 
127
183
  ### `useGoogleMaps`
@@ -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,6 +27,7 @@ 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,
@@ -34,6 +35,9 @@ var GoogleMapsProvider = ({
34
35
  }) => {
35
36
  const src = (() => {
36
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 React3 from "react";
110
+ import * as React4 from "react";
84
111
 
85
112
  // src/useGoogleMaps.ts
86
- import * as React2 from "react";
113
+ import * as React3 from "react";
87
114
  var useGoogleMaps = () => {
88
115
  const {
89
116
  status,
90
117
  google
91
- } = React2.useContext(GoogleMapsContext);
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] = React3.useState(false);
110
- const geocoder = React3.useMemo(() => {
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 React4 from "react";
152
+ import * as React5 from "react";
126
153
  import { useCallbackRef } from "use-callback-ref";
127
154
  var useMap = (options = {}) => {
128
- const [, forceUpdate] = React4.useState(0);
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 [map, setMap] = React4.useState(null);
139
- React4.useEffect(() => {
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
- React4.useEffect(() => {
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 React6 from "react";
203
+ import * as React7 from "react";
176
204
 
177
205
  // src/usePlacesAutocomplete/useLatest.ts
178
- import * as React5 from "react";
206
+ import * as React6 from "react";
179
207
  var useLatest = val => {
180
- const ref = React5.useRef(val);
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] = React6.useState(false);
210
- const [value, setVal] = React6.useState(defaultValue);
211
- const [suggestions, setSuggestions] = React6.useState({
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 = React6.useRef(null);
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 = React6.useCallback(() => {
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 = React6.useCallback(() => {
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 = React6.useCallback(() => {
275
+ const clearCache = React7.useCallback(() => {
248
276
  try {
249
277
  sessionStorage.removeItem(upaCacheKey);
250
278
  } catch (error) {}
251
279
  }, []);
252
- const fetchPredictions = React6.useCallback(debounce_default(val => {
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 = React6.useCallback((val, shouldFetchData = true) => {
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
- React6.useEffect(() => {
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.8",
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",