places-autocomplete-svelte 2.1.7 → 2.1.8
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 +30 -46
- package/dist/PlaceAutocomplete.svelte +76 -68
- package/dist/helpers.d.ts +11 -1
- package/dist/helpers.js +55 -0
- package/dist/interfaces.d.ts +9 -13
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -69,19 +69,29 @@ let onResponse = (response) => {
|
|
|
69
69
|
|
|
70
70
|
|
|
71
71
|
## Component Properties
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
| `
|
|
76
|
-
| `
|
|
77
|
-
| `
|
|
78
|
-
| `
|
|
79
|
-
| `
|
|
80
|
-
| `
|
|
81
|
-
|
|
82
|
-
|
|
72
|
+
|
|
73
|
+
| Property | Type | Description | Required | Default Value |
|
|
74
|
+
|--------------------------|-----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|-----------------------------------------------|
|
|
75
|
+
| `PUBLIC_GOOGLE_MAPS_API_KEY` | `String` | Your Google Maps Places API Key. | Yes | |
|
|
76
|
+
| `onResponse` | `CustomEvent` | Dispatched when a place is selected, containing the place details in `event.detail`. | Yes | |
|
|
77
|
+
| `onError` | `CustomEvent` | Dispatched when an error occurs, with the error message in `event.detail`. | No | |
|
|
78
|
+
| `requestParams` | `Object` | Object for additional request parameters (e.g., `types`, `bounds`, `origin`, `region`, `language`). See [AutocompleteRequest](https://developers.google.com/maps/documentation/javascript/reference/autocomplete-data#AutocompleteRequest). | No | `{}` |
|
|
79
|
+
| `fetchFields` | `Array` | Array of place data fields to return. See [Supported Fields](https://developers.google.com/maps/documentation/javascript/reference/places-service#PlaceResult) | No | `['formattedAddress', 'addressComponents']` |
|
|
80
|
+
| `options` | `Object` | Options for customizing the component's behavior and appearance. See "Customization" below. | No | See default values in "Customization" |
|
|
81
|
+
|
|
82
|
+
|
|
83
83
|
|
|
84
84
|
## Customization
|
|
85
|
+
### Options
|
|
86
|
+
|
|
87
|
+
| Property | Type | Description | Default Value |
|
|
88
|
+
|----------------|-----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------|
|
|
89
|
+
| `autofocus` | `boolean` | If `true`, the input field will be focused automatically when the component mounts. | `false` |
|
|
90
|
+
| `placeholder` | `String` | Placeholder text for the input field. | `"Search..."` |
|
|
91
|
+
| `autocomplete`| `string` | HTML `autocomplete` attribute for the input field. Set to `"off"` to disable browser autocomplete. | `"off"` |
|
|
92
|
+
| `show_distance`| `boolean` | If `true`, and if an `origin` is specified in `requestParams`, displays the distance to each suggestion. The distance is calculated as a geodesic in meters. | `false` |
|
|
93
|
+
| `classes` | `Object` | Object to override default Tailwind CSS classes.structure. | See [styling](https://places-autocomplete-demo.pages.dev/examples/styling) |
|
|
94
|
+
|
|
85
95
|
### Styling
|
|
86
96
|
Customize the component's appearance by providing an object to the classes property. This object should contain key-value pairs, where the keys correspond to the component's elements and the values are your custom CSS class names. See [styling](https://places-autocomplete-demo.pages.dev/examples/styling) for details.
|
|
87
97
|
|
|
@@ -93,17 +103,6 @@ Fine-tune the autocomplete search with the requestParams property. This property
|
|
|
93
103
|
<script>
|
|
94
104
|
// ... other imports
|
|
95
105
|
|
|
96
|
-
/**
|
|
97
|
-
* @type string optional
|
|
98
|
-
*/
|
|
99
|
-
const placeholder = 'Search...';
|
|
100
|
-
/**
|
|
101
|
-
* @type string optional
|
|
102
|
-
* The <input> HTML autocomplete attribute.
|
|
103
|
-
* default: 'off'
|
|
104
|
-
* */
|
|
105
|
-
const autocompete = 'off';
|
|
106
|
-
|
|
107
106
|
/**
|
|
108
107
|
* @type boolean optional
|
|
109
108
|
* Boolean attribute indicating that an element should be focused on page load.
|
|
@@ -127,27 +126,14 @@ const requestParams = {
|
|
|
127
126
|
|
|
128
127
|
/**
|
|
129
128
|
* @type object optional
|
|
130
|
-
*
|
|
129
|
+
* Options
|
|
131
130
|
*/
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
'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',
|
|
139
|
-
kbd_container: 'absolute inset-y-0 right-0 flex py-1.5 pr-1.5',
|
|
140
|
-
kbd_escape:
|
|
141
|
-
'inline-flex items-center rounded border border-gray-300 px-1 font-sans text-xs text-gray-500 w-8 mr-1',
|
|
142
|
-
kbd_up:
|
|
143
|
-
'inline-flex items-center justify-center rounded border border-gray-300 px-1 font-sans text-xs text-gray-500 w-6',
|
|
144
|
-
kbd_down:
|
|
145
|
-
'inline-flex items-center rounded border border-gray-400 px-1 font-sans text-xs text-gray-500 justify-center w-6',
|
|
146
|
-
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',
|
|
147
|
-
li: 'z-50 cursor-default select-none py-2 pl-4 text-gray-900 hover:bg-indigo-500 hover:text-white',
|
|
148
|
-
li_current: 'bg-indigo-500 text-white',
|
|
149
|
-
li_a: 'block w-full'
|
|
150
|
-
},
|
|
131
|
+
const options = {
|
|
132
|
+
autofocus: false,
|
|
133
|
+
autocompete: 'off',
|
|
134
|
+
placeholder: 'Start typing your address',
|
|
135
|
+
show_distance: true,
|
|
136
|
+
};
|
|
151
137
|
|
|
152
138
|
/**
|
|
153
139
|
* @type array optional
|
|
@@ -160,11 +146,9 @@ const fetchFields = ['formattedAddress', 'addressComponents'];
|
|
|
160
146
|
{onResponse}
|
|
161
147
|
{PUBLIC_GOOGLE_MAPS_API_KEY}
|
|
162
148
|
{requestParams}
|
|
163
|
-
{
|
|
164
|
-
{autocompete}
|
|
165
|
-
{autofocus}
|
|
149
|
+
{options}
|
|
166
150
|
{fetchFields}
|
|
167
|
-
|
|
151
|
+
|
|
168
152
|
/>
|
|
169
153
|
|
|
170
154
|
```
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { onMount } from 'svelte';
|
|
3
3
|
import * as GMaps from '@googlemaps/js-api-loader';
|
|
4
|
-
import type { Props } from './interfaces.js';
|
|
5
|
-
import { validateRequestParams } from './helpers.js';
|
|
4
|
+
import type { ComponentOptions, Props } from './interfaces.js';
|
|
5
|
+
import { validateOptions, validateRequestParams } from './helpers.js';
|
|
6
6
|
const { Loader } = GMaps;
|
|
7
7
|
|
|
8
8
|
let {
|
|
@@ -12,42 +12,38 @@
|
|
|
12
12
|
*/
|
|
13
13
|
PUBLIC_GOOGLE_MAPS_API_KEY,
|
|
14
14
|
fetchFields = $bindable(['formattedAddress', 'addressComponents']),
|
|
15
|
-
|
|
16
|
-
autocompete = 'off',
|
|
17
|
-
autofocus = false,
|
|
18
|
-
classes = {
|
|
19
|
-
section: '',
|
|
20
|
-
container: 'relative z-10 transform rounded-xl mt-4',
|
|
21
|
-
icon_container: 'pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3',
|
|
22
|
-
icon: '<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8" /><path d="m21 21-4.3-4.3" /></svg>',
|
|
23
|
-
input:
|
|
24
|
-
'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',
|
|
25
|
-
kbd_container: 'absolute inset-y-0 right-0 flex py-1.5 pr-1.5',
|
|
26
|
-
kbd_escape:
|
|
27
|
-
'inline-flex items-center rounded border border-gray-300 px-1 font-sans text-xs text-gray-500 w-8 mr-1',
|
|
28
|
-
kbd_up:
|
|
29
|
-
'inline-flex items-center justify-center rounded border border-gray-300 px-1 font-sans text-xs text-gray-500 w-6',
|
|
30
|
-
kbd_down:
|
|
31
|
-
'inline-flex items-center rounded border border-gray-400 px-1 font-sans text-xs text-gray-500 justify-center w-6',
|
|
32
|
-
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',
|
|
33
|
-
li: 'z-50 cursor-default select-none py-2 pl-4 text-gray-900 hover:bg-indigo-500 hover:text-white',
|
|
34
|
-
li_current: 'bg-indigo-500 text-white',
|
|
35
|
-
li_a: 'block w-full'
|
|
36
|
-
},
|
|
15
|
+
options,
|
|
37
16
|
onResponse = $bindable((e: Event) => {}),
|
|
38
17
|
onError = $bindable((error: string) => {}),
|
|
39
18
|
requestParams = {}
|
|
40
19
|
}: Props = $props();
|
|
41
20
|
|
|
21
|
+
// validate options
|
|
22
|
+
options = validateOptions(options);
|
|
23
|
+
|
|
42
24
|
// set classes as state
|
|
43
|
-
let cl = $state(classes);
|
|
25
|
+
let cl = $state(options.classes);
|
|
44
26
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
27
|
+
// format meters to km and meters
|
|
28
|
+
const formatMeters = function (meters: number): string|null {
|
|
29
|
+
if(typeof meters !== 'number') {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const km = Math.floor(meters / 1000);
|
|
33
|
+
const remainingMeters = meters % 1000;
|
|
34
|
+
let formattedString = '';
|
|
35
|
+
if (km > 0) {
|
|
36
|
+
formattedString += km + 'km ';
|
|
37
|
+
}
|
|
38
|
+
formattedString += remainingMeters + 'm';
|
|
39
|
+
return formattedString;
|
|
40
|
+
};
|
|
50
41
|
|
|
42
|
+
// reset keyboard classes
|
|
43
|
+
const resetKbdClasses = () => {
|
|
44
|
+
cl.kbd_down = options.classes.kbd_down;
|
|
45
|
+
cl.kbd_up = options.classes.kbd_up;
|
|
46
|
+
};
|
|
51
47
|
|
|
52
48
|
// Local variables
|
|
53
49
|
let inputRef: HTMLInputElement;
|
|
@@ -55,12 +51,14 @@
|
|
|
55
51
|
let results: any[] = $state([]);
|
|
56
52
|
let loader: GMaps.Loader;
|
|
57
53
|
let placesApi: { [key: string]: any } = {};
|
|
54
|
+
|
|
55
|
+
|
|
58
56
|
//https://developers.google.com/maps/documentation/javascript/reference/autocomplete-data
|
|
59
57
|
// validate and merge requestParams with requestParamsDefault
|
|
60
58
|
//let request = $state(validateRequestParams(Object.assign(requestParamsDefault, requestParams)));
|
|
61
59
|
requestParams = validateRequestParams(requestParams);
|
|
62
60
|
let request = $state(requestParams);
|
|
63
|
-
|
|
61
|
+
//$inspect(request);
|
|
64
62
|
// clear result when input is empty
|
|
65
63
|
$effect(() => {
|
|
66
64
|
if (request.input == '') {
|
|
@@ -108,12 +106,15 @@
|
|
|
108
106
|
const { suggestions } =
|
|
109
107
|
await placesApi.AutocompleteSuggestion.fetchAutocompleteSuggestions(request);
|
|
110
108
|
results = [];
|
|
109
|
+
const formatter = new Intl.NumberFormat('en');
|
|
111
110
|
// iterate suggestions and add results to an array
|
|
112
111
|
for (const suggestion of suggestions) {
|
|
112
|
+
|
|
113
113
|
// add suggestions to results
|
|
114
114
|
results.push({
|
|
115
115
|
to_pace: suggestion.placePrediction.toPlace(),
|
|
116
|
-
text: suggestion.placePrediction.text.toString()
|
|
116
|
+
text: suggestion.placePrediction.text.toString(),
|
|
117
|
+
distance: formatMeters(suggestion.placePrediction.distanceMeters)
|
|
117
118
|
});
|
|
118
119
|
}
|
|
119
120
|
} catch (e: any) {
|
|
@@ -162,7 +163,7 @@
|
|
|
162
163
|
* Initialize the Google Maps JavaScript API Loader.
|
|
163
164
|
*/
|
|
164
165
|
onMount(async (): Promise<void> => {
|
|
165
|
-
if(autofocus) {
|
|
166
|
+
if (options.autofocus) {
|
|
166
167
|
// focus on the input
|
|
167
168
|
inputRef.focus();
|
|
168
169
|
}
|
|
@@ -193,11 +194,11 @@
|
|
|
193
194
|
if (e.key === 'ArrowDown') {
|
|
194
195
|
currentSuggestion = Math.min(currentSuggestion + 1, results.length - 1);
|
|
195
196
|
resetKbdClasses();
|
|
196
|
-
|
|
197
|
+
cl.kbd_down += ' bg-indigo-500 text-white';
|
|
197
198
|
} else if (e.key === 'ArrowUp') {
|
|
198
199
|
currentSuggestion = Math.max(currentSuggestion - 1, 0);
|
|
199
200
|
resetKbdClasses();
|
|
200
|
-
|
|
201
|
+
cl.kbd_up += ' bg-indigo-500 text-white';
|
|
201
202
|
} else if (e.key === 'Enter') {
|
|
202
203
|
e.preventDefault();
|
|
203
204
|
if (currentSuggestion >= 0) {
|
|
@@ -209,28 +210,29 @@
|
|
|
209
210
|
}
|
|
210
211
|
|
|
211
212
|
setTimeout(() => {
|
|
212
|
-
|
|
213
|
-
|
|
213
|
+
resetKbdClasses();
|
|
214
|
+
}, 300);
|
|
214
215
|
}
|
|
215
216
|
</script>
|
|
216
217
|
|
|
217
218
|
<svelte:window onkeydown={onKeyDown} />
|
|
218
219
|
|
|
219
|
-
<section class=
|
|
220
|
-
<div class=
|
|
221
|
-
{#if classes.icon}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
220
|
+
<section class={options.classes?.section}>
|
|
221
|
+
<div class={options.classes.container}>
|
|
222
|
+
{#if options.classes.icon}
|
|
223
|
+
<div class={options.classes.icon_container}>
|
|
224
|
+
{@html options.classes.icon}
|
|
225
|
+
</div>
|
|
226
|
+
{/if}
|
|
227
|
+
|
|
226
228
|
|
|
227
229
|
<input
|
|
228
230
|
type="text"
|
|
229
231
|
name="search"
|
|
230
232
|
bind:this={inputRef}
|
|
231
|
-
class=
|
|
232
|
-
{placeholder}
|
|
233
|
-
autocomplete={
|
|
233
|
+
class={options.classes.input}
|
|
234
|
+
placeholder={options.placeholder}
|
|
235
|
+
autocomplete={options.autocomplete}
|
|
234
236
|
aria-controls="options"
|
|
235
237
|
aria-autocomplete="list"
|
|
236
238
|
aria-owns="options"
|
|
@@ -242,37 +244,43 @@
|
|
|
242
244
|
/>
|
|
243
245
|
|
|
244
246
|
{#if results.length > 0}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
class=
|
|
248
|
-
>
|
|
249
|
-
>
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
>⇑</kbd
|
|
253
|
-
>
|
|
254
|
-
<kbd
|
|
255
|
-
class="{cl.kbd_down}"
|
|
256
|
-
>⇓</kbd
|
|
257
|
-
>
|
|
258
|
-
</div>
|
|
259
|
-
<ul
|
|
260
|
-
class="{classes.ul}"
|
|
261
|
-
id="options"
|
|
262
|
-
>
|
|
247
|
+
<div class={options.classes.kbd_container}>
|
|
248
|
+
<kbd class={options.classes.kbd_escape}>Esc</kbd>
|
|
249
|
+
<kbd class={cl.kbd_up}>⇑</kbd>
|
|
250
|
+
<kbd class={cl.kbd_down}>⇓</kbd>
|
|
251
|
+
</div>
|
|
252
|
+
|
|
253
|
+
<ul class={options.classes.ul} id="options">
|
|
263
254
|
{#each results as place, i}
|
|
264
255
|
<li
|
|
265
|
-
class={[
|
|
256
|
+
class={[options.classes.li, i === currentSuggestion && options.classes.li_current]}
|
|
266
257
|
id="option-{i + 1}"
|
|
267
258
|
>
|
|
268
259
|
<!-- svelte-ignore a11y_invalid_attribute -->
|
|
269
260
|
<a
|
|
270
261
|
href="javascript:void(0)"
|
|
271
|
-
class=
|
|
262
|
+
class={[options.classes?.li_a, 'flex justify-between']}
|
|
272
263
|
tabindex={i + 1}
|
|
273
264
|
onclick={() => onPlaceSelected(place.to_pace)}
|
|
274
265
|
>
|
|
275
|
-
|
|
266
|
+
<div class="flex min-w-0 gap-x-4">
|
|
267
|
+
<!-- <img
|
|
268
|
+
class="size-12 flex-none rounded-full bg-gray-50"
|
|
269
|
+
src="https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
|
|
270
|
+
alt=""
|
|
271
|
+
/> -->
|
|
272
|
+
<div class="min-w-0 flex-auto">
|
|
273
|
+
<p class={[i === currentSuggestion && options.classes.li_current,'text-sm/6 font-semibold text-gray-900']}>{place.text}</p>
|
|
274
|
+
<!-- <p class="mt-1 truncate text-xs/5 text-gray-500">leslie.alexander@example.com</p> -->
|
|
275
|
+
</div>
|
|
276
|
+
</div>
|
|
277
|
+
{#if options.show_distance && place.distance}
|
|
278
|
+
<div class="shrink-0 flex flex-col items-end min-w-16">
|
|
279
|
+
<p class={[i === currentSuggestion && options.classes.li_current,'mt-1 text-xs/5 text-gray-500']}>
|
|
280
|
+
{place.distance}
|
|
281
|
+
</p>
|
|
282
|
+
</div>
|
|
283
|
+
{/if}
|
|
276
284
|
</a>
|
|
277
285
|
</li>
|
|
278
286
|
{/each}
|
package/dist/helpers.d.ts
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
|
-
import type { RequestParams } from './interfaces.js';
|
|
1
|
+
import type { RequestParams, ComponentOptions, ComponentClasses } from './interfaces.js';
|
|
2
2
|
export declare const requestParamsDefault: RequestParams;
|
|
3
3
|
/**
|
|
4
4
|
* Validate and cast request parameters
|
|
5
5
|
* @param requestParams
|
|
6
6
|
*/
|
|
7
7
|
export declare const validateRequestParams: (requestParams: RequestParams | undefined) => RequestParams;
|
|
8
|
+
/**
|
|
9
|
+
* Default component classes
|
|
10
|
+
*/
|
|
11
|
+
export declare const componentClasses: ComponentClasses;
|
|
12
|
+
export declare const componentOptions: ComponentOptions;
|
|
13
|
+
/**
|
|
14
|
+
* Validate and cast component options
|
|
15
|
+
* @param options
|
|
16
|
+
*/
|
|
17
|
+
export declare const validateOptions: (options: ComponentOptions | undefined) => ComponentOptions;
|
package/dist/helpers.js
CHANGED
|
@@ -186,3 +186,58 @@ export const validateRequestParams = (requestParams) => {
|
|
|
186
186
|
//console.log('requestParams:', Object.keys(requestParams));
|
|
187
187
|
return requestParams;
|
|
188
188
|
};
|
|
189
|
+
/**
|
|
190
|
+
* Default component classes
|
|
191
|
+
*/
|
|
192
|
+
export const componentClasses = {
|
|
193
|
+
section: '',
|
|
194
|
+
container: 'relative z-10 transform rounded-xl mt-4',
|
|
195
|
+
icon_container: 'pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3',
|
|
196
|
+
icon: '<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8" /><path d="m21 21-4.3-4.3" /></svg>',
|
|
197
|
+
input: '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',
|
|
198
|
+
kbd_container: 'absolute inset-y-0 right-0 flex py-1.5 pr-1.5',
|
|
199
|
+
kbd_escape: 'inline-flex items-center rounded border border-gray-300 px-1 font-sans text-xs text-gray-500 w-8 mr-1',
|
|
200
|
+
kbd_up: 'inline-flex items-center justify-center rounded border border-gray-300 px-1 font-sans text-xs text-gray-500 w-6',
|
|
201
|
+
kbd_down: 'inline-flex items-center rounded border border-gray-400 px-1 font-sans text-xs text-gray-500 justify-center w-6',
|
|
202
|
+
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',
|
|
203
|
+
li: 'z-50 cursor-default select-none py-2 px-2 lg:px-4 text-gray-900 hover:bg-indigo-500 hover:text-white',
|
|
204
|
+
li_current: 'bg-indigo-500 text-white',
|
|
205
|
+
li_a: 'block w-full',
|
|
206
|
+
};
|
|
207
|
+
export const componentOptions = {
|
|
208
|
+
autofocus: false,
|
|
209
|
+
autocomplete: 'off',
|
|
210
|
+
classes: componentClasses,
|
|
211
|
+
placeholder: '',
|
|
212
|
+
show_distance: false
|
|
213
|
+
};
|
|
214
|
+
/**
|
|
215
|
+
* Validate and cast component options
|
|
216
|
+
* @param options
|
|
217
|
+
*/
|
|
218
|
+
export const validateOptions = (options) => {
|
|
219
|
+
// If options is not an object, set it to an empty object
|
|
220
|
+
if (typeof options !== 'object' || Object.keys(options).length === 0) {
|
|
221
|
+
options = {
|
|
222
|
+
autofocus: false,
|
|
223
|
+
autocomplete: 'off',
|
|
224
|
+
classes: componentClasses,
|
|
225
|
+
placeholder: 'Start typing...',
|
|
226
|
+
show_distance: false
|
|
227
|
+
};
|
|
228
|
+
return options;
|
|
229
|
+
}
|
|
230
|
+
// Find the missing options properties
|
|
231
|
+
for (const key in componentOptions) {
|
|
232
|
+
if (!(key in options)) {
|
|
233
|
+
options[key] = componentOptions[key];
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
// Find the missing classes properties
|
|
237
|
+
for (const key in componentClasses) {
|
|
238
|
+
if (!(key in options.classes)) {
|
|
239
|
+
options.classes[key] = componentClasses[key];
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return options;
|
|
243
|
+
};
|
package/dist/interfaces.d.ts
CHANGED
|
@@ -23,22 +23,18 @@ export interface RequestParams {
|
|
|
23
23
|
sessionToken?: string;
|
|
24
24
|
}
|
|
25
25
|
export interface ComponentClasses {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
kbd_down?: string;
|
|
35
|
-
ul?: string;
|
|
36
|
-
li?: string;
|
|
37
|
-
li_current?: string;
|
|
38
|
-
li_a?: string;
|
|
26
|
+
[key: string]: string;
|
|
27
|
+
}
|
|
28
|
+
export interface ComponentOptions {
|
|
29
|
+
autofocus: boolean;
|
|
30
|
+
autocomplete: AutoFill;
|
|
31
|
+
classes: ComponentClasses;
|
|
32
|
+
placeholder: string;
|
|
33
|
+
show_distance: boolean;
|
|
39
34
|
}
|
|
40
35
|
export interface Props {
|
|
41
36
|
PUBLIC_GOOGLE_MAPS_API_KEY: string;
|
|
37
|
+
options?: ComponentOptions;
|
|
42
38
|
fetchFields?: string[];
|
|
43
39
|
placeholder?: string;
|
|
44
40
|
autofocus?: boolean;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "places-autocomplete-svelte",
|
|
3
3
|
"license": "MIT",
|
|
4
|
-
"version": "2.1.
|
|
4
|
+
"version": "2.1.8",
|
|
5
5
|
"description": "A lightweight and customizable Svelte component for easy integration of Google Maps Places (New) Autocomplete in your Svelte/SvelteKit applications. Provides accessible autocomplete suggestions and detailed address retrieval.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"svelte",
|
|
@@ -72,9 +72,9 @@
|
|
|
72
72
|
"@sveltejs/kit": "^2.16.1",
|
|
73
73
|
"@sveltejs/package": "^2.3.9",
|
|
74
74
|
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
|
75
|
-
"@tailwindcss/postcss": "^4.0.
|
|
75
|
+
"@tailwindcss/postcss": "^4.0.3",
|
|
76
76
|
"@tailwindcss/typography": "^0.5.16",
|
|
77
|
-
"@tailwindcss/vite": "^4.0.
|
|
77
|
+
"@tailwindcss/vite": "^4.0.3",
|
|
78
78
|
"@types/eslint": "^9.6.1",
|
|
79
79
|
"autoprefixer": "^10.4.20",
|
|
80
80
|
"eslint": "^9.19.0",
|
|
@@ -85,9 +85,9 @@
|
|
|
85
85
|
"prettier": "^3.4.2",
|
|
86
86
|
"prettier-plugin-svelte": "^3.3.3",
|
|
87
87
|
"publint": "^0.3.2",
|
|
88
|
-
"svelte": "^5.19.
|
|
88
|
+
"svelte": "^5.19.6",
|
|
89
89
|
"svelte-check": "^4.1.4",
|
|
90
|
-
"tailwindcss": "^4.0.
|
|
90
|
+
"tailwindcss": "^4.0.3",
|
|
91
91
|
"tslib": "^2.8.1",
|
|
92
92
|
"typescript": "^5.7.3",
|
|
93
93
|
"typescript-eslint": "^8.22.0",
|