places-autocomplete-svelte 2.2.17 → 2.2.19
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 +119 -36
- package/dist/PlaceAutocomplete.svelte +67 -18
- package/dist/helpers.js +6 -3
- package/package.json +19 -19
package/README.md
CHANGED
|
@@ -5,7 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
A flexible, accessible, and secure [Svelte](https://kit.svelte.dev) component leveraging the [Google Maps Places Autocomplete API (New)](https://developers.google.com/maps/documentation/javascript/place-autocomplete-overview).
|
|
7
7
|
|
|
8
|
-
The component handles API loading, session tokens, debounced fetching, and accessibility, allowing you to focus on building your application. It intelligently manages the Google Maps API loader, creating a shared instance that prevents conflicts with other map components on the same page.
|
|
8
|
+
The component handles API loading, session tokens, debounced fetching, and accessibility, allowing you to focus on building your application. It intelligently manages the Google Maps API loader, creating a shared instance via Svelte's context that prevents conflicts with other map components on the same page.
|
|
9
|
+
|
|
10
|
+
**Two initialisation patterns:**
|
|
11
|
+
- **Simple/Automatic**: Pass your API key directly to the component for basic use cases
|
|
12
|
+
- **Advanced/Manual**: Initialise the loader once in a parent component when using multiple Google Maps libraries or components
|
|
9
13
|
|
|
10
14
|
## Available: Standalone JavaScript Library
|
|
11
15
|
|
|
@@ -53,74 +57,122 @@ yarn add places-autocomplete-svelte
|
|
|
53
57
|
|
|
54
58
|
## Usage
|
|
55
59
|
|
|
56
|
-
|
|
60
|
+
### Basic Usage (Automatic Initialisation)
|
|
57
61
|
|
|
62
|
+
For simple use cases, just pass your API key to the component. It will automatically handle the Google Maps loader initialisation:
|
|
58
63
|
|
|
59
|
-
```javascript
|
|
60
|
-
// In your +page.svelte or a parent component
|
|
61
64
|
|
|
65
|
+
```javascript
|
|
62
66
|
<script lang="ts">
|
|
63
67
|
import { PlaceAutocomplete } from 'places-autocomplete-svelte';
|
|
64
68
|
import type { PlaceResult } from 'places-autocomplete-svelte/interfaces';
|
|
65
69
|
|
|
66
70
|
// Get API Key securely (e.g., from environment variables)
|
|
67
|
-
const PUBLIC_GOOGLE_MAPS_API_KEY = import.meta.env.VITE_PUBLIC_GOOGLE_MAPS_API_KEY;
|
|
71
|
+
const PUBLIC_GOOGLE_MAPS_API_KEY = import.meta.env.VITE_PUBLIC_GOOGLE_MAPS_API_KEY;
|
|
68
72
|
|
|
69
|
-
// --- Handle Component Response ---
|
|
70
73
|
const handleResponse = (response: PlaceResult) => {
|
|
71
|
-
console.log('
|
|
74
|
+
console.log('Selected:', response.formattedAddress);
|
|
72
75
|
};
|
|
73
76
|
|
|
74
|
-
// --- Handle Component Errors ---
|
|
75
77
|
const handleError = (error: string) => {
|
|
76
78
|
console.error('Error:', error);
|
|
77
79
|
};
|
|
78
80
|
</script>
|
|
79
81
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
+
<PlaceAutocomplete
|
|
83
|
+
{PUBLIC_GOOGLE_MAPS_API_KEY}
|
|
84
|
+
onResponse={handleResponse}
|
|
85
|
+
onError={handleError}
|
|
86
|
+
/>
|
|
82
87
|
```
|
|
83
88
|
|
|
84
|
-
### Advanced
|
|
89
|
+
### Advanced Usage (Manual Initialisation)
|
|
85
90
|
|
|
86
|
-
|
|
91
|
+
For applications that need multiple Google Maps libraries (e.g., `places`, `maps`, `marker`) or multiple map components, initialise the loader once in a parent component. This approach:
|
|
87
92
|
|
|
88
|
-
|
|
93
|
+
- Loads all required libraries in a single API call (more efficient)
|
|
94
|
+
- Prevents "Loader must not be called again" errors
|
|
95
|
+
- Shares the loader instance across all child components via Svelte context
|
|
96
|
+
- Works seamlessly with SvelteKit's SSR (only initialises in the browser)
|
|
89
97
|
|
|
90
|
-
|
|
98
|
+
**When to use manual initialisation:**
|
|
99
|
+
- Using multiple Google Maps components on the same page
|
|
100
|
+
- Need to load multiple libraries (`maps`, `marker`, `geometry`, etc.)
|
|
101
|
+
- Building a layout that shares map functionality across routes
|
|
102
|
+
- Want centralised error handling for the loader
|
|
91
103
|
|
|
92
104
|
```javascript
|
|
93
|
-
//
|
|
105
|
+
// In +layout.svelte or +page.svelte
|
|
94
106
|
<script lang="ts">
|
|
95
|
-
import { onMount } from 'svelte';
|
|
96
107
|
import { browser } from '$app/environment';
|
|
97
108
|
import { PlaceAutocomplete } from 'places-autocomplete-svelte';
|
|
98
|
-
import {
|
|
109
|
+
import { setGMapsContext, initialiseGMaps, importLibrary } from 'places-autocomplete-svelte/gmaps';
|
|
110
|
+
import { onMount } from 'svelte';
|
|
99
111
|
|
|
100
|
-
// 1. Set the context
|
|
112
|
+
// 1. Set the context at the top level (must be synchronous)
|
|
101
113
|
setGMapsContext();
|
|
102
114
|
|
|
103
|
-
// 2.
|
|
115
|
+
// 2. Initialise the loader in the browser
|
|
104
116
|
if (browser) {
|
|
105
117
|
initialiseGMaps({
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
118
|
+
key: import.meta.env.VITE_PUBLIC_GOOGLE_MAPS_API_KEY,
|
|
119
|
+
v: 'weekly'
|
|
120
|
+
}).catch((error) => {
|
|
121
|
+
console.error('Failed to initialise Google Maps:', error);
|
|
110
122
|
});
|
|
111
123
|
}
|
|
112
124
|
|
|
113
|
-
//
|
|
125
|
+
// 3. Load additional libraries as needed
|
|
126
|
+
let map: google.maps.Map;
|
|
127
|
+
|
|
128
|
+
onMount(async () => {
|
|
129
|
+
const { Map } = await importLibrary('maps');
|
|
130
|
+
const { AdvancedMarkerElement } = await importLibrary('marker');
|
|
131
|
+
|
|
132
|
+
const mapElement = document.getElementById('map');
|
|
133
|
+
if (mapElement) {
|
|
134
|
+
map = new Map(mapElement, {
|
|
135
|
+
center: { lat: 51.5072, lng: -0.1276 },
|
|
136
|
+
zoom: 10,
|
|
137
|
+
mapId: 'YOUR_MAP_ID'
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// 4. Handle autocomplete responses
|
|
143
|
+
const handleResponse = (response: PlaceResult) => {
|
|
144
|
+
console.log('Selected:', response.formattedAddress);
|
|
145
|
+
// Update map with selected location
|
|
146
|
+
if (response.location && map) {
|
|
147
|
+
map.setCenter(response.location);
|
|
148
|
+
map.setZoom(15);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const handleError = (error: string) => {
|
|
153
|
+
console.error('Error:', error);
|
|
154
|
+
};
|
|
114
155
|
</script>
|
|
115
156
|
|
|
116
|
-
<!-- The
|
|
117
|
-
<!--
|
|
118
|
-
<PlaceAutocomplete
|
|
157
|
+
<!-- The component automatically uses the shared context -->
|
|
158
|
+
<!-- No need to pass PUBLIC_GOOGLE_MAPS_API_KEY when using manual initialisation -->
|
|
159
|
+
<PlaceAutocomplete
|
|
160
|
+
onResponse={handleResponse}
|
|
161
|
+
onError={handleError}
|
|
162
|
+
/>
|
|
119
163
|
|
|
120
|
-
|
|
121
|
-
<div id="map"></div>
|
|
164
|
+
<div id="map" class="h-96 w-full"></div>
|
|
122
165
|
```
|
|
123
166
|
|
|
167
|
+
**Available helper functions from `places-autocomplete-svelte/gmaps`:**
|
|
168
|
+
|
|
169
|
+
- `setGMapsContext()` - Creates the shared context (call once at the top level)
|
|
170
|
+
- `getGMapsContext()` - Retrieves the context (returns stores for initialisation state and errors)
|
|
171
|
+
- `hasGMapsContext()` - Checks if context exists (useful for conditional logic)
|
|
172
|
+
- `initialiseGMaps(options)` - Initialises the loader with your API key and options
|
|
173
|
+
- `initialiseGMapsNoContext(options)` - Initialises without context (for edge cases)
|
|
174
|
+
- `importLibrary(library)` - Dynamically imports Google Maps libraries
|
|
175
|
+
|
|
124
176
|
## Security
|
|
125
177
|
|
|
126
178
|
### API Key Security
|
|
@@ -148,12 +200,14 @@ This component is built to be accessible and follows the [WAI-ARIA Authoring Pra
|
|
|
148
200
|
|
|
149
201
|
| Prop | Type | Required | Default | Description |
|
|
150
202
|
| :--- | :--- | :--- | :--- | :--- |
|
|
151
|
-
| `PUBLIC_GOOGLE_MAPS_API_KEY` | `string` |
|
|
152
|
-
| `
|
|
153
|
-
| `
|
|
154
|
-
| `
|
|
155
|
-
| `
|
|
156
|
-
| `
|
|
203
|
+
| `PUBLIC_GOOGLE_MAPS_API_KEY` | `string` | No* | - | Your Google Maps API Key. **Required for automatic initialisation.** Optional if you've initialised the loader in a parent component using `initialiseGMaps()`. |
|
|
204
|
+
| `onResponse` | `(response: PlaceResult) => void` | Yes | - | Callback triggered when a user selects a place. Receives the full place details object. |
|
|
205
|
+
| `onError` | `(error: string) => void` | Yes | - | Callback triggered when an error occurs (API loading, network issues, etc.). |
|
|
206
|
+
| `fetchFields` | `string[]` | No | `['formattedAddress', 'addressComponents']` | Place Data Fields to request from the API. See [Place Data Fields](https://developers.google.com/maps/documentation/javascript/place-data-fields). **Affects API billing.** |
|
|
207
|
+
| `requestParams` | `Partial<RequestParams>` | No | `{ inputOffset: 3 }` | Parameters for the Autocomplete API request (language, region, location bias, etc.). See RequestParams interface. |
|
|
208
|
+
| `options` | `Partial<ComponentOptions>` | No | `{ debounce: 100 }` | UI and behavior options (placeholder, debounce delay, distance display, custom classes, etc.). See ComponentOptions interface. |
|
|
209
|
+
|
|
210
|
+
*Either `PUBLIC_GOOGLE_MAPS_API_KEY` prop OR manual initialisation with `initialiseGMaps()` is required.
|
|
157
211
|
|
|
158
212
|
## Component Methods (Imperative API)
|
|
159
213
|
|
|
@@ -241,7 +295,36 @@ const options = {
|
|
|
241
295
|
|
|
242
296
|
## TypeScript
|
|
243
297
|
|
|
244
|
-
This component is written in TypeScript
|
|
298
|
+
This component is written in TypeScript with full type definitions included.
|
|
299
|
+
|
|
300
|
+
**Available imports:**
|
|
301
|
+
|
|
302
|
+
```typescript
|
|
303
|
+
// Component
|
|
304
|
+
import { PlaceAutocomplete } from 'places-autocomplete-svelte';
|
|
305
|
+
|
|
306
|
+
// Types and interfaces
|
|
307
|
+
import type {
|
|
308
|
+
PlaceResult,
|
|
309
|
+
ComponentOptions,
|
|
310
|
+
RequestParams,
|
|
311
|
+
FormattedAddress,
|
|
312
|
+
ComponentClasses,
|
|
313
|
+
Props
|
|
314
|
+
} from 'places-autocomplete-svelte/interfaces';
|
|
315
|
+
|
|
316
|
+
// Google Maps loader helpers
|
|
317
|
+
import {
|
|
318
|
+
setGMapsContext,
|
|
319
|
+
getGMapsContext,
|
|
320
|
+
hasGMapsContext,
|
|
321
|
+
initialiseGMaps,
|
|
322
|
+
initialiseGMapsNoContext,
|
|
323
|
+
importLibrary,
|
|
324
|
+
type GMapsContext,
|
|
325
|
+
type APIOptions
|
|
326
|
+
} from 'places-autocomplete-svelte/gmaps';
|
|
327
|
+
```
|
|
245
328
|
|
|
246
329
|
## Google Places API & Billing
|
|
247
330
|
|
|
@@ -111,6 +111,21 @@
|
|
|
111
111
|
return request;
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
// Helper function to find a specific address component
|
|
115
|
+
const getAddressComponent = (response: { addressComponents: any[]; },type: string) =>
|
|
116
|
+
response.addressComponents?.find((c: { types: string | string[]; }) => c.types.includes(type))?.longText || '';
|
|
117
|
+
|
|
118
|
+
// Helper function to get secondary text from address components
|
|
119
|
+
const getSecondaryText = (place: { addressComponents: any[]; }) => {
|
|
120
|
+
const locality = getAddressComponent(place, 'locality');
|
|
121
|
+
const adminArea = getAddressComponent(place, 'administrative_area_level_1');
|
|
122
|
+
const postalCode = getAddressComponent(place, 'postal_code');
|
|
123
|
+
const country = getAddressComponent(place, 'country');
|
|
124
|
+
|
|
125
|
+
let components = [locality, adminArea, country, postalCode].filter(Boolean);
|
|
126
|
+
return components.join(', ');
|
|
127
|
+
};
|
|
128
|
+
|
|
114
129
|
/**
|
|
115
130
|
* Make request and get autocomplete suggestions.
|
|
116
131
|
* @param event
|
|
@@ -142,10 +157,16 @@
|
|
|
142
157
|
// Clear previous results
|
|
143
158
|
results = [];
|
|
144
159
|
|
|
160
|
+
|
|
161
|
+
|
|
145
162
|
// ieterate over suggestions and add results to an array
|
|
146
163
|
for (const suggestion of suggestions) {
|
|
147
164
|
// get prediction text
|
|
148
|
-
|
|
165
|
+
//console.log(suggestion.placePrediction.toPlace());
|
|
166
|
+
let place = suggestions[0].placePrediction.toPlace();
|
|
167
|
+
await place.fetchFields({fields: ["addressComponents"]});
|
|
168
|
+
|
|
169
|
+
const predictionText = suggestion.placePrediction.mainText;
|
|
149
170
|
const originalText = predictionText.text;
|
|
150
171
|
// Array of objects with startOffset, endOffset
|
|
151
172
|
const matches = predictionText.matches;
|
|
@@ -162,14 +183,16 @@
|
|
|
162
183
|
highlightedText = createHighlightedSegments(originalText, matches);
|
|
163
184
|
|
|
164
185
|
results.push({
|
|
165
|
-
place:
|
|
166
|
-
|
|
186
|
+
place: place,
|
|
187
|
+
mainText: highlightedText,
|
|
188
|
+
secondaryText: getSecondaryText(place),
|
|
167
189
|
distance: formatDistance(
|
|
168
190
|
suggestion.placePrediction.distanceMeters,
|
|
169
191
|
options.distance_units ?? 'km'
|
|
170
192
|
)
|
|
171
193
|
});
|
|
172
194
|
}
|
|
195
|
+
//console.log('Autocomplete suggestions:', results);
|
|
173
196
|
} catch (e: any) {
|
|
174
197
|
onError((e.name || 'An error occurred') + ' - ' + (e.message || 'see console for details.'));
|
|
175
198
|
}
|
|
@@ -383,21 +406,47 @@
|
|
|
383
406
|
i === currentSuggestion && options.classes?.li_div_current
|
|
384
407
|
]}
|
|
385
408
|
>
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
409
|
+
{#if options.classes?.map_pin_icon}
|
|
410
|
+
<svg
|
|
411
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
412
|
+
width="24"
|
|
413
|
+
height="24"
|
|
414
|
+
viewBox="0 0 24 24"
|
|
415
|
+
fill="none"
|
|
416
|
+
stroke="currentColor"
|
|
417
|
+
stroke-width="2"
|
|
418
|
+
stroke-linecap="round"
|
|
419
|
+
stroke-linejoin="round"
|
|
420
|
+
class="size-5">{@html options.classes.map_pin_icon}</svg
|
|
421
|
+
>
|
|
422
|
+
{/if}
|
|
423
|
+
|
|
424
|
+
<div class={[options.classes?.li_div_p_container ?? '']}>
|
|
425
|
+
<p
|
|
426
|
+
class={[
|
|
427
|
+
i === currentSuggestion && options.classes?.li_current,
|
|
428
|
+
options.classes?.li_div_one_p
|
|
429
|
+
]}
|
|
430
|
+
>
|
|
431
|
+
{#each p.mainText as segment}
|
|
432
|
+
{#if segment.highlighted}
|
|
433
|
+
<span class={options.classes?.highlight ?? 'font-bold'}
|
|
434
|
+
>{segment.text}</span
|
|
435
|
+
>
|
|
436
|
+
{:else}
|
|
437
|
+
{segment.text}
|
|
438
|
+
{/if}
|
|
439
|
+
{/each}
|
|
440
|
+
</p>
|
|
441
|
+
<p
|
|
442
|
+
class={[
|
|
443
|
+
i === currentSuggestion && options.classes?.li_current,
|
|
444
|
+
options.classes?.li_div_one_p_secondaryText
|
|
445
|
+
]}
|
|
446
|
+
>
|
|
447
|
+
{p.secondaryText}
|
|
448
|
+
</p>
|
|
449
|
+
</div>
|
|
401
450
|
</div>
|
|
402
451
|
</div>
|
|
403
452
|
{#if options.distance && p.distance}
|
package/dist/helpers.js
CHANGED
|
@@ -302,12 +302,15 @@ export const componentClasses = {
|
|
|
302
302
|
kbd_active: 'bg-indigo-500 text-white',
|
|
303
303
|
ul: 'absolute z-50 -mb-2 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm divide-y divide-gray-100',
|
|
304
304
|
li: 'z-50 cursor-default select-none py-2 px-2 lg:px-4 text-gray-900 hover:bg-indigo-500 hover:text-white',
|
|
305
|
-
li_current: 'bg-indigo-500',
|
|
305
|
+
li_current: 'bg-indigo-500 text-white',
|
|
306
306
|
li_a: 'block w-full flex justify-between',
|
|
307
307
|
li_a_current: 'text-white',
|
|
308
308
|
li_div_container: 'flex min-w-0 gap-x-4',
|
|
309
|
-
li_div_one: 'min-w-0 flex-auto',
|
|
310
|
-
|
|
309
|
+
li_div_one: 'min-w-0 flex-auto flex gap-x-4 justify-center items-center',
|
|
310
|
+
li_div_p_container: 'min-w-0 flex-auto',
|
|
311
|
+
li_div_one_p: 'text-sm/6 text-left',
|
|
312
|
+
map_pin_icon: '<path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"/><circle cx="12" cy="10" r="3"/>',
|
|
313
|
+
li_div_one_p_secondaryText: 'text-xs text-left leading-2',
|
|
311
314
|
li_div_two: 'shrink-0 flex flex-col items-end min-w-16',
|
|
312
315
|
li_div_two_p: 'mt-1 text-xs/5',
|
|
313
316
|
highlight: 'font-bold',
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "places-autocomplete-svelte",
|
|
3
3
|
"license": "MIT",
|
|
4
|
-
"version": "2.2.
|
|
4
|
+
"version": "2.2.19",
|
|
5
5
|
"description": "A flexible, accessible, and secure Svelte component leveraging the Google Maps Places Autocomplete API (New) to provide a user-friendly way to search for and retrieve detailed address information.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"svelte",
|
|
@@ -75,38 +75,38 @@
|
|
|
75
75
|
"svelte": "^5.0.0"
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
78
|
-
"@sveltejs/adapter-auto": "^
|
|
78
|
+
"@sveltejs/adapter-auto": "^7.0.0",
|
|
79
79
|
"@sveltejs/adapter-cloudflare": "^7.2.4",
|
|
80
|
-
"@sveltejs/kit": "^2.
|
|
81
|
-
"@sveltejs/package": "^2.5.
|
|
80
|
+
"@sveltejs/kit": "^2.49.0",
|
|
81
|
+
"@sveltejs/package": "^2.5.7",
|
|
82
82
|
"@sveltejs/vite-plugin-svelte": "^6.2.1",
|
|
83
|
-
"@tailwindcss/postcss": "^4.1.
|
|
83
|
+
"@tailwindcss/postcss": "^4.1.17",
|
|
84
84
|
"@tailwindcss/typography": "^0.5.19",
|
|
85
|
-
"@tailwindcss/vite": "^4.1.
|
|
85
|
+
"@tailwindcss/vite": "^4.1.17",
|
|
86
86
|
"@types/eslint": "^9.6.1",
|
|
87
87
|
"@types/google.maps": "^3.58.1",
|
|
88
|
-
"@types/node": "^24.
|
|
89
|
-
"autoprefixer": "^10.4.
|
|
90
|
-
"eslint": "^9.
|
|
88
|
+
"@types/node": "^24.10.1",
|
|
89
|
+
"autoprefixer": "^10.4.22",
|
|
90
|
+
"eslint": "^9.39.1",
|
|
91
91
|
"eslint-config-prettier": "^10.1.8",
|
|
92
|
-
"eslint-plugin-svelte": "^3.
|
|
93
|
-
"globals": "^16.
|
|
92
|
+
"eslint-plugin-svelte": "^3.13.0",
|
|
93
|
+
"globals": "^16.5.0",
|
|
94
94
|
"postcss": "^8.5.6",
|
|
95
|
-
"prettier": "^3.
|
|
95
|
+
"prettier": "^3.7.3",
|
|
96
96
|
"prettier-plugin-svelte": "^3.4.0",
|
|
97
|
-
"publint": "^0.3.
|
|
98
|
-
"svelte": "^5.
|
|
99
|
-
"svelte-check": "^4.3.
|
|
100
|
-
"tailwindcss": "^4.1.
|
|
97
|
+
"publint": "^0.3.15",
|
|
98
|
+
"svelte": "^5.45.2",
|
|
99
|
+
"svelte-check": "^4.3.4",
|
|
100
|
+
"tailwindcss": "^4.1.17",
|
|
101
101
|
"tslib": "^2.8.1",
|
|
102
102
|
"typescript": "^5.9.3",
|
|
103
|
-
"typescript-eslint": "^8.
|
|
104
|
-
"vite": "^7.
|
|
103
|
+
"typescript-eslint": "^8.48.0",
|
|
104
|
+
"vite": "^7.2.4"
|
|
105
105
|
},
|
|
106
106
|
"svelte": "./dist/index.js",
|
|
107
107
|
"types": "./dist/PlaceAutocomplete.svelte.d.ts",
|
|
108
108
|
"type": "module",
|
|
109
109
|
"dependencies": {
|
|
110
|
-
"@googlemaps/js-api-loader": "^2.0.
|
|
110
|
+
"@googlemaps/js-api-loader": "^2.0.2"
|
|
111
111
|
}
|
|
112
112
|
}
|