@ttoss/google-maps 2.0.6 → 2.0.8

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
@@ -82,3 +82,52 @@ const MyComponent = () => {
82
82
  ```
83
83
 
84
84
  With this, you can perform any operation that the `google.maps` object allows, such as creating markers, drawing polygons, etc.
85
+
86
+ ### Using with Next.js (custom Script component)
87
+
88
+ 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:
89
+
90
+ ```tsx
91
+ import { GoogleMapsProvider } from '@ttoss/google-maps';
92
+ import Script from 'next/script';
93
+
94
+ const App = ({ children }) => {
95
+ return (
96
+ <OtherProviders>
97
+ <GoogleMapsProvider
98
+ apiKey={process.env.GOOGLE_MAPS_API_KEY}
99
+ Script={Script}
100
+ >
101
+ {children}
102
+ </GoogleMapsProvider>
103
+ </OtherProviders>
104
+ );
105
+ };
106
+ ```
107
+
108
+ ## API
109
+
110
+ ### `GoogleMapsProvider`
111
+
112
+ #### Props
113
+
114
+ - `apiKey`: string - Google Maps API key.
115
+ - `libraries`: string[] - [Libraries to load](https://developers.google.com/maps/documentation/javascript/libraries).
116
+ - `language`: string - [Language](https://developers.google.com/maps/documentation/javascript/localization).
117
+ - `Script`: React.ComponentType - Custom `Script` component to use.
118
+ - `onError`: (error: Error) => void - Callback to handle script loading errors.
119
+
120
+ ### `useMap`
121
+
122
+ #### Returns
123
+
124
+ - `ref`: React.RefObject<HTMLDivElement> - Reference to the map container.
125
+ - `map`: google.maps.Map | null - Google Maps object.
126
+
127
+ ### `useGoogleMaps`
128
+
129
+ #### Returns
130
+
131
+ - `google`: typeof google - `google.maps` object.
132
+ - `status`: 'idle' | 'error' | 'loading' | 'ready' - Status of the script loading.
133
+ - `isReady`: boolean - Whether the script is ready. The same as `status === 'ready'`.
package/dist/esm/index.js CHANGED
@@ -3,18 +3,34 @@
3
3
  // src/GoogleMapsProvider.tsx
4
4
  import * as React from "react";
5
5
  import { useScript } from "@ttoss/react-hooks";
6
- import { jsx } from "react/jsx-runtime";
6
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
7
  var GoogleMapsContext = React.createContext({
8
8
  status: "idle",
9
9
  google: {
10
10
  maps: null
11
11
  }
12
12
  });
13
+ var DefaultScript = ({
14
+ src,
15
+ onReady
16
+ }) => {
17
+ const {
18
+ status
19
+ } = useScript(src);
20
+ React.useEffect(() => {
21
+ if (status === "ready") {
22
+ onReady();
23
+ }
24
+ }, [status, onReady]);
25
+ return null;
26
+ };
13
27
  var GoogleMapsProvider = ({
14
28
  children,
15
29
  apiKey,
16
30
  libraries,
17
- language
31
+ language,
32
+ Script = DefaultScript,
33
+ onError
18
34
  }) => {
19
35
  const src = (() => {
20
36
  let srcTemp = `https://maps.googleapis.com/maps/api/js?key=${apiKey}`;
@@ -26,9 +42,7 @@ var GoogleMapsProvider = ({
26
42
  }
27
43
  return srcTemp;
28
44
  })();
29
- const {
30
- status
31
- } = useScript(src);
45
+ const [status, setStatus] = React.useState("loading");
32
46
  const google = React.useMemo(() => {
33
47
  if (status === "ready" && window.google) {
34
48
  return window.google;
@@ -51,9 +65,17 @@ var GoogleMapsProvider = ({
51
65
  }
52
66
  };
53
67
  }, [google, status]);
54
- return /* @__PURE__ */jsx(GoogleMapsContext.Provider, {
55
- value,
56
- children
68
+ return /* @__PURE__ */jsxs(Fragment, {
69
+ children: [/* @__PURE__ */jsx(Script, {
70
+ src,
71
+ onReady: () => {
72
+ return setStatus("ready");
73
+ },
74
+ onError
75
+ }), /* @__PURE__ */jsx(GoogleMapsContext.Provider, {
76
+ value,
77
+ children
78
+ })]
57
79
  });
58
80
  };
59
81
 
@@ -67,7 +89,9 @@ var useGoogleMaps = () => {
67
89
  status,
68
90
  google
69
91
  } = React2.useContext(GoogleMapsContext);
92
+ const isReady = status === "ready";
70
93
  return {
94
+ isReady,
71
95
  status,
72
96
  google,
73
97
  /**
@@ -108,14 +132,25 @@ var useMap = (options = {}) => {
108
132
  });
109
133
  });
110
134
  const {
111
- google
135
+ google,
136
+ isReady
112
137
  } = useGoogleMaps();
113
- const map = React4.useMemo(() => {
114
- if (google?.maps && ref.current) {
115
- return new google.maps.Map(ref.current, options);
138
+ const [map, setMap] = React4.useState(null);
139
+ React4.useEffect(() => {
140
+ if (map) {
141
+ return;
116
142
  }
117
- return null;
118
- }, [google?.maps, ref.current]);
143
+ if (!ref.current) {
144
+ return;
145
+ }
146
+ if (!isReady) {
147
+ return;
148
+ }
149
+ if (!google.maps) {
150
+ return;
151
+ }
152
+ setMap(new google.maps.Map(ref.current, options));
153
+ }, [map, isReady, ref, google.maps, options]);
119
154
  const optionsStringify = JSON.stringify(options);
120
155
  React4.useEffect(() => {
121
156
  if (map) {
@@ -137,7 +172,15 @@ var useMap = (options = {}) => {
137
172
  };
138
173
 
139
174
  // src/usePlacesAutocomplete/index.ts
175
+ import * as React6 from "react";
176
+
177
+ // src/usePlacesAutocomplete/useLatest.ts
140
178
  import * as React5 from "react";
179
+ var useLatest = val => {
180
+ const ref = React5.useRef(val);
181
+ ref.current = val;
182
+ return ref;
183
+ };
141
184
 
142
185
  // src/usePlacesAutocomplete/debounce.ts
143
186
  var debounce = (fn, delay) => {
@@ -153,14 +196,6 @@ var debounce = (fn, delay) => {
153
196
  };
154
197
  var debounce_default = debounce;
155
198
 
156
- // src/usePlacesAutocomplete/useLatest.ts
157
- import { useRef } from "react";
158
- var useLatest_default = val => {
159
- const ref = useRef(val);
160
- ref.current = val;
161
- return ref;
162
- };
163
-
164
199
  // src/usePlacesAutocomplete/index.ts
165
200
  var usePlacesAutocomplete = ({
166
201
  requestOptions,
@@ -171,21 +206,21 @@ var usePlacesAutocomplete = ({
171
206
  defaultValue = "",
172
207
  initOnMount = true
173
208
  } = {}) => {
174
- const [ready, setReady] = React5.useState(false);
175
- const [value, setVal] = React5.useState(defaultValue);
176
- const [suggestions, setSuggestions] = React5.useState({
209
+ const [ready, setReady] = React6.useState(false);
210
+ const [value, setVal] = React6.useState(defaultValue);
211
+ const [suggestions, setSuggestions] = React6.useState({
177
212
  loading: false,
178
213
  status: "",
179
214
  data: []
180
215
  });
181
- const asRef = React5.useRef(null);
182
- const requestOptionsRef = useLatest_default(requestOptions);
216
+ const asRef = React6.useRef(null);
217
+ const requestOptionsRef = useLatest(requestOptions);
183
218
  const {
184
219
  google
185
220
  } = useGoogleMaps();
186
- const googleMapsRef = useLatest_default(google.maps);
221
+ const googleMapsRef = useLatest(google.maps);
187
222
  const upaCacheKey = cacheKey ? `upa-${cacheKey}` : "upa";
188
- const init = React5.useCallback(() => {
223
+ const init = React6.useCallback(() => {
189
224
  if (asRef.current) {
190
225
  return;
191
226
  }
@@ -202,19 +237,19 @@ var usePlacesAutocomplete = ({
202
237
  asRef.current = new placesLib.AutocompleteService();
203
238
  setReady(true);
204
239
  }, [google.maps]);
205
- const clearSuggestions = React5.useCallback(() => {
240
+ const clearSuggestions = React6.useCallback(() => {
206
241
  setSuggestions({
207
242
  loading: false,
208
243
  status: "",
209
244
  data: []
210
245
  });
211
246
  }, []);
212
- const clearCache = React5.useCallback(() => {
247
+ const clearCache = React6.useCallback(() => {
213
248
  try {
214
249
  sessionStorage.removeItem(upaCacheKey);
215
250
  } catch (error) {}
216
251
  }, []);
217
- const fetchPredictions = React5.useCallback(debounce_default(val => {
252
+ const fetchPredictions = React6.useCallback(debounce_default(val => {
218
253
  if (!val) {
219
254
  clearSuggestions();
220
255
  return;
@@ -265,13 +300,13 @@ var usePlacesAutocomplete = ({
265
300
  }
266
301
  });
267
302
  }, debounce2), [debounce2, clearSuggestions]);
268
- const setValue = React5.useCallback((val, shouldFetchData = true) => {
303
+ const setValue = React6.useCallback((val, shouldFetchData = true) => {
269
304
  setVal(val);
270
305
  if (asRef.current && shouldFetchData) {
271
306
  fetchPredictions(val);
272
307
  }
273
308
  }, [fetchPredictions]);
274
- React5.useEffect(() => {
309
+ React6.useEffect(() => {
275
310
  if (!initOnMount) {
276
311
  return () => {
277
312
  return null;
package/dist/index.d.ts CHANGED
@@ -3,7 +3,12 @@ import * as React from 'react';
3
3
 
4
4
  type GoogleMaps = typeof google.maps;
5
5
  type Libraries = 'places' | 'visualization' | 'drawing' | 'geometry';
6
- declare const GoogleMapsProvider: ({ children, apiKey, libraries, language, }: {
6
+ type ScriptProps = {
7
+ src: string;
8
+ onReady: () => void;
9
+ onError?: (e: Error) => void;
10
+ };
11
+ declare const GoogleMapsProvider: ({ children, apiKey, libraries, language, Script, onError, }: {
7
12
  children: React.ReactNode;
8
13
  apiKey: string;
9
14
  libraries?: Libraries[];
@@ -11,6 +16,8 @@ declare const GoogleMapsProvider: ({ children, apiKey, libraries, language, }: {
11
16
  * https://developers.google.com/maps/faq#languagesupport
12
17
  */
13
18
  language?: string;
19
+ Script?: React.ComponentType<ScriptProps>;
20
+ onError?: (e: Error) => void;
14
21
  }) => react_jsx_runtime.JSX.Element;
15
22
 
16
23
  declare const useGeocoder: () => {
@@ -67,6 +74,7 @@ declare const usePlacesAutocomplete: ({ requestOptions, debounce, cache, cacheKe
67
74
  * @returns An object containing the API status and the google object.
68
75
  */
69
76
  declare const useGoogleMaps: () => {
77
+ isReady: boolean;
70
78
  status: "idle" | "loading" | "ready" | "error";
71
79
  google: {
72
80
  maps: GoogleMaps;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttoss/google-maps",
3
- "version": "2.0.6",
3
+ "version": "2.0.8",
4
4
  "license": "MIT",
5
5
  "author": "ttoss",
6
6
  "contributors": [