@ttoss/google-maps 1.14.0 → 1.14.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.
package/README.md CHANGED
@@ -1,251 +1,61 @@
1
1
  # @ttoss/google-maps
2
2
 
3
- ## 📚 About
3
+ <strong>@ttoss/google-maps</strong> is an opinionated way to use Google Maps in your React application.
4
4
 
5
- <strong> @ttoss/google-maps</strong> is a easiest way to use Google Maps in your React application.
5
+ ## Installing
6
6
 
7
- ## 🚀 Get Started
8
-
9
- ### Install @ttoss/google-maps
7
+ Install `@ttoss/google-maps` in your project:
10
8
 
11
9
  ```shell
12
- $ yarn add
10
+ $ yarn add @ttoss/google-maps
13
11
  # or
14
12
  $ npm install @ttoss/google-maps
15
13
  ```
16
14
 
17
- ## 📄 Examples of use
18
-
19
- ### Map
20
-
21
- ```tsx
22
- export type MapProps = {
23
- width?: number | string;
24
- height?: number | string;
25
- image?: Omit<MapImageOptions, 'map'>;
26
- options?: google.maps.MapOptions;
27
- };
28
-
29
- const Map = ({ height, width, image, options }: MapProps) => {
30
- const { googleMaps } = useGoogleMaps();
31
-
32
- const [mapDivRef, setMapDivRef] = React.useState<HTMLDivElement | null>(null);
33
-
34
- const map = React.useMemo(() => {
35
- if (googleMaps && mapDivRef) {
36
- const googleMapsMap = new googleMaps.Map(mapDivRef, defaultOptions);
37
- return googleMapsMap;
38
- }
39
-
40
- return null;
41
- }, [googleMaps, mapDivRef]);
42
-
43
- React.useEffect(() => {
44
- if (map && options?.center) {
45
- map.setCenter(options.center);
46
- }
47
- }, [map, options?.center]);
48
-
49
- return (
50
- <div id="google-maps" ref={(r) => setMapDivRef(r)} sx={{ width, height }} />
51
- );
52
- };
53
-
54
- Map.defaultProps = {
55
- width: 400,
56
- height: 300,
57
- } as MapProps;
15
+ If you use TypeScript, add the following to a declaration file (generally `typings.d.ts`):
58
16
 
59
- export default Map;
17
+ ```typescript title="typings.d.ts"
18
+ /// <reference types="google.maps" />
60
19
  ```
61
20
 
62
- ### Latitude and Longitude
63
-
64
- ```ts
65
- import { useGeocoder } from '@ttoss/google-maps';
21
+ ## Configuring `GoogleMapsProvider`
66
22
 
67
- type MapGeocoderResult = google.maps.GeocoderResult;
68
- type MapGeocoderStatus = google.maps.GeocoderStatus;
69
-
70
- export type LatLng = {
71
- lat: number;
72
- lng: number;
73
- };
74
-
75
- export const useGeocoding = () => {
76
- const { geocoder } = useGeocoder();
77
-
78
- const getLatLong = ({ address }: { address: string }): Promise<LatLng> => {
79
- return new Promise((resolve, reject) => {
80
- if (!geocoder) {
81
- return reject(new Error('Geocoder not defined'));
82
- }
83
-
84
- geocoder.geocode(
85
- { address },
86
- (results: MapGeocoderResult[] | null, status: MapGeocoderStatus) => {
87
- if (results && status === window.google.maps.GeocoderStatus.OK) {
88
- const lat = results[0].geometry.location.lat();
89
- const lng = results[0].geometry.location.lng();
90
-
91
- return resolve({
92
- lat,
93
- lng,
94
- });
95
- } else {
96
- console.log(
97
- 'Geocode was not successful for the following reason: ',
98
- status
99
- );
100
- return reject(new Error('Result not found'));
101
- }
102
- }
103
- );
104
- });
105
- };
106
-
107
- return { getLatLong };
108
- };
109
- ```
110
-
111
- ### Providers
23
+ At the root of your application, configure `GoogleMapsProvider` with your Google Maps API key. This way, the whole application can access the `google` variable.
112
24
 
113
25
  ```tsx
114
- import * as React from 'react';
115
-
116
26
  import { GoogleMapsProvider } from '@ttoss/google-maps';
117
27
 
118
- const Providers: React.FC = ({ children }) => {
119
- const apiKey = 'YOUR_API_KEY';
120
-
121
- if (!apiKey) {
122
- return <>{children}</>;
123
- }
124
-
28
+ const App = ({ children }) => {
125
29
  return (
126
- <GoogleMapsProvider apiKey={apiKey} libraries={['places']} language="pt-BR">
127
- {children}
128
- </GoogleMapsProvider>
30
+ <OtherProviders>
31
+ <GoogleMapsProvider apiKey={process.env.GOOGLE_MAPS_API_KEY}>
32
+ {children}
33
+ </GoogleMapsProvider>
34
+ </OtherProviders>
129
35
  );
130
36
  };
131
-
132
- export default Providers;
133
37
  ```
134
38
 
135
- ### Autocomplete
136
-
137
- ```tsx
138
- import React from 'react';
139
-
140
- import { usePlacesAutocomplete } from '@ttoss/google-maps';
141
-
142
- const Component = () => {
143
- const [text, setText] = React.useState('');
144
- const clearText = () => setText('');
145
-
146
- const apiKey = 'YOUR_API_KEY';
147
-
148
- const {
149
- ready,
150
- value,
151
- suggestions: { status, data },
152
- setValue,
153
- clearSuggestions,
154
- } = usePlacesAutocomplete({
155
- debounce: 300,
156
- cacheKey: apiKey,
157
- });
158
-
159
- const handleInput = (e: any) => {
160
- setValue(e.target.value);
161
- };
162
-
163
- const handleSelect =
164
- ({ description }: { description: string }) =>
165
- () => {
166
- setValue(description, false);
167
- clearSuggestions();
168
- };
169
-
170
- const renderSuggestions = () =>
171
- data.map((suggestion) => {
172
- const {
173
- place_id,
174
- structured_formatting: { main_text, secondary_text },
175
- } = suggestion;
176
-
177
- return (
178
- <li key={place_id} onClick={() => handleSelect(suggestion)}>
179
- <strong>{main_text}</strong>
180
-
181
- <small>{secondary_text}</small>
182
- </li>
183
- );
184
- });
39
+ ## Rendering the Map
185
40
 
186
- return (
187
- <div>
188
- <input value={value} onChange={handleInput} disabled={!ready} />
189
-
190
- {status === 'OK' && <ul>{renderSuggestions()}</ul>}
191
- </div>
192
- );
193
- };
41
+ At the component level, render Google Maps using `useMap` hook:
194
42
 
195
- export default Component;
196
- ```
197
-
198
- ## 📘 Types
43
+ ```tsx
44
+ import { Box, Text } from '@ttoss/ui';
45
+ import { useMap } from '@ttoss/google-maps';
199
46
 
200
- ```ts
201
- import { ScriptStatus } from '@ttoss/hooks';
47
+ const MyComponent = () => {
48
+ const { ref, map } = useMap();
202
49
 
203
- const useMap: (options: google.maps.MapOptions) => {
204
- map: google.maps.Map | null;
205
- ref: React.RefObject<HTMLDivElement>;
206
- isMapInitialized: boolean;
207
- };
50
+ React.useEffect(() => {
51
+ // You have access to every map methods, like `setOptions`, through `map`.
52
+ }, [map]);
208
53
 
209
- const useGeocoder: () => {
210
- geocoder: google.maps.Geocoder | null;
211
- isGeocoderInitialized: boolean;
54
+ return (
55
+ <Box>
56
+ <Text>My Map</Text>
57
+ <Box ref={ref} sx={{ height, width }} />
58
+ </Box>
59
+ );
212
60
  };
213
-
214
- type Libraries = 'places' | 'visualization' | 'drawing' | 'geometry';
215
-
216
- type Extends<T, U extends T> = U;
217
-
218
- type LoadedMapsStatus = Extends<ScriptStatus, 'ready'>;
219
-
220
- type NotLoadedMapStatus = Extends<ScriptStatus, 'idle' | 'error' | 'loading'>;
221
-
222
- export type GoogleMaps = typeof google.maps;
223
-
224
- const GoogleMapsProvider: React.FC<{
225
- apiKey: string;
226
- libraries?: Libraries[] | undefined;
227
- language?: string;
228
- }>;
229
-
230
- const useGoogleMaps: () =>
231
- | {
232
- status: LoadedMapsStatus;
233
- googleMaps: GoogleMaps;
234
- }
235
- | {
236
- status: NotLoadedMapStatus;
237
- googleMaps: null;
238
- };
239
61
  ```
240
-
241
- ---
242
-
243
- ## 💻 For more information
244
-
245
- - **[ Platform Google Maps Documentation](https://developers.google.com/maps/documentation/javascript/overview)**
246
-
247
- <br/>
248
-
249
- <h4 align="center">
250
- Special thanks for the inspiring <a href="https://github.com/jmarceli/react-hook-google-maps">react-hook-google-maps</a> and <a href="https://github.com/wellyshen/use-places-autocomplete">use-places-autocomplete</a> documentation.
251
- </h4>
package/dist/esm/index.js CHANGED
@@ -2,13 +2,18 @@
2
2
  import * as React from "react";
3
3
 
4
4
  // src/GoogleMapsProvider.tsx
5
- import { useScript } from "@ttoss/hooks";
6
5
  import * as React2 from "react";
6
+ import { useScript } from "@ttoss/hooks";
7
7
  var GoogleMapsContext = React2.createContext({
8
8
  status: "idle",
9
9
  googleMaps: null
10
10
  });
11
- var GoogleMapsProvider = ({ children, apiKey, libraries, language }) => {
11
+ var GoogleMapsProvider = ({
12
+ children,
13
+ apiKey,
14
+ libraries,
15
+ language
16
+ }) => {
12
17
  const src = (() => {
13
18
  let srcTemp = `https://maps.googleapis.com/maps/api/js?key=${apiKey}`;
14
19
  if (libraries) {
@@ -62,21 +67,28 @@ var useGeocoder = () => {
62
67
 
63
68
  // src/useMap.ts
64
69
  import * as React4 from "react";
65
- var useMap = (options) => {
66
- const ref = React4.useRef(null);
70
+ import { useCallbackRef } from "use-callback-ref";
71
+ var useMap = (options = {}) => {
72
+ const [, forceUpdate] = React4.useState(0);
73
+ const ref = useCallbackRef(null, () => forceUpdate((n) => n + 1));
67
74
  const { googleMaps } = useGoogleMaps();
68
- const [isMapInitialized, setIsMapInitialized] = React4.useState(false);
69
- const optionsStringify = JSON.stringify(options);
70
75
  const map = React4.useMemo(() => {
71
76
  if (googleMaps && ref.current) {
72
- const parsedOptions = JSON.parse(optionsStringify);
73
- const googleMapsMap = new googleMaps.Map(ref.current, parsedOptions);
74
- setIsMapInitialized(true);
75
- return googleMapsMap;
77
+ return new googleMaps.Map(ref.current, options);
76
78
  }
77
79
  return null;
78
- }, [googleMaps, optionsStringify]);
79
- return { map, ref, isMapInitialized };
80
+ }, [googleMaps, ref.current]);
81
+ const optionsStringify = JSON.stringify(options);
82
+ React4.useEffect(() => {
83
+ if (map) {
84
+ const parsedOptions = JSON.parse(optionsStringify);
85
+ map.setOptions(parsedOptions);
86
+ }
87
+ }, [optionsStringify, map]);
88
+ return {
89
+ map,
90
+ ref
91
+ };
80
92
  };
81
93
  export {
82
94
  GoogleMapsProvider,
package/dist/index.d.ts CHANGED
@@ -1,19 +1,20 @@
1
- import { ScriptStatus } from '@ttoss/hooks';
2
1
  import * as React from 'react';
2
+ import { ScriptStatus } from '@ttoss/hooks';
3
3
 
4
4
  declare type Extends<T, U extends T> = U;
5
5
  declare type GoogleMaps = typeof google.maps;
6
6
  declare type LoadedMapsStatus = Extends<ScriptStatus, 'ready'>;
7
7
  declare type NotLoadedMapStatus = Extends<ScriptStatus, 'idle' | 'error' | 'loading'>;
8
8
  declare type Libraries = 'places' | 'visualization' | 'drawing' | 'geometry';
9
- declare const GoogleMapsProvider: React.FC<{
9
+ declare const GoogleMapsProvider: ({ children, apiKey, libraries, language, }: {
10
+ children: React.ReactNode;
10
11
  apiKey: string;
11
- libraries?: Libraries[];
12
+ libraries?: Libraries[] | undefined;
12
13
  /**
13
14
  * https://developers.google.com/maps/faq#languagesupport
14
15
  */
15
- language?: string;
16
- }>;
16
+ language?: string | undefined;
17
+ }) => JSX.Element;
17
18
  /**
18
19
  *
19
20
  * @returns param.googleMaps: GoogleMaps - returns the google maps object which
@@ -32,10 +33,15 @@ declare const useGeocoder: () => {
32
33
  isGeocoderInitialized: boolean;
33
34
  };
34
35
 
35
- declare const useMap: (options: google.maps.MapOptions) => {
36
+ declare const useMap: (options?: google.maps.MapOptions) => {
37
+ /**
38
+ * asss
39
+ */
36
40
  map: google.maps.Map | null;
37
- ref: React.RefObject<HTMLDivElement>;
38
- isMapInitialized: boolean;
41
+ /**
42
+ * hhhh
43
+ */
44
+ ref: React.MutableRefObject<HTMLDivElement | null>;
39
45
  };
40
46
 
41
47
  export { GoogleMapsProvider, useGeocoder, useGoogleMaps, useMap };
package/dist/index.js CHANGED
@@ -33,13 +33,18 @@ module.exports = __toCommonJS(src_exports);
33
33
  var React = __toESM(require("react"));
34
34
 
35
35
  // src/GoogleMapsProvider.tsx
36
- var import_hooks = require("@ttoss/hooks");
37
36
  var React2 = __toESM(require("react"));
37
+ var import_hooks = require("@ttoss/hooks");
38
38
  var GoogleMapsContext = React2.createContext({
39
39
  status: "idle",
40
40
  googleMaps: null
41
41
  });
42
- var GoogleMapsProvider = ({ children, apiKey, libraries, language }) => {
42
+ var GoogleMapsProvider = ({
43
+ children,
44
+ apiKey,
45
+ libraries,
46
+ language
47
+ }) => {
43
48
  const src = (() => {
44
49
  let srcTemp = `https://maps.googleapis.com/maps/api/js?key=${apiKey}`;
45
50
  if (libraries) {
@@ -93,21 +98,28 @@ var useGeocoder = () => {
93
98
 
94
99
  // src/useMap.ts
95
100
  var React4 = __toESM(require("react"));
96
- var useMap = (options) => {
97
- const ref = React4.useRef(null);
101
+ var import_use_callback_ref = require("use-callback-ref");
102
+ var useMap = (options = {}) => {
103
+ const [, forceUpdate] = React4.useState(0);
104
+ const ref = (0, import_use_callback_ref.useCallbackRef)(null, () => forceUpdate((n) => n + 1));
98
105
  const { googleMaps } = useGoogleMaps();
99
- const [isMapInitialized, setIsMapInitialized] = React4.useState(false);
100
- const optionsStringify = JSON.stringify(options);
101
106
  const map = React4.useMemo(() => {
102
107
  if (googleMaps && ref.current) {
103
- const parsedOptions = JSON.parse(optionsStringify);
104
- const googleMapsMap = new googleMaps.Map(ref.current, parsedOptions);
105
- setIsMapInitialized(true);
106
- return googleMapsMap;
108
+ return new googleMaps.Map(ref.current, options);
107
109
  }
108
110
  return null;
109
- }, [googleMaps, optionsStringify]);
110
- return { map, ref, isMapInitialized };
111
+ }, [googleMaps, ref.current]);
112
+ const optionsStringify = JSON.stringify(options);
113
+ React4.useEffect(() => {
114
+ if (map) {
115
+ const parsedOptions = JSON.parse(optionsStringify);
116
+ map.setOptions(parsedOptions);
117
+ }
118
+ }, [optionsStringify, map]);
119
+ return {
120
+ map,
121
+ ref
122
+ };
111
123
  };
112
124
  // Annotate the CommonJS export names for ESM import in node:
113
125
  0 && (module.exports = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttoss/google-maps",
3
- "version": "1.14.0",
3
+ "version": "1.14.3",
4
4
  "author": "ttoss",
5
5
  "contributors": [
6
6
  {
@@ -31,12 +31,13 @@
31
31
  "build": "tsup"
32
32
  },
33
33
  "dependencies": {
34
- "@ttoss/hooks": "^1.14.0",
35
- "@types/google.maps": "^3.47.3"
34
+ "@ttoss/hooks": "^1.14.3",
35
+ "@types/google.maps": "^3.48.6",
36
+ "use-callback-ref": "^1.3.0"
36
37
  },
37
38
  "peerDependencies": {
38
39
  "react": ">=16.8.0",
39
40
  "react-dom": ">=16.8.0"
40
41
  },
41
- "gitHead": "bbcc5a8487112ce78a1873b19349b903299ff26e"
42
+ "gitHead": "0930d6b8f8d7bce388ea223298fa2b71c5717058"
42
43
  }
@@ -1,5 +1,5 @@
1
- import { useScript, ScriptStatus } from '@ttoss/hooks';
2
1
  import * as React from 'react';
2
+ import { ScriptStatus, useScript } from '@ttoss/hooks';
3
3
 
4
4
  type Extends<T, U extends T> = U;
5
5
 
@@ -25,14 +25,20 @@ const GoogleMapsContext = React.createContext<
25
25
 
26
26
  type Libraries = 'places' | 'visualization' | 'drawing' | 'geometry';
27
27
 
28
- export const GoogleMapsProvider: React.FC<{
28
+ export const GoogleMapsProvider = ({
29
+ children,
30
+ apiKey,
31
+ libraries,
32
+ language,
33
+ }: {
34
+ children: React.ReactNode;
29
35
  apiKey: string;
30
36
  libraries?: Libraries[];
31
37
  /**
32
38
  * https://developers.google.com/maps/faq#languagesupport
33
39
  */
34
40
  language?: string;
35
- }> = ({ children, apiKey, libraries, language }) => {
41
+ }) => {
36
42
  const src = (() => {
37
43
  let srcTemp = `https://maps.googleapis.com/maps/api/js?key=${apiKey}`;
38
44
 
package/src/useMap.ts CHANGED
@@ -1,12 +1,28 @@
1
1
  import * as React from 'react';
2
-
2
+ import { useCallbackRef } from 'use-callback-ref';
3
3
  import { useGoogleMaps } from './GoogleMapsProvider';
4
4
 
5
- export const useMap = (options: google.maps.MapOptions) => {
6
- const ref = React.useRef<HTMLDivElement>(null);
5
+ export const useMap = (options: google.maps.MapOptions = {}) => {
6
+ /**
7
+ * Read here for more details about the useCallbackRef hook:
8
+ * https://github.com/theKashey/use-callback-ref#usecallbackref---to-replace-reactuseref
9
+ */
10
+ const [, forceUpdate] = React.useState(0);
11
+
12
+ const ref = useCallbackRef<HTMLDivElement>(null, () =>
13
+ forceUpdate((n) => n + 1)
14
+ );
15
+
7
16
  const { googleMaps } = useGoogleMaps();
8
17
 
9
- const [isMapInitialized, setIsMapInitialized] = React.useState(false);
18
+ const map = React.useMemo(() => {
19
+ if (googleMaps && ref.current) {
20
+ return new googleMaps.Map(ref.current, options);
21
+ }
22
+
23
+ return null;
24
+ // eslint-disable-next-line react-hooks/exhaustive-deps
25
+ }, [googleMaps, ref.current]);
10
26
 
11
27
  /**
12
28
  * To avoid re-initializing the map because shallow object comparison.
@@ -14,16 +30,24 @@ export const useMap = (options: google.maps.MapOptions) => {
14
30
  */
15
31
  const optionsStringify = JSON.stringify(options);
16
32
 
17
- const map = React.useMemo(() => {
18
- if (googleMaps && ref.current) {
33
+ /**
34
+ * Update options but not reinitialize the map.
35
+ */
36
+ React.useEffect(() => {
37
+ if (map) {
19
38
  const parsedOptions = JSON.parse(optionsStringify);
20
- const googleMapsMap = new googleMaps.Map(ref.current, parsedOptions);
21
- setIsMapInitialized(true);
22
- return googleMapsMap;
39
+ map.setOptions(parsedOptions);
23
40
  }
41
+ }, [optionsStringify, map]);
24
42
 
25
- return null;
26
- }, [googleMaps, optionsStringify]);
27
-
28
- return { map, ref, isMapInitialized };
43
+ return {
44
+ /**
45
+ * asss
46
+ */
47
+ map,
48
+ /**
49
+ * hhhh
50
+ */
51
+ ref,
52
+ };
29
53
  };