Skip to content

Commit 636e533

Browse files
authored
feat(google-map): add language change for map (#9)
* feat(google-map): add language change for map * refactor(google-map): refactor code * refactor(map-provider): adjust useEffect hooks * feat(readme): adjust readme for language and region * fix(README): correct typo * 1.4.0
1 parent bc699c5 commit 636e533

File tree

6 files changed

+79
-19
lines changed

6 files changed

+79
-19
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ function App() {
6262
options={mapOptions}
6363
libraries={['places']}
6464
mapIds={['<your-mapstyle-id>']}
65+
language={'de'}
66+
region={'DE'}
6567
onLoad={(map) => map.setZoom(4)}
6668
>
6769
<React.StrictMode>
@@ -100,6 +102,8 @@ Component to wrap around the code where the map should be available.
100102
options={mapOptions}
101103
libraries={['places']}
102104
mapIds={['<your-mapstyle-id>']}
105+
language={'de'}
106+
region={'DE'}
103107
onLoad={(map) => map.setZoom(4)}
104108
>
105109
{children}
@@ -115,6 +119,8 @@ interface GoogleMapProviderProps {
115119
options: google.maps.MapOptions;
116120
libraries: string[];
117121
mapIds: string[];
122+
language: string;
123+
region: string;
118124
onLoad?: (map: google.maps.Map) => void;
119125
}
120126
```

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@ubilabs/google-maps-react-hooks",
3-
"version": "1.3.0",
3+
"version": "1.4.0",
44
"description": "React hooks and map context provider for Google Maps",
55
"source": "src/index.ts",
66
"main": "dist/index.umd.js",

src/google-map.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ interface GoogleMapOptions {
77
onLoadScript: () => void;
88
onLoadMap: (loadedMap: GoogleMap) => void;
99
libraries?: string[];
10+
language?: string;
11+
region?: string;
1012
mapIds?: string[];
1113
}
1214

@@ -18,8 +20,7 @@ export default class GoogleMap {
1820
map?: google.maps.Map;
1921

2022
constructor(options: GoogleMapOptions) {
21-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
22-
if ((window as any).google) {
23+
if (window.google && window.google.maps) {
2324
this.initMap(options);
2425
} else {
2526
this.loadGoogleScript(options);
@@ -31,11 +32,14 @@ export default class GoogleMap {
3132
*/
3233
private loadGoogleScript(options: GoogleMapOptions): void {
3334
const scriptTag = document.createElement('script');
35+
const defaultLanguage = window.navigator.language.slice(0, 2);
36+
const defaultRegion = window.navigator.language.slice(3, 5);
3437
scriptTag.setAttribute('type', 'text/javascript');
3538
scriptTag.setAttribute(
3639
'src',
3740
`https://maps.googleapis.com/maps/api/js?key=${
3841
options.googleMapsAPIKey
42+
}&language=${options.language || defaultLanguage}&region=${options.region || defaultRegion}
3943
}${
4044
options.libraries && `&libraries=${options.libraries.join(',')}`
4145
}${
@@ -66,9 +70,23 @@ export default class GoogleMap {
6670
/**
6771
* Remove event listeners
6872
*/
69-
public destroy = (): void => {
73+
public destroyListeners = (): void => {
7074
if (this.map) {
7175
google.maps.event.clearInstanceListeners(this.map);
7276
}
7377
};
78+
79+
/**
80+
* Remove map instance
81+
*/
82+
public destroyComplete = (): void => {
83+
if (this.map) {
84+
document.querySelectorAll('script[src^="https://maps.googleapis.com"]').forEach(script => {
85+
script.remove();
86+
});
87+
if (window.google && window.google.maps) {
88+
delete window.google.maps;
89+
}
90+
}
91+
};
7492
}

src/hooks/directions.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ const useDirections = (props: DirectionsProps = {}): DirectionsHookReturns => {
3232
// Creates a Directions Service instance
3333
const directionsService = useMemo<google.maps.DirectionsService | null>(() => {
3434
// Wait for map to be initialized
35-
if (loading) {
35+
if (!map || loading) {
3636
return null;
3737
}
3838

3939
return new google.maps.DirectionsService();
40-
}, [loading]);
40+
}, [map, loading]);
4141

4242
// Creates a Directions Renderer instance
4343
const directionsRenderer = useMemo<google.maps.DirectionsRenderer | null>(() => {

src/map-provider.tsx

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ export interface GoogleMapProviderProps {
88
mapContainer?: HTMLElement | null;
99
options: google.maps.MapOptions;
1010
libraries: string[];
11+
language?: string;
12+
region?: string;
1113
mapIds: string[];
1214
onLoad?: (map: google.maps.Map) => void;
1315
}
@@ -33,16 +35,18 @@ const GoogleMapProvider = (props: GoogleMapProviderProps): JSX.Element => {
3335
mapContainer,
3436
options,
3537
libraries,
38+
language,
39+
region,
3640
mapIds,
3741
onLoad
3842
} = props;
43+
3944
const [loading, setLoading] = useState<boolean>(true);
4045
const [map, setMap] = useState<GoogleMap>();
4146

42-
// Initializes Google Map on mount
43-
useEffect(() => {
47+
const createGoogleMap = (() => {
4448
if (!mapContainer) {
45-
return (): void => {};
49+
return;
4650
}
4751

4852
const mapOptions = {
@@ -57,23 +61,55 @@ const GoogleMapProvider = (props: GoogleMapProviderProps): JSX.Element => {
5761
},
5862
config: options,
5963
libraries,
60-
mapIds
64+
mapIds,
65+
language,
66+
region
6167
};
68+
// Create Google Map instance
69+
new GoogleMap(mapOptions);
70+
});
6271

63-
// Destroy old map instance
64-
if (map) {
65-
map.destroy();
72+
// Initializes map on mount
73+
useEffect(() => {
74+
if (!mapContainer) {
75+
return (): void => {};
6676
}
6777

68-
// Create Google Map instance
69-
new GoogleMap(mapOptions);
78+
// create new map instance
79+
createGoogleMap();
7080

71-
// Destroy Google Map when component unmounts
72-
return (): void => {
73-
map && map.destroy();
81+
// Destroy Google Map when component unmounts
82+
return (): void => {
83+
map && map.destroyComplete();
7484
};
85+
}, []);
86+
87+
// Destroy and recreate map on mapcontainer change
88+
useEffect(() => {
89+
if (!map || !mapContainer) {
90+
return;
91+
}
92+
93+
// Destroy old map instance listeners
94+
map.destroyListeners();
95+
96+
// create new map instance
97+
createGoogleMap();
7598
}, [mapContainer]);
7699

100+
// Destroy and recreate map on language or region change
101+
useEffect(() => {
102+
if (!map || !mapContainer) {
103+
return;
104+
}
105+
106+
// Destroy old map instance
107+
map.destroyComplete();
108+
109+
// create new map instance
110+
createGoogleMap();
111+
}, [language, region]);
112+
77113
return (
78114
<GoogleMapContext.Provider value={{...map, loading}}>
79115
{children}

0 commit comments

Comments
 (0)