@ttoss/google-maps 2.0.2 → 2.0.3

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.
@@ -0,0 +1,266 @@
1
+ /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
+
3
+ // src/GoogleMapsProvider.tsx
4
+ import * as React from "react";
5
+ import { useScript } from "@ttoss/react-hooks";
6
+ import { jsx } from "react/jsx-runtime";
7
+ var GoogleMapsContext = React.createContext({
8
+ status: "idle",
9
+ googleMaps: null
10
+ });
11
+ var GoogleMapsProvider = ({
12
+ children,
13
+ apiKey,
14
+ libraries,
15
+ language
16
+ }) => {
17
+ const src = (() => {
18
+ let srcTemp = `https://maps.googleapis.com/maps/api/js?key=${apiKey}`;
19
+ if (libraries) {
20
+ srcTemp = srcTemp + `&libraries=${libraries.join(",")}`;
21
+ }
22
+ if (language) {
23
+ srcTemp = srcTemp + `&language=${language}`;
24
+ }
25
+ return srcTemp;
26
+ })();
27
+ const {
28
+ status
29
+ } = useScript(src);
30
+ const googleMaps = React.useMemo(() => {
31
+ if (status === "ready" && window.google.maps) {
32
+ return window.google.maps;
33
+ }
34
+ return null;
35
+ }, [status]);
36
+ const value = React.useMemo(() => {
37
+ if (status === "ready" && googleMaps) {
38
+ return {
39
+ status,
40
+ googleMaps
41
+ };
42
+ }
43
+ return {
44
+ status,
45
+ googleMaps: null
46
+ };
47
+ }, [googleMaps, status]);
48
+ return /* @__PURE__ */jsx(GoogleMapsContext.Provider, {
49
+ value,
50
+ children
51
+ });
52
+ };
53
+ var useGoogleMaps = () => {
54
+ return React.useContext(GoogleMapsContext);
55
+ };
56
+
57
+ // src/useGeocoder.ts
58
+ import * as React2 from "react";
59
+ var useGeocoder = () => {
60
+ const {
61
+ googleMaps
62
+ } = useGoogleMaps();
63
+ const [isGeocoderInitialized, setIsGeocoderInitialized] = React2.useState(false);
64
+ const geocoder = React2.useMemo(() => {
65
+ if (googleMaps) {
66
+ const googleMapsGeocoder = new googleMaps.Geocoder();
67
+ setIsGeocoderInitialized(true);
68
+ return googleMapsGeocoder;
69
+ }
70
+ return null;
71
+ }, [googleMaps]);
72
+ return {
73
+ geocoder,
74
+ isGeocoderInitialized
75
+ };
76
+ };
77
+
78
+ // src/useMap.ts
79
+ import * as React3 from "react";
80
+ import { useCallbackRef } from "use-callback-ref";
81
+ var useMap = (options = {}) => {
82
+ const [, forceUpdate] = React3.useState(0);
83
+ const ref = useCallbackRef(null, () => {
84
+ return forceUpdate(n => {
85
+ return n + 1;
86
+ });
87
+ });
88
+ const {
89
+ googleMaps
90
+ } = useGoogleMaps();
91
+ const map = React3.useMemo(() => {
92
+ if (googleMaps && ref.current) {
93
+ return new googleMaps.Map(ref.current, options);
94
+ }
95
+ return null;
96
+ }, [googleMaps, ref.current]);
97
+ const optionsStringify = JSON.stringify(options);
98
+ React3.useEffect(() => {
99
+ if (map) {
100
+ const parsedOptions = JSON.parse(optionsStringify);
101
+ map.setOptions(parsedOptions);
102
+ }
103
+ }, [optionsStringify, map]);
104
+ return {
105
+ /**
106
+ * asss
107
+ */
108
+ map,
109
+ /**
110
+ * hhhh
111
+ */
112
+ ref
113
+ };
114
+ };
115
+
116
+ // src/usePlacesAutocomplete/index.ts
117
+ import { useCallback, useEffect as useEffect2, useRef as useRef2, useState as useState3 } from "react";
118
+
119
+ // src/usePlacesAutocomplete/debounce.ts
120
+ var debounce = (fn, delay) => {
121
+ let timer;
122
+ function debounceFn(...args) {
123
+ if (timer !== null) {
124
+ clearTimeout(timer);
125
+ timer = null;
126
+ }
127
+ timer = setTimeout(() => fn.apply(this, args), delay);
128
+ }
129
+ return debounceFn;
130
+ };
131
+ var debounce_default = debounce;
132
+
133
+ // src/usePlacesAutocomplete/useLatest.ts
134
+ import { useRef } from "react";
135
+ var useLatest_default = val => {
136
+ const ref = useRef(val);
137
+ ref.current = val;
138
+ return ref;
139
+ };
140
+
141
+ // src/usePlacesAutocomplete/index.ts
142
+ var usePlacesAutocomplete = ({
143
+ requestOptions,
144
+ debounce: debounce2 = 200,
145
+ cache = 24 * 60 * 60,
146
+ cacheKey,
147
+ callbackName,
148
+ defaultValue = "",
149
+ initOnMount = true
150
+ } = {}) => {
151
+ const [ready, setReady] = useState3(false);
152
+ const [value, setVal] = useState3(defaultValue);
153
+ const [suggestions, setSuggestions] = useState3({
154
+ loading: false,
155
+ status: "",
156
+ data: []
157
+ });
158
+ const asRef = useRef2(null);
159
+ const requestOptionsRef = useLatest_default(requestOptions);
160
+ const {
161
+ googleMaps
162
+ } = useGoogleMaps();
163
+ const googleMapsRef = useLatest_default(googleMaps);
164
+ const upaCacheKey = cacheKey ? `upa-${cacheKey}` : "upa";
165
+ const init = useCallback(() => {
166
+ if (asRef.current) return;
167
+ if (!googleMaps) {
168
+ return;
169
+ }
170
+ const {
171
+ current: gMaps
172
+ } = googleMapsRef;
173
+ const placesLib = gMaps?.places || googleMaps.places;
174
+ if (!placesLib) {
175
+ return;
176
+ }
177
+ asRef.current = new placesLib.AutocompleteService();
178
+ setReady(true);
179
+ }, [googleMaps]);
180
+ const clearSuggestions = useCallback(() => {
181
+ setSuggestions({
182
+ loading: false,
183
+ status: "",
184
+ data: []
185
+ });
186
+ }, []);
187
+ const clearCache = useCallback(() => {
188
+ try {
189
+ sessionStorage.removeItem(upaCacheKey);
190
+ } catch (error) {}
191
+ }, []);
192
+ const fetchPredictions = useCallback(debounce_default(val => {
193
+ if (!val) {
194
+ clearSuggestions();
195
+ return;
196
+ }
197
+ setSuggestions(prevState => ({
198
+ ...prevState,
199
+ loading: true
200
+ }));
201
+ let cachedData = {};
202
+ try {
203
+ cachedData = JSON.parse(sessionStorage.getItem(upaCacheKey) || "{}");
204
+ } catch (error) {}
205
+ if (cache) {
206
+ cachedData = Object.keys(cachedData).reduce((acc, key) => {
207
+ if (cachedData[key].maxAge - Date.now() >= 0) acc[key] = cachedData[key];
208
+ return acc;
209
+ }, {});
210
+ if (cachedData[val]) {
211
+ setSuggestions({
212
+ loading: false,
213
+ status: "OK",
214
+ data: cachedData[val].data
215
+ });
216
+ return;
217
+ }
218
+ }
219
+ asRef?.current?.getPlacePredictions({
220
+ ...requestOptionsRef.current,
221
+ input: val
222
+ }, (data, status) => {
223
+ setSuggestions({
224
+ loading: false,
225
+ status,
226
+ data: data || []
227
+ });
228
+ if (cache && status === "OK") {
229
+ cachedData[val] = {
230
+ data,
231
+ maxAge: Date.now() + cache * 1e3
232
+ };
233
+ try {
234
+ sessionStorage.setItem(upaCacheKey, JSON.stringify(cachedData));
235
+ } catch (error) {}
236
+ }
237
+ });
238
+ }, debounce2), [debounce2, clearSuggestions]);
239
+ const setValue = useCallback((val, shouldFetchData = true) => {
240
+ setVal(val);
241
+ if (asRef.current && shouldFetchData) fetchPredictions(val);
242
+ }, [fetchPredictions]);
243
+ useEffect2(() => {
244
+ if (!initOnMount) {
245
+ return () => null;
246
+ }
247
+ if (!googleMapsRef.current && !googleMaps && callbackName) {
248
+ window[callbackName] = init;
249
+ } else {
250
+ init();
251
+ }
252
+ return () => {
253
+ if (window[callbackName]) delete window[callbackName];
254
+ };
255
+ }, [callbackName, init]);
256
+ return {
257
+ ready,
258
+ value,
259
+ suggestions,
260
+ setValue,
261
+ clearSuggestions,
262
+ clearCache,
263
+ init
264
+ };
265
+ };
266
+ export { GoogleMapsProvider, useGeocoder, useGoogleMaps, useMap, usePlacesAutocomplete };
@@ -0,0 +1,78 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+ import { ScriptStatus } from '@ttoss/react-hooks';
4
+
5
+ type Extends<T, U extends T> = U;
6
+ type GoogleMaps = typeof google.maps;
7
+ type LoadedMapsStatus = Extends<ScriptStatus, 'ready'>;
8
+ type NotLoadedMapStatus = Extends<ScriptStatus, 'idle' | 'error' | 'loading'>;
9
+ type Libraries = 'places' | 'visualization' | 'drawing' | 'geometry';
10
+ declare const GoogleMapsProvider: ({ children, apiKey, libraries, language, }: {
11
+ children: React.ReactNode;
12
+ apiKey: string;
13
+ libraries?: Libraries[];
14
+ /**
15
+ * https://developers.google.com/maps/faq#languagesupport
16
+ */
17
+ language?: string;
18
+ }) => react_jsx_runtime.JSX.Element;
19
+ /**
20
+ *
21
+ * @returns param.googleMaps: GoogleMaps - returns the google maps object which
22
+ * provides access to the [Google Maps API](https://developers.google.com/maps/documentation/javascript/overview).
23
+ */
24
+ declare const useGoogleMaps: () => {
25
+ status: LoadedMapsStatus;
26
+ googleMaps: GoogleMaps;
27
+ } | {
28
+ status: NotLoadedMapStatus;
29
+ googleMaps: null;
30
+ };
31
+
32
+ declare const useGeocoder: () => {
33
+ geocoder: google.maps.Geocoder | null;
34
+ isGeocoderInitialized: boolean;
35
+ };
36
+
37
+ declare const useMap: (options?: google.maps.MapOptions) => {
38
+ /**
39
+ * asss
40
+ */
41
+ map: google.maps.Map | null;
42
+ /**
43
+ * hhhh
44
+ */
45
+ ref: React.MutableRefObject<HTMLDivElement | null>;
46
+ };
47
+
48
+ interface HookArgs {
49
+ requestOptions?: Omit<google.maps.places.AutocompletionRequest, 'input'>;
50
+ debounce?: number;
51
+ cache?: number | false;
52
+ cacheKey?: string;
53
+ callbackName?: string;
54
+ defaultValue?: string;
55
+ initOnMount?: boolean;
56
+ }
57
+ type Suggestion = google.maps.places.AutocompletePrediction;
58
+ type Status = `${google.maps.places.PlacesServiceStatus}` | '';
59
+ interface Suggestions {
60
+ readonly loading: boolean;
61
+ readonly status: Status;
62
+ data: Suggestion[];
63
+ }
64
+ interface SetValue {
65
+ (val: string, shouldFetchData?: boolean): void;
66
+ }
67
+ interface HookReturn {
68
+ ready: boolean;
69
+ value: string;
70
+ suggestions: Suggestions;
71
+ setValue: SetValue;
72
+ clearSuggestions: () => void;
73
+ clearCache: () => void;
74
+ init: () => void;
75
+ }
76
+ declare const usePlacesAutocomplete: ({ requestOptions, debounce, cache, cacheKey, callbackName, defaultValue, initOnMount, }?: HookArgs) => HookReturn;
77
+
78
+ export { GoogleMapsProvider, useGeocoder, useGoogleMaps, useMap, usePlacesAutocomplete };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttoss/google-maps",
3
- "version": "2.0.2",
3
+ "version": "2.0.3",
4
4
  "author": "ttoss",
5
5
  "contributors": [
6
6
  "Pedro Arantes <pedro@arantespp.com> (https://arantespp.com/contact)",
@@ -25,7 +25,7 @@
25
25
  "dependencies": {
26
26
  "@types/google.maps": "^3.54.10",
27
27
  "use-callback-ref": "^1.3.0",
28
- "@ttoss/react-hooks": "^2.0.2"
28
+ "@ttoss/react-hooks": "^2.0.3"
29
29
  },
30
30
  "peerDependencies": {
31
31
  "react": ">=16.8.0",
@@ -36,8 +36,8 @@
36
36
  "jest": "^29.7.0",
37
37
  "react": "^18.3.1",
38
38
  "tsup": "^8.3.0",
39
- "@ttoss/config": "^1.33.0",
40
- "@ttoss/test-utils": "^2.1.15"
39
+ "@ttoss/config": "^1.34.0",
40
+ "@ttoss/test-utils": "^2.1.16"
41
41
  },
42
42
  "keywords": [
43
43
  "Google",