places-autocomplete-svelte 1.0.1 → 2.0.6
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 +97 -135
- package/dist/PlaceAutocomplete.svelte +253 -166
- package/dist/PlaceAutocomplete.svelte.d.ts +23 -36
- package/package.json +27 -20
package/README.md
CHANGED
|
@@ -3,32 +3,32 @@
|
|
|
3
3
|
This Svelte component leverages the [Google Maps Places Autocomplete API](https://developers.google.com/maps/documentation/javascript/place-autocomplete-overview) to provide a user-friendly way to search for and retrieve detailed address information within your [SvelteKit](https://kit.svelte.dev) applications.
|
|
4
4
|
|
|
5
5
|
## Features:
|
|
6
|
-
- Seamless Integration: Easily integrate the component into your SvelteKit projects.
|
|
7
|
-
- Autocomplete Suggestions: Provide users with real-time suggestions as they type, enhancing the search experience.
|
|
8
|
-
- Detailed Address Retrieval: Retrieve comprehensive address information, including street address, city, region, postal code, and country.
|
|
9
|
-
- Formatted and Unformatted Responses: Access both formatted address strings and raw address component data for flexible use cases.
|
|
10
|
-
- Country Selection: Allow users to specify a region for more targeted results.
|
|
11
|
-
|
|
12
6
|
|
|
7
|
+
- **Seamless Integration:** Easily integrate the component into your SvelteKit projects.
|
|
8
|
+
- **Autocomplete Suggestions:** Provide users with real-time suggestions as they type, enhancing the search experience.
|
|
9
|
+
- **Detailed Address Retrieval:** Retrieve comprehensive address information, including street address, city, region, postal code, and country.
|
|
10
|
+
- **Formatted and Unformatted Responses:** Access both formatted address strings and raw address component data for flexible use cases.
|
|
11
|
+
- **Country/Region Selection:** Allow users to specify a region for more targeted results.
|
|
12
|
+
- **Customizable:** Tailor the component's appearance and behavior using language settings and placeholder text.
|
|
13
13
|
|
|
14
14
|

|
|
15
15
|
|
|
16
|
-
|
|
17
16
|
## Requirements
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
- Google Maps API Key: Create an API key with the Places API (New) enabled. Refer to [Use API Keys](https://developers.google.com/maps/documentation/javascript/get-api-key) for detailed instructions.
|
|
18
|
+
- **Google Maps API Key:** Create an API key with the Places API (New) enabled. Refer to [Use API Keys](https://developers.google.com/maps/documentation/javascript/get-api-key) for detailed instructions.
|
|
21
19
|
|
|
20
|
+
## Installation Svelte 5
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
```bash
|
|
23
|
+
npm i places-autocomplete-svelte
|
|
24
|
+
```
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
## Installation Svelte 4
|
|
26
27
|
|
|
27
28
|
```bash
|
|
28
|
-
|
|
29
|
+
npm i places-autocomplete-svelte@1.0.1
|
|
29
30
|
```
|
|
30
31
|
|
|
31
|
-
|
|
32
32
|
## Import Component
|
|
33
33
|
|
|
34
34
|
```javascript
|
|
@@ -37,168 +37,130 @@ import PlaceAutocomplete from 'places-autocomplete-svelte';
|
|
|
37
37
|
|
|
38
38
|
## Basic Usage
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
The request default `language: 'en-GB'` and `region: 'GB'`, see below to specify different.
|
|
40
|
+
1. **Provide your Google Maps API Key:** Replace `'--YOUR_API_KEY--'` with your actual Google Maps API key.
|
|
41
|
+
2. **Bind to Address Variables:** Use `bind:formattedAddress` to capture the selected address as string.
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
```js
|
|
43
|
+
```svelte
|
|
47
44
|
<script>
|
|
48
|
-
import
|
|
49
|
-
|
|
50
|
-
//the business name and address.
|
|
51
|
-
let formattedAddress = '';
|
|
52
|
-
// Your Google Maps Public API Key
|
|
53
|
-
let PUBLIC_GOOGLE_MAPS_API_KEY = '--YOUR_API_KEY--';
|
|
54
|
-
</script>
|
|
45
|
+
import { PlaceAutocomplete } from 'places-autocomplete-svelte';
|
|
55
46
|
|
|
56
|
-
|
|
47
|
+
let formattedAddress = '';
|
|
48
|
+
let PUBLIC_GOOGLE_MAPS_API_KEY = '--YOUR_API_KEY--';
|
|
49
|
+
</script>
|
|
57
50
|
|
|
58
|
-
|
|
59
|
-
<p>{formattedAddress}</p>
|
|
51
|
+
<PlaceAutocomplete bind:PUBLIC_GOOGLE_MAPS_API_KEY bind:formattedAddress />
|
|
60
52
|
|
|
53
|
+
<p>Formatted Address: {formattedAddress}</p>
|
|
61
54
|
```
|
|
62
|
-
- Replace `'--YOUR_API_KEY--'` with your actual Google Maps API key.
|
|
63
|
-
- The `formattedAddress` variable will be populated with the selected place's formatted address string.
|
|
64
55
|
|
|
65
|
-
##
|
|
56
|
+
## Specifying Countries/Regions
|
|
57
|
+
|
|
58
|
+
Use the `countries` property to refine search by region:
|
|
66
59
|
|
|
67
|
-
```
|
|
60
|
+
```svelte
|
|
68
61
|
<script>
|
|
69
|
-
|
|
70
|
-
// formatted address object
|
|
71
|
-
let formattedAddressObj = {
|
|
72
|
-
street_number: '',
|
|
73
|
-
street: '',
|
|
74
|
-
town: '',
|
|
75
|
-
county: '',
|
|
76
|
-
country_iso2: '',
|
|
77
|
-
postcode: ''
|
|
78
|
-
};
|
|
79
|
-
// Your Google Maps Public API Key
|
|
80
|
-
let PUBLIC_GOOGLE_MAPS_API_KEY = '--YOUR_API_KEY--';
|
|
62
|
+
// ... other imports
|
|
81
63
|
|
|
64
|
+
let countries = [
|
|
65
|
+
{ name: 'United Kingdom', region: 'GB', language: 'en-GB' },
|
|
66
|
+
{ name: 'United States', region: 'US', language: 'en-US' }
|
|
67
|
+
// ... more countries
|
|
68
|
+
];
|
|
82
69
|
</script>
|
|
83
70
|
|
|
84
|
-
<PlaceAutocomplete
|
|
85
|
-
bind:PUBLIC_GOOGLE_MAPS_API_KEY
|
|
86
|
-
bind:formattedAddressObj />
|
|
87
|
-
/**
|
|
88
|
-
* Formatted address
|
|
89
|
-
* {
|
|
90
|
-
* "street_number":"Etihad Stadium",
|
|
91
|
-
* "street":"Etihad Campus",
|
|
92
|
-
* "town":"Manchester",
|
|
93
|
-
* "county":"Greater Manchester",
|
|
94
|
-
* "country_iso2":"GB",
|
|
95
|
-
* "postcode":"M11 3FF"
|
|
96
|
-
* }
|
|
97
|
-
*/
|
|
98
|
-
<p>{JSON.stringify(formattedAddressObj)}</p>
|
|
99
|
-
|
|
71
|
+
<PlaceAutocomplete bind:PUBLIC_GOOGLE_MAPS_API_KEY bind:formattedAddress bind:countries />
|
|
100
72
|
```
|
|
101
73
|
|
|
102
|
-
- The `
|
|
103
|
-
|
|
104
|
-
Address Parsing:
|
|
74
|
+
- The `region` code follows the [CLDR two-character format](https://developers.google.com/maps/documentation/javascript/reference/autocomplete-data#AutocompleteRequest).
|
|
75
|
+
- The `language` in which to return results. [See details](https://developers.google.com/maps/documentation/javascript/reference/autocomplete-data#AutocompleteRequest.language)
|
|
105
76
|
|
|
106
|
-
|
|
77
|
+
## Accessing Full Response Data
|
|
107
78
|
|
|
108
|
-
|
|
109
|
-
- `street`: longText property of the `route`
|
|
110
|
-
- `town`: longText property of the `postal_town`
|
|
111
|
-
- `county`: longText property of the `administrative_area_level_2`
|
|
112
|
-
- `country_iso2`: shortText property of the `country`
|
|
113
|
-
- `postcode`: longText property of the `postal_code`
|
|
79
|
+
For maximum flexibility, access the complete unformatted response from the Google Maps API:
|
|
114
80
|
|
|
115
|
-
|
|
81
|
+
```svelte
|
|
82
|
+
<script>
|
|
83
|
+
// ... other imports
|
|
84
|
+
let fullResponse = {};
|
|
85
|
+
</script>
|
|
116
86
|
|
|
117
|
-
|
|
87
|
+
<PlaceAutocomplete bind:PUBLIC_GOOGLE_MAPS_API_KEY bind:fullResponse />
|
|
118
88
|
|
|
119
|
-
|
|
89
|
+
<pre>{JSON.stringify(fullResponse, null, 2)}</pre>
|
|
90
|
+
```
|
|
120
91
|
|
|
92
|
+
## Example
|
|
121
93
|
|
|
122
|
-
```
|
|
94
|
+
```svelte
|
|
123
95
|
<script>
|
|
124
|
-
import
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
let formattedAddress = '';
|
|
128
|
-
|
|
129
|
-
let
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
{ name: 'United
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
{ name: 'Greece', region: 'GR' },
|
|
136
|
-
{ name: 'Russia', region: 'RU' },
|
|
137
|
-
{ name: 'Japan', region: 'JP' }
|
|
138
|
-
];
|
|
96
|
+
import { PlaceAutocomplete } from 'places-autocomplete-svelte';
|
|
97
|
+
|
|
98
|
+
let PUBLIC_GOOGLE_MAPS_API_KEY = '--YOUR_API_KEY--';
|
|
99
|
+
let formattedAddress = '';
|
|
100
|
+
let fullResponse = {};
|
|
101
|
+
let formattedAddressObj = {};
|
|
102
|
+
let countries = [
|
|
103
|
+
{ name: 'United Kingdom', region: 'GB' , language:'en-GB'},
|
|
104
|
+
{ name: 'United States', region: 'US',language:'en-US' },
|
|
105
|
+
// ... more countries
|
|
106
|
+
];
|
|
139
107
|
</script>
|
|
140
108
|
|
|
141
|
-
<PlaceAutocomplete
|
|
142
|
-
bind:PUBLIC_GOOGLE_MAPS_API_KEY
|
|
143
|
-
bind:formattedAddress
|
|
144
|
-
bind:
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
109
|
+
<PlaceAutocomplete
|
|
110
|
+
bind:PUBLIC_GOOGLE_MAPS_API_KEY
|
|
111
|
+
bind:formattedAddress
|
|
112
|
+
bind:fullResponse
|
|
113
|
+
bind:formattedAddressObj
|
|
114
|
+
bind:countries
|
|
115
|
+
placeholder="Enter your address...">
|
|
148
116
|
|
|
149
117
|
```
|
|
150
118
|
|
|
151
|
-
- The `
|
|
119
|
+
- The `formattedAddress` - selected address as string.
|
|
120
|
+
- The `fullResponse` - the complete unformatted response from the Google Maps API.
|
|
121
|
+
- The `formattedAddressObj` - parsed address components, containing individual elements like street number, town, and postcode.
|
|
122
|
+
|
|
123
|
+
The `formattedAddressObj` mapping corresponds to the following component types:
|
|
124
|
+
|
|
125
|
+
- `formattedAddressObj.street_number`: longText property of the street_number
|
|
126
|
+
- `formattedAddressObj.street`: longText property of the route
|
|
127
|
+
- `formattedAddressObj.town`: longText property of the postal_town
|
|
128
|
+
- `formattedAddressObj.county`: longText property of the administrative_area_level_2
|
|
129
|
+
- `formattedAddressObj.country_iso2`: shortText property of the country
|
|
130
|
+
- `formattedAddressObj.postcode`: longText property of the postal_code
|
|
152
131
|
|
|
153
|
-
|
|
132
|
+
## Error Handling
|
|
154
133
|
|
|
155
|
-
|
|
134
|
+
The component will throw an error if:
|
|
156
135
|
|
|
136
|
+
- The Google Maps API key is invalid or missing.
|
|
137
|
+
- There are network issues connecting to the Google Maps service.
|
|
157
138
|
|
|
158
|
-
|
|
139
|
+
Handle these errors gracefully in your application:
|
|
159
140
|
|
|
160
|
-
```
|
|
141
|
+
```svelte
|
|
161
142
|
<script>
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
//
|
|
165
|
-
let
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
// countries
|
|
171
|
-
let countries = [
|
|
172
|
-
{ name: 'United Kingdom', region: 'GB' },
|
|
173
|
-
{ name: 'United States', region: 'US' },
|
|
174
|
-
{ name: 'Switzerland', region: 'CH' },
|
|
175
|
-
{ name: 'Greece', region: 'GR' },
|
|
176
|
-
{ name: 'Russia', region: 'RU' },
|
|
177
|
-
{ name: 'Japan', region: 'JP' }
|
|
178
|
-
];
|
|
143
|
+
// ... other imports
|
|
144
|
+
|
|
145
|
+
// Error handler
|
|
146
|
+
let pacError = '';
|
|
147
|
+
let onError = (error: string) => {
|
|
148
|
+
console.error(error);
|
|
149
|
+
pacError = error;
|
|
150
|
+
};
|
|
179
151
|
</script>
|
|
180
152
|
|
|
181
|
-
<PlaceAutocomplete
|
|
182
|
-
bind:formattedAddress
|
|
183
|
-
bind:formattedAddressObj
|
|
184
|
-
bind:fullResponse
|
|
185
|
-
bind:PUBLIC_GOOGLE_MAPS_API_KEY
|
|
186
|
-
bind:countries/>
|
|
153
|
+
<PlaceAutocomplete bind:PUBLIC_GOOGLE_MAPS_API_KEY {onError} />
|
|
187
154
|
|
|
155
|
+
{#if pacError}
|
|
156
|
+
<p class="error">{pacError}</p>
|
|
157
|
+
{/if}
|
|
188
158
|
```
|
|
189
|
-
Depending on your application requirements you can bind the component properties as needed.
|
|
190
|
-
Below example binds all three responsones:
|
|
191
|
-
- `formattedAddress` - place name and address as string
|
|
192
|
-
- `formattedAddressObj` - populated with the parsed address components
|
|
193
|
-
- `fullResponse` - populated address components response as it retruned from `fetchFilds()` method
|
|
194
|
-
|
|
195
|
-
## Customization:
|
|
196
|
-
|
|
197
|
-
- **Language:** The component defaults to `language: 'en-GB'` and `region: 'GB'`. You can customize these settings as needed.
|
|
198
159
|
|
|
160
|
+
## Contributing
|
|
199
161
|
|
|
162
|
+
Contributions are welcome! Please open an issue or submit a pull request on the [GitHub repository](https://github.com/alexpechkarev/places-autocomplete-svelte/).
|
|
200
163
|
|
|
201
164
|
## License
|
|
202
165
|
|
|
203
166
|
[MIT](LICENSE)
|
|
204
|
-
|
|
@@ -1,162 +1,249 @@
|
|
|
1
|
-
<script
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
let
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onMount } from 'svelte';
|
|
3
|
+
import * as GMaps from '@googlemaps/js-api-loader';
|
|
4
|
+
const { Loader } = GMaps;
|
|
5
|
+
|
|
6
|
+
// Props Interface
|
|
7
|
+
interface Props {
|
|
8
|
+
PUBLIC_GOOGLE_MAPS_API_KEY: string;
|
|
9
|
+
fetchFields: string[];
|
|
10
|
+
countries: { name: string; region: string }[];
|
|
11
|
+
formattedAddress: string;
|
|
12
|
+
fullResponse: { longText: string; shortText: string; types: Array<string> }[];
|
|
13
|
+
formattedAddressObj: {
|
|
14
|
+
street_number: string;
|
|
15
|
+
street: string;
|
|
16
|
+
town: string;
|
|
17
|
+
county: string;
|
|
18
|
+
country_iso2: string;
|
|
19
|
+
postcode: string;
|
|
20
|
+
};
|
|
21
|
+
onError: (error: string) => void;
|
|
22
|
+
}
|
|
23
|
+
// Bindable Props
|
|
24
|
+
let {
|
|
25
|
+
PUBLIC_GOOGLE_MAPS_API_KEY = $bindable(''),
|
|
26
|
+
/**
|
|
27
|
+
* By default using SKU: Place Detals (Location Only) - 0.005 USD per each
|
|
28
|
+
* @see https://developers.google.com/maps/documentation/javascript/usage-and-billing#location-placedetails
|
|
29
|
+
*/
|
|
30
|
+
fetchFields = $bindable(['formattedAddress', 'addressComponents']),
|
|
31
|
+
countries = $bindable([]),
|
|
32
|
+
formattedAddress = $bindable(''),
|
|
33
|
+
fullResponse = $bindable([]),
|
|
34
|
+
formattedAddressObj = $bindable({
|
|
35
|
+
street_number: '',
|
|
36
|
+
street: '',
|
|
37
|
+
town: '',
|
|
38
|
+
county: '',
|
|
39
|
+
country_iso2: '',
|
|
40
|
+
postcode: ''
|
|
41
|
+
}),
|
|
42
|
+
onError = $bindable((error: string) => {})
|
|
43
|
+
}: Props = $props();
|
|
44
|
+
|
|
45
|
+
// Check if countries are available
|
|
46
|
+
let hasCountries = countries.length > 0;
|
|
47
|
+
// Local variables
|
|
48
|
+
let inputRef: HTMLInputElement;
|
|
49
|
+
let currentSuggestion = $state(-1);
|
|
50
|
+
let title: string = $state('');
|
|
51
|
+
let results: any[] = $state([]);
|
|
52
|
+
let token;
|
|
53
|
+
let loader: GMaps.Loader;
|
|
54
|
+
let placesApi: { [key: string]: any } = {};
|
|
55
|
+
//https://developers.google.com/maps/documentation/javascript/reference/autocomplete-data#AutocompleteRequest.includedPrimaryTypes
|
|
56
|
+
let request = $state({
|
|
57
|
+
input: '',
|
|
58
|
+
language: 'en-GB',
|
|
59
|
+
region: 'GB',
|
|
60
|
+
sessionToken: ''
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
$effect(() => {
|
|
64
|
+
if (request.input == '') {
|
|
65
|
+
results = [];
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Reset search input and results.
|
|
71
|
+
*/
|
|
72
|
+
const reset = () => {
|
|
73
|
+
currentSuggestion = -1;
|
|
74
|
+
request.input = '';
|
|
75
|
+
results = [];
|
|
76
|
+
refreshToken(request);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Make request and get autocomplete suggestions.
|
|
81
|
+
* @param event
|
|
82
|
+
*/
|
|
83
|
+
const makeAcRequest = async (
|
|
84
|
+
event: Event & { currentTarget: HTMLInputElement }
|
|
85
|
+
): Promise<void> => {
|
|
86
|
+
const target = event.currentTarget as HTMLInputElement;
|
|
87
|
+
if (target?.value == '') {
|
|
88
|
+
title = '';
|
|
89
|
+
request.input = '';
|
|
90
|
+
results = [];
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
request.input = target.value;
|
|
95
|
+
try {
|
|
96
|
+
const { suggestions } =
|
|
97
|
+
await placesApi.AutocompleteSuggestion.fetchAutocompleteSuggestions(request);
|
|
98
|
+
results = [];
|
|
99
|
+
// iterate suggestions and add results to an array
|
|
100
|
+
for (const suggestion of suggestions) {
|
|
101
|
+
// add suggexstions to results
|
|
102
|
+
results.push({
|
|
103
|
+
to_pace: suggestion.placePrediction.toPlace(),
|
|
104
|
+
text: suggestion.placePrediction.text.toString()
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
} catch (e: any) {
|
|
108
|
+
onError((e.name || 'An error occurred') + ' - ' + (e.message || 'see console for details.'));
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* Event handler for clicking on a suggested place.
|
|
113
|
+
//https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/reference/autocomplete-data#AutocompleteSuggestion
|
|
114
|
+
* @param place
|
|
115
|
+
*/
|
|
116
|
+
const onPlaceSelected = async (place: {
|
|
117
|
+
[x: string]: any;
|
|
118
|
+
fetchFields: (arg0: { fields: string[] }) => any;
|
|
119
|
+
addressComponents: any;
|
|
120
|
+
formattedAddress: string;
|
|
121
|
+
}): Promise<void> => {
|
|
122
|
+
try {
|
|
123
|
+
await place.fetchFields({
|
|
124
|
+
fields: fetchFields
|
|
125
|
+
});
|
|
126
|
+
let placeData = place.toJSON();
|
|
127
|
+
formattedAddressObj = {
|
|
128
|
+
street_number: '',
|
|
129
|
+
street: '',
|
|
130
|
+
town: '',
|
|
131
|
+
county: '',
|
|
132
|
+
country_iso2: '',
|
|
133
|
+
postcode: ''
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
title = 'Selected address: ' + placeData.formattedAddress;
|
|
137
|
+
formattedAddress = placeData.formattedAddress;
|
|
138
|
+
fullResponse = placeData.addressComponents;
|
|
139
|
+
|
|
140
|
+
for (const component of placeData.addressComponents) {
|
|
141
|
+
switch (component.types[0]) {
|
|
142
|
+
case 'street_number':
|
|
143
|
+
case 'point_of_interest':
|
|
144
|
+
case 'establishment':
|
|
145
|
+
formattedAddressObj.street_number = component.longText;
|
|
146
|
+
break;
|
|
147
|
+
case 'route':
|
|
148
|
+
case 'premise':
|
|
149
|
+
formattedAddressObj.street = component.longText;
|
|
150
|
+
break;
|
|
151
|
+
case 'postal_town':
|
|
152
|
+
formattedAddressObj.town = component.longText;
|
|
153
|
+
break;
|
|
154
|
+
case 'administrative_area_level_2':
|
|
155
|
+
formattedAddressObj.county = component.longText;
|
|
156
|
+
break;
|
|
157
|
+
case 'country':
|
|
158
|
+
formattedAddressObj.country_iso2 = component.shortText;
|
|
159
|
+
break;
|
|
160
|
+
case 'postal_code':
|
|
161
|
+
formattedAddressObj.postcode = component.longText;
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
} catch (e: any) {
|
|
166
|
+
onError(
|
|
167
|
+
(e.name || 'An error occurred') + ' - ' + (e.message || 'error fetching place details')
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// reset srarch input and results
|
|
172
|
+
reset();
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Helper function to refresh the session token.
|
|
177
|
+
* @param request
|
|
178
|
+
*/
|
|
179
|
+
const refreshToken = async (request: {
|
|
180
|
+
input?: string;
|
|
181
|
+
language?: string;
|
|
182
|
+
region?: string;
|
|
183
|
+
sessionToken?: any;
|
|
184
|
+
}): Promise<{ input?: string; language?: string; region?: string; sessionToken?: any }> => {
|
|
185
|
+
try {
|
|
186
|
+
token = new placesApi.AutocompleteSessionToken();
|
|
187
|
+
request.sessionToken = token;
|
|
188
|
+
return request;
|
|
189
|
+
} catch (e: any) {
|
|
190
|
+
onError((e.name || 'An error occurred') + ' - ' + (e.message || 'error fetch token'));
|
|
191
|
+
return request;
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
/**
|
|
195
|
+
* Initialize the Google Maps JavaScript API Loader.
|
|
196
|
+
*/
|
|
197
|
+
onMount(async (): Promise<void> => {
|
|
198
|
+
inputRef.focus();
|
|
199
|
+
|
|
200
|
+
try {
|
|
201
|
+
loader = new Loader({
|
|
202
|
+
apiKey: PUBLIC_GOOGLE_MAPS_API_KEY,
|
|
203
|
+
version: 'weekly',
|
|
204
|
+
libraries: ['places']
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
const { AutocompleteSessionToken, AutocompleteSuggestion } =
|
|
208
|
+
await loader.importLibrary('places');
|
|
209
|
+
placesApi.AutocompleteSessionToken = AutocompleteSessionToken;
|
|
210
|
+
placesApi.AutocompleteSuggestion = AutocompleteSuggestion;
|
|
211
|
+
token = new placesApi.AutocompleteSessionToken();
|
|
212
|
+
request.sessionToken = token;
|
|
213
|
+
} catch (e: any) {
|
|
214
|
+
onError(
|
|
215
|
+
(e.name || 'An error occurred') + ' - ' + (e.message || 'Error loading Google Maps API')
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
/**
|
|
220
|
+
* Handles keyboard events for navigating the suggestions.
|
|
221
|
+
*/
|
|
222
|
+
function onKeyDown(e: KeyboardEvent) {
|
|
223
|
+
if (e.key === 'ArrowDown') {
|
|
224
|
+
currentSuggestion = Math.min(currentSuggestion + 1, results.length - 1);
|
|
225
|
+
} else if (e.key === 'ArrowUp') {
|
|
226
|
+
currentSuggestion = Math.max(currentSuggestion - 1, 0);
|
|
227
|
+
} else if (e.key === 'Enter') {
|
|
228
|
+
e.preventDefault();
|
|
229
|
+
if (currentSuggestion >= 0) {
|
|
230
|
+
onPlaceSelected(results[currentSuggestion].to_pace);
|
|
231
|
+
}
|
|
232
|
+
} else if (e.key === 'Escape') {
|
|
233
|
+
// reset srarch input and results
|
|
234
|
+
reset();
|
|
235
|
+
}
|
|
236
|
+
}
|
|
141
237
|
</script>
|
|
142
238
|
|
|
143
239
|
<svelte:window on:keydown={onKeyDown} />
|
|
144
240
|
|
|
145
241
|
<section class="my-10">
|
|
146
|
-
{#if placesError}
|
|
147
|
-
<div
|
|
148
|
-
class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
|
149
|
-
role="alert"
|
|
150
|
-
>
|
|
151
|
-
<strong class="font-bold">Error!</strong>
|
|
152
|
-
<span class="block">Check your PUBLIC_GOOGLE_MAPS_API_KEY and API restrictions.</span>
|
|
153
|
-
<span class="block sm:inline">{placesError}</span>
|
|
154
|
-
</div>
|
|
155
|
-
{/if}
|
|
156
|
-
|
|
157
242
|
<div class="grid grid-cols-1 lg:grid-cols-6 gap-x-4">
|
|
158
243
|
<div class:lg:col-span-4={hasCountries} class:lg:col-span-6={!hasCountries}>
|
|
159
|
-
<label class="mt-1 text-sm leading-6 text-gray-600" for="search"
|
|
244
|
+
<label class="mt-1 text-sm leading-6 text-gray-600" for="search"
|
|
245
|
+
>Start typing your address</label
|
|
246
|
+
>
|
|
160
247
|
<div class="relative z-50 transform rounded-xl mt-4">
|
|
161
248
|
<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
|
|
162
249
|
<svg
|
|
@@ -170,15 +257,16 @@ function onKeyDown(e) {
|
|
|
170
257
|
stroke-linejoin="round"><circle cx="11" cy="11" r="8" /><path d="m21 21-4.3-4.3" /></svg
|
|
171
258
|
>
|
|
172
259
|
</div>
|
|
260
|
+
|
|
173
261
|
<input
|
|
174
262
|
type="text"
|
|
175
263
|
name="search"
|
|
176
264
|
bind:this={inputRef}
|
|
177
|
-
class="border-1 w-full rounded-md border-
|
|
265
|
+
class="border-1 w-full rounded-md border-0 shadow-sm bg-gray-100 px-4 py-2.5 pl-10 pr-20 text-gray-900 ring-1 ring-inset ring-gray-300 focus:ring-2 sm:text-sm"
|
|
178
266
|
placeholder="Search..."
|
|
179
267
|
aria-controls="options"
|
|
180
268
|
bind:value={request.input}
|
|
181
|
-
|
|
269
|
+
oninput={makeAcRequest}
|
|
182
270
|
/>
|
|
183
271
|
|
|
184
272
|
{#if results.length > 0}
|
|
@@ -201,19 +289,22 @@ function onKeyDown(e) {
|
|
|
201
289
|
id="options"
|
|
202
290
|
>
|
|
203
291
|
{#each results as place, i}
|
|
204
|
-
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
205
|
-
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
|
206
|
-
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
|
|
207
292
|
<li
|
|
208
293
|
class="z-50 cursor-default select-none py-2 pl-4 text-gray-900 hover:bg-indigo-500 hover:text-white"
|
|
209
294
|
class:bg-indigo-500={i === currentSuggestion}
|
|
210
295
|
class:bg-white={i !== currentSuggestion}
|
|
211
296
|
class:text-white={i === currentSuggestion}
|
|
212
297
|
id="option-{i + 1}"
|
|
213
|
-
tabindex={i + 1}
|
|
214
|
-
on:click={() => onPlaceSelected(place.to_pace)}
|
|
215
298
|
>
|
|
216
|
-
|
|
299
|
+
<!-- svelte-ignore a11y_invalid_attribute -->
|
|
300
|
+
<a
|
|
301
|
+
href="javascript:void(0)"
|
|
302
|
+
class="block w-full"
|
|
303
|
+
tabindex={i + 1}
|
|
304
|
+
onclick={() => onPlaceSelected(place.to_pace)}
|
|
305
|
+
>
|
|
306
|
+
{place.text}
|
|
307
|
+
</a>
|
|
217
308
|
</li>
|
|
218
309
|
{/each}
|
|
219
310
|
</ul>
|
|
@@ -228,7 +319,7 @@ function onKeyDown(e) {
|
|
|
228
319
|
<select
|
|
229
320
|
id="country"
|
|
230
321
|
name="country"
|
|
231
|
-
class="h-10 w-full rounded-md border-
|
|
322
|
+
class="h-10 w-full rounded-md border-0 bg-transparent py-0 pl-2 pr-7 text-gray-500 focus:ring-2 ring-1 ring-inset ring-gray-300 focus:ring-inset focus:ring-indigo-600 sm:text-sm"
|
|
232
323
|
bind:value={request.region}
|
|
233
324
|
>
|
|
234
325
|
{#each countries as country}
|
|
@@ -238,12 +329,8 @@ function onKeyDown(e) {
|
|
|
238
329
|
</div>
|
|
239
330
|
</div>
|
|
240
331
|
|
|
241
|
-
<div class="lg:col-span-6">
|
|
332
|
+
<div class="lg:col-span-6 mt-2">
|
|
242
333
|
<div class="text-sm font-medium leading-6 text-gray-500">{title}</div>
|
|
243
334
|
</div>
|
|
244
335
|
</div>
|
|
245
336
|
</section>
|
|
246
|
-
|
|
247
|
-
<style>
|
|
248
|
-
input,select,ul{margin:0;padding:0}.absolute,.sr-only{position:absolute}.block,svg{display:block}*,.border-gray-300{--tw-border-opacity:1}.text-gray-500,.text-gray-900,.text-red-700,.text-white{--tw-text-opacity:1}*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb;--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / 0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }:after,:before{--tw-content:''}:host,section{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:system-ui,sans-serif,apple color emoji,segoe ui emoji,Segoe UI Symbol,noto color emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}strong{font-weight:bolder}kbd{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}input,select{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit}input:where([type=button]),input:where([type=reset]),input:where([type=submit]){background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}ul{list-style:none}.cursor-default,:disabled{cursor:default}svg{vertical-align:middle}[type=text],input:where(:not([type])),select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#6b7280;border-width:1px;border-radius:0;padding:.5rem .75rem;font-size:1rem;line-height:1.5rem;--tw-shadow:0 0 #0000}[type=text]:focus,input:where(:not([type])):focus,select:focus{outline:transparent solid 2px;outline-offset:2px;--tw-ring-inset:var(--tw-empty,);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);border-color:#2563eb}input::-moz-placeholder{color:#6b7280;opacity:1}input::placeholder{color:#6b7280;opacity:1}select{text-transform:none;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIGZpbGw9J25vbmUnIHZpZXdCb3g9JzAgMCAyMCAyMCc+PHBhdGggc3Ryb2tlPScjNmI3MjgwJyBzdHJva2UtbGluZWNhcD0ncm91bmQnIHN0cm9rZS1saW5lam9pbj0ncm91bmQnIHN0cm9rZS13aWR0aD0nMS41JyBkPSdNNiA4bDQgNCA0LTQnLz48L3N2Zz4=);background-position:right .5rem center;background-repeat:no-repeat;background-size:1.5em 1.5em;padding-right:2.5rem;-webkit-print-color-adjust:exact;print-color-adjust:exact}:root{--background:0 0% 100%;--foreground:222.2 84% 4.9%;--muted:210 40% 96.1%;--muted-foreground:215.4 16.3% 46.9%;--popover:0 0% 100%;--popover-foreground:222.2 84% 4.9%;--card:0 0% 100%;--card-foreground:222.2 84% 4.9%;--border:214.3 31.8% 91.4%;--input:214.3 31.8% 91.4%;--primary:222.2 47.4% 11.2%;--primary-foreground:210 40% 98%;--secondary:210 40% 96.1%;--secondary-foreground:222.2 47.4% 11.2%;--accent:210 40% 96.1%;--accent-foreground:222.2 47.4% 11.2%;--destructive:0 72.2% 50.6%;--destructive-foreground:210 40% 98%;--ring:222.2 84% 4.9%;--radius:0.5rem}*{border-color:hsl(var(--border) / var(--tw-border-opacity))}::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / 0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }.sr-only{width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.relative{position:relative}.inset-y-0{top:0;bottom:0}.left-0{left:0}.right-0{right:0}.z-50{z-index:50}.-mb-2{margin-bottom:-.5rem}.mr-1{margin-right:.25rem}.mt-4{margin-top:1rem}.flex{display:flex}.inline-flex{display:inline-flex}.hidden{display:none}.h-10{height:2.5rem}.h-5{height:1.25rem}.max-h-60{max-height:15rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-8{width:2rem}.w-full{width:100%}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr));grid-template-columns:1fr}.items-center{align-items:center}.gap-x-4{-moz-column-gap:1rem;column-gap:1rem;row-gap:1rem}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-gray-300{border-color:rgb(209 213 219 / var(--tw-border-opacity))}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246 / var(--tw-bg-opacity))}.bg-indigo-500,.hover\:bg-indigo-500:hover{--tw-bg-opacity:1;background-color:rgb(99 102 241 / var(--tw-bg-opacity))}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255 / var(--tw-bg-opacity))}.px-1{padding-left:.25rem;padding-right:.25rem}.px-4{padding-left:1rem;padding-right:1rem}.py-0{padding-top:0;padding-bottom:0}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.pl-10{padding-left:2.5rem}.pl-2{padding-left:.5rem}.pl-3{padding-left:.75rem}.pl-4{padding-left:1rem}.pr-1\.5{padding-right:.375rem}.pr-20{padding-right:5rem}.pr-7{padding-right:1.75rem}.text-base{font-size:1rem;line-height:1.5rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.text-gray-500{color:rgb(107 114 128 / var(--tw-text-opacity))}.text-gray-900{color:rgb(17 24 39 / var(--tw-text-opacity))}.text-red-700{color:rgb(185 28 28 / var(--tw-text-opacity))}.text-white{color:rgb(255 255 255 / var(--tw-text-opacity))}.shadow-lg{--tw-shadow:0 10px 15px -3px rgb(0 0 0 / 0.1),0 4px 6px -4px rgb(0 0 0 / 0.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.focus\:ring-1:focus,.focus\:ring-2:focus,.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\:ring-1:focus,.ring-1{--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.ring-black{--tw-ring-opacity:1;--tw-ring-color:rgb(0 0 0 / var(--tw-ring-opacity))}.focus\:outline-none:focus{outline:transparent solid 2px;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.focus\:ring-inset:focus{--tw-ring-inset:inset}@media (min-width:640px){.sm\:text-sm{font-size:.875rem;line-height:1.25rem}}@media (min-width:1024px){.lg\:col-span-2{grid-column:span 2/span 2}}@keyframes swipe-out{0%{transform:translateY(calc(var(--lift) * var(--offset) + var(--swipe-amount)));opacity:1}to{transform:translateY(calc(var(--lift) * var(--offset) + var(--swipe-amount) + var(--lift) * -100%));opacity:0}}.grid{display:grid}@media (min-width:768px){.lg\:grid-cols-6{grid-template-columns:repeat(6,1fr)}.lg\:col-span-6{grid-column-start:span 6}.lg\:col-span-4{grid-column-start:span 4}.lg\:col-span-2{grid-column-start:span 2}}.my-10{margin-top:2.5rem;margin-bottom:2.5rem} .justify-center {justify-content: center;} .hover\:text-white:hover{color:rgb(255 255 255 / var(--tw-text-opacity))}
|
|
249
|
-
</style>
|
|
@@ -1,37 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
country_iso2: string;
|
|
22
|
-
postcode: string;
|
|
23
|
-
};
|
|
1
|
+
declare const PlaceAutocomplete: import("svelte").Component<{
|
|
2
|
+
PUBLIC_GOOGLE_MAPS_API_KEY: string;
|
|
3
|
+
fetchFields: string[];
|
|
4
|
+
countries: {
|
|
5
|
+
name: string;
|
|
6
|
+
region: string;
|
|
7
|
+
}[];
|
|
8
|
+
formattedAddress: string;
|
|
9
|
+
fullResponse: {
|
|
10
|
+
longText: string;
|
|
11
|
+
shortText: string;
|
|
12
|
+
types: Array<string>;
|
|
13
|
+
}[];
|
|
14
|
+
formattedAddressObj: {
|
|
15
|
+
street_number: string;
|
|
16
|
+
street: string;
|
|
17
|
+
town: string;
|
|
18
|
+
county: string;
|
|
19
|
+
country_iso2: string;
|
|
20
|
+
postcode: string;
|
|
24
21
|
};
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
slots: {};
|
|
29
|
-
exports?: {} | undefined;
|
|
30
|
-
bindings?: string | undefined;
|
|
31
|
-
};
|
|
32
|
-
export type PlaceAutocompleteProps = typeof __propDef.props;
|
|
33
|
-
export type PlaceAutocompleteEvents = typeof __propDef.events;
|
|
34
|
-
export type PlaceAutocompleteSlots = typeof __propDef.slots;
|
|
35
|
-
export default class PlaceAutocomplete extends SvelteComponent<PlaceAutocompleteProps, PlaceAutocompleteEvents, PlaceAutocompleteSlots> {
|
|
36
|
-
}
|
|
37
|
-
export {};
|
|
22
|
+
onError: (error: string) => void;
|
|
23
|
+
}, {}, "PUBLIC_GOOGLE_MAPS_API_KEY" | "fetchFields" | "formattedAddress" | "countries" | "fullResponse" | "formattedAddressObj" | "onError">;
|
|
24
|
+
export default PlaceAutocomplete;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "places-autocomplete-svelte",
|
|
3
3
|
"license": "MIT",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "2.0.6",
|
|
5
5
|
"description": "A Svelte component that leverages the power of Google Places New API to provide a user-friendly autocomplete experience for location searches.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"svelte",
|
|
@@ -55,34 +55,41 @@
|
|
|
55
55
|
"!dist/**/*.test.*",
|
|
56
56
|
"!dist/**/*.spec.*"
|
|
57
57
|
],
|
|
58
|
+
"publishConfig": {
|
|
59
|
+
"@alexpechkarev:registry": "https://npm.pkg.github.com",
|
|
60
|
+
"provenance": true
|
|
61
|
+
},
|
|
58
62
|
"peerDependencies": {
|
|
59
|
-
"svelte": "^
|
|
63
|
+
"svelte": "^5.1.4"
|
|
60
64
|
},
|
|
61
65
|
"devDependencies": {
|
|
62
|
-
"@sveltejs/adapter-auto": "^3.
|
|
63
|
-
"@sveltejs/adapter-cloudflare": "^4.
|
|
64
|
-
"@sveltejs/kit": "^2.
|
|
65
|
-
"@sveltejs/package": "^2.3.
|
|
66
|
-
"@sveltejs/vite-plugin-svelte": "^
|
|
67
|
-
"@types/eslint": "^
|
|
68
|
-
"
|
|
66
|
+
"@sveltejs/adapter-auto": "^3.3.1",
|
|
67
|
+
"@sveltejs/adapter-cloudflare": "^4.7.4",
|
|
68
|
+
"@sveltejs/kit": "^2.7.3",
|
|
69
|
+
"@sveltejs/package": "^2.3.7",
|
|
70
|
+
"@sveltejs/vite-plugin-svelte": "^4.0.0",
|
|
71
|
+
"@types/eslint": "^9.6.1",
|
|
72
|
+
"autoprefixer": "^10.4.20",
|
|
73
|
+
"eslint": "^9.13.0",
|
|
69
74
|
"eslint-config-prettier": "^9.1.0",
|
|
70
|
-
"eslint-plugin-svelte": "^2.
|
|
71
|
-
"globals": "^15.
|
|
75
|
+
"eslint-plugin-svelte": "^2.46.0",
|
|
76
|
+
"globals": "^15.11.0",
|
|
77
|
+
"postcss": "^8.4.47",
|
|
72
78
|
"prettier": "^3.3.3",
|
|
73
|
-
"prettier-plugin-svelte": "^3.2.
|
|
74
|
-
"publint": "^0.2.
|
|
75
|
-
"svelte": "^
|
|
76
|
-
"svelte-check": "^
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
-
"typescript
|
|
80
|
-
"
|
|
79
|
+
"prettier-plugin-svelte": "^3.2.7",
|
|
80
|
+
"publint": "^0.2.12",
|
|
81
|
+
"svelte": "^5.1.4",
|
|
82
|
+
"svelte-check": "^4.0.5",
|
|
83
|
+
"tailwindcss": "^3.4.14",
|
|
84
|
+
"tslib": "^2.8.0",
|
|
85
|
+
"typescript": "^5.6.3",
|
|
86
|
+
"typescript-eslint": "^8.12.2",
|
|
87
|
+
"vite": "^5.4.10"
|
|
81
88
|
},
|
|
82
89
|
"svelte": "./dist/index.js",
|
|
83
90
|
"types": "./dist/PlaceAutocomplete.svelte.d.ts",
|
|
84
91
|
"type": "module",
|
|
85
92
|
"dependencies": {
|
|
86
|
-
"@googlemaps/js-api-loader": "^1.16.
|
|
93
|
+
"@googlemaps/js-api-loader": "^1.16.8"
|
|
87
94
|
}
|
|
88
95
|
}
|