places-autocomplete-svelte 2.2.20 → 2.2.22
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 +208 -85
- package/dist/PlaceAutocomplete.svelte +820 -117
- package/dist/PlaceAutocomplete.svelte.d.ts +5 -0
- package/dist/gmaps.d.ts +62 -14
- package/dist/gmaps.js +64 -25
- package/dist/helpers.js +26 -23
- package/dist/interfaces.d.ts +107 -1
- package/package.json +17 -17
|
@@ -1,7 +1,44 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview PlaceAutocomplete Component - Google Places Autocomplete for Svelte 5
|
|
4
|
+
* @author Alexander Pechkarev <alexpechkarev@gmail.com>
|
|
5
|
+
* @see https://github.com/alexpechkarev/places-autocomplete-svelte
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
* @license MIT
|
|
8
|
+
*
|
|
9
|
+
* A production-ready, accessible autocomplete component for Google Places API (New).
|
|
10
|
+
* Built with Svelte 5 runes for optimal reactivity and performance.
|
|
11
|
+
*
|
|
12
|
+
* @features
|
|
13
|
+
* - Full keyboard navigation (ArrowUp, ArrowDown, Enter, Escape)
|
|
14
|
+
* - Session token management for billing optimization
|
|
15
|
+
* - Debounced API requests to minimize costs
|
|
16
|
+
* - Customizable styling via CSS classes
|
|
17
|
+
* - Distance calculations from origin point
|
|
18
|
+
* - Text highlighting in suggestions
|
|
19
|
+
* - ARIA-compliant accessibility
|
|
20
|
+
* - Imperative API for programmatic control
|
|
21
|
+
*
|
|
22
|
+
*
|
|
23
|
+
* @publicMethods
|
|
24
|
+
* - `clear()` - Clears input and resets session
|
|
25
|
+
* - `focus()` - Focuses the input field
|
|
26
|
+
* - `getRequestParams()` - Returns current request parameters
|
|
27
|
+
* - `setRequestParams(params)` - Updates request parameters dynamically
|
|
28
|
+
* - `setFetchFields(fields)` - Updates Place Data Fields to fetch
|
|
29
|
+
* - `getFetchFields()` - Returns current fetch fields
|
|
30
|
+
*
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import { onMount, untrack } from 'svelte';
|
|
3
34
|
import type { PlaceResult, Props } from './interfaces.js';
|
|
4
|
-
import {
|
|
35
|
+
import {
|
|
36
|
+
getGMapsContext,
|
|
37
|
+
hasGMapsContext,
|
|
38
|
+
importLibrary,
|
|
39
|
+
initialiseGMapsNoContext,
|
|
40
|
+
type GMapsContext
|
|
41
|
+
} from './gmaps.js';
|
|
5
42
|
import {
|
|
6
43
|
validateOptions,
|
|
7
44
|
validateRequestParams,
|
|
@@ -11,23 +48,21 @@
|
|
|
11
48
|
debounce
|
|
12
49
|
} from './helpers.js';
|
|
13
50
|
|
|
14
|
-
|
|
15
51
|
let gmaps: GMapsContext | undefined;
|
|
16
52
|
// Get the context synchronously. This is safe.
|
|
17
53
|
if (hasGMapsContext()) {
|
|
18
54
|
gmaps = getGMapsContext();
|
|
19
55
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
56
|
|
|
23
57
|
let {
|
|
24
58
|
/**
|
|
25
|
-
*
|
|
59
|
+
* Google Maps API key required for Places API usage.
|
|
60
|
+
* By default, uses SKU: Place Details (Location Only) - 0.005 USD per request.
|
|
26
61
|
* @see https://developers.google.com/maps/documentation/javascript/usage-and-billing#location-placedetails
|
|
27
62
|
*/
|
|
28
|
-
PUBLIC_GOOGLE_MAPS_API_KEY='',
|
|
29
|
-
fetchFields,
|
|
30
|
-
options,
|
|
63
|
+
PUBLIC_GOOGLE_MAPS_API_KEY = '',
|
|
64
|
+
fetchFields = ['addressComponents', 'formattedAddress'],
|
|
65
|
+
options = {},
|
|
31
66
|
onResponse = $bindable((response: PlaceResult) => {}),
|
|
32
67
|
onError = $bindable((error: string) => {}),
|
|
33
68
|
requestParams = {}
|
|
@@ -35,28 +70,40 @@
|
|
|
35
70
|
|
|
36
71
|
const isDefaultOnResponse = onResponse.toString() === ((response: PlaceResult) => {}).toString();
|
|
37
72
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
//console.log(fetchFields);
|
|
73
|
+
/**
|
|
74
|
+
* Create validated derived values that react to prop changes
|
|
75
|
+
*/
|
|
76
|
+
let validatedOptions = $derived(validateOptions(options));
|
|
77
|
+
let validatedFetchFields = $derived(validateFetchFields(fetchFields));
|
|
78
|
+
let validatedRequestParams = $derived(validateRequestParams(requestParams));
|
|
45
79
|
|
|
80
|
+
/**
|
|
81
|
+
* Local variables
|
|
82
|
+
*/
|
|
46
83
|
let kbdAction = $state(''); // 'up', 'down', or 'escape'
|
|
47
|
-
|
|
48
|
-
// Local variables
|
|
49
84
|
let inputRef: HTMLInputElement;
|
|
50
85
|
let currentSuggestion = $state(-1);
|
|
51
86
|
let results: any[] = $state([]);
|
|
52
87
|
let placesApi: { [key: string]: any } = {};
|
|
53
88
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
let request = $state(
|
|
89
|
+
/**
|
|
90
|
+
* Initialise request state - will be synced with validated params in effect
|
|
91
|
+
*/
|
|
92
|
+
let request = $state<any>({ input: '' });
|
|
58
93
|
//$inspect(request);
|
|
59
|
-
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Synchronizes the request object with validated request parameters while preserving the current input value.
|
|
97
|
+
* Uses untrack() to prevent reading request.input from creating a reactive dependency that would trigger the effect.
|
|
98
|
+
*/
|
|
99
|
+
$effect(() => {
|
|
100
|
+
const currentInput = untrack(() => request.input);
|
|
101
|
+
request = { ...validatedRequestParams, input: currentInput };
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Clears the suggestions list when the input field is empty.
|
|
106
|
+
*/
|
|
60
107
|
$effect(() => {
|
|
61
108
|
if (request.input == '') {
|
|
62
109
|
results = [];
|
|
@@ -64,11 +111,14 @@
|
|
|
64
111
|
});
|
|
65
112
|
|
|
66
113
|
/**
|
|
67
|
-
*
|
|
114
|
+
* Resets the search input and clears the suggestions list.
|
|
115
|
+
* Optionally populates the input with the formatted address of the selected place.
|
|
116
|
+
* @param {PlaceResult} [placeData] - Optional place data to populate the input field with.
|
|
117
|
+
* @private
|
|
68
118
|
*/
|
|
69
119
|
const reset = (placeData?: PlaceResult) => {
|
|
70
120
|
currentSuggestion = -1;
|
|
71
|
-
if (
|
|
121
|
+
if (validatedOptions?.clear_input == false) {
|
|
72
122
|
if (placeData && placeData.formattedAddress) {
|
|
73
123
|
// set input to formatted address
|
|
74
124
|
request.input = placeData.formattedAddress;
|
|
@@ -83,18 +133,23 @@
|
|
|
83
133
|
|
|
84
134
|
/**
|
|
85
135
|
* Clears the autocomplete input field and suggestions list.
|
|
86
|
-
* Refreshes the Google Places session token
|
|
87
|
-
*
|
|
136
|
+
* Refreshes the Google Places session token to start a new autocomplete session.
|
|
137
|
+
* This method can be called imperatively on the component instance.
|
|
138
|
+
* @public
|
|
88
139
|
* @example
|
|
89
140
|
* let autocompleteComponent;
|
|
90
141
|
* autocompleteComponent.clear();
|
|
91
142
|
*/
|
|
92
143
|
export function clear() {
|
|
93
|
-
|
|
144
|
+
currentSuggestion = -1;
|
|
145
|
+
request.input = '';
|
|
146
|
+
results = [];
|
|
147
|
+
setSessionToken();
|
|
94
148
|
}
|
|
95
149
|
|
|
96
150
|
/**
|
|
97
|
-
* Programmatically
|
|
151
|
+
* Programmatically sets focus to the autocomplete input element.
|
|
152
|
+
* @public
|
|
98
153
|
* @example
|
|
99
154
|
* autocompleteComponent.focus();
|
|
100
155
|
*/
|
|
@@ -103,20 +158,113 @@
|
|
|
103
158
|
}
|
|
104
159
|
|
|
105
160
|
/**
|
|
106
|
-
* Returns the current internal request parameters.
|
|
161
|
+
* Returns the current internal request parameters being used for API calls.
|
|
107
162
|
* Useful for debugging or inspecting the component's state.
|
|
108
|
-
* @
|
|
163
|
+
* @public
|
|
164
|
+
* @returns {RequestParams} The current request parameters object.
|
|
109
165
|
*/
|
|
110
166
|
export function getRequestParams() {
|
|
111
|
-
return
|
|
167
|
+
return validatedRequestParams;
|
|
112
168
|
}
|
|
113
169
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
170
|
+
/**
|
|
171
|
+
* Dynamically updates the request parameters used for Places API autocomplete calls.
|
|
172
|
+
* Useful for changing search criteria dynamically (e.g., region, language, or location bias).
|
|
173
|
+
* The provided parameters are merged with existing ones without replacing the entire object.
|
|
174
|
+
* @public
|
|
175
|
+
* @param {Partial<RequestParams>} params - Partial request parameters to merge with current settings.
|
|
176
|
+
* @example
|
|
177
|
+
* // Change region and language
|
|
178
|
+
* autocompleteComponent.setRequestParams({
|
|
179
|
+
* region: 'FR',
|
|
180
|
+
* language: 'fr',
|
|
181
|
+
* includedRegionCodes: ['FR']
|
|
182
|
+
* });
|
|
183
|
+
*
|
|
184
|
+
* // Set origin for distance calculations
|
|
185
|
+
* autocompleteComponent.setRequestParams({
|
|
186
|
+
* origin: { lat: 48.8566, lng: 2.3522 }
|
|
187
|
+
* });
|
|
188
|
+
*/
|
|
189
|
+
export function setRequestParams(params: Partial<typeof requestParams>) {
|
|
190
|
+
validatedRequestParams = validateRequestParams({ ...requestParams, ...params });
|
|
191
|
+
}
|
|
117
192
|
|
|
118
|
-
|
|
119
|
-
|
|
193
|
+
/**
|
|
194
|
+
* Dynamically updates the Place Data Fields to fetch when a place is selected.
|
|
195
|
+
* Replaces the current fetch fields with the provided array.
|
|
196
|
+
* @public
|
|
197
|
+
* @param {string[]} fields - Array of Place Data Field names to fetch (e.g., 'displayName', 'types', 'location').
|
|
198
|
+
* @see https://developers.google.com/maps/documentation/javascript/place-data-fields
|
|
199
|
+
* @example
|
|
200
|
+
* autocompleteComponent.setFetchFields(['displayName', 'types', 'location']);
|
|
201
|
+
*/
|
|
202
|
+
export function setFetchFields(fields: string[]) {
|
|
203
|
+
validatedFetchFields = validateFetchFields(fields);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Returns the current array of Place Data Fields that will be requested when a place is selected.
|
|
208
|
+
* @public
|
|
209
|
+
* @returns {string[]} Array of current Place Data Field names.
|
|
210
|
+
* @example
|
|
211
|
+
* const fields = autocompleteComponent.getFetchFields();
|
|
212
|
+
* console.log('Current fields:', fields);
|
|
213
|
+
*/
|
|
214
|
+
export function getFetchFields(): string[] {
|
|
215
|
+
return validatedFetchFields;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Dynamically updates the component's configuration options.
|
|
220
|
+
* Merges the provided options with existing settings.
|
|
221
|
+
* @public
|
|
222
|
+
* @param options - Partial options object to update component behavior and appearance.
|
|
223
|
+
* @example
|
|
224
|
+
* // Update options to change placeholder and enable distance display
|
|
225
|
+
* autocompleteComponent.setOptions({
|
|
226
|
+
* placeholder: 'Enter a location',
|
|
227
|
+
* showDistance: true
|
|
228
|
+
* });
|
|
229
|
+
*/
|
|
230
|
+
export function setOptions(options: typeof validatedOptions){
|
|
231
|
+
validatedOptions = validateOptions(options);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Returns the current validated options used by the component.
|
|
237
|
+
* Useful for inspecting configuration settings.
|
|
238
|
+
* @public
|
|
239
|
+
* @returns {typeof validatedOptions} The current validated options object.
|
|
240
|
+
* @example
|
|
241
|
+
* const options = autocompleteComponent.getOptions();
|
|
242
|
+
* console.log('Current options:', options);
|
|
243
|
+
*/
|
|
244
|
+
export function getOptions(): typeof validatedOptions {
|
|
245
|
+
return validatedOptions;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Extracts a specific address component from the place response.
|
|
251
|
+
* @private
|
|
252
|
+
* @param {Object} response - The place response object containing address components.
|
|
253
|
+
* @param {string} type - The address component type to find (e.g., 'locality', 'country').
|
|
254
|
+
* @returns {string} The long text of the address component, or an empty string if not found.
|
|
255
|
+
*/
|
|
256
|
+
const getAddressComponent = (response: { addressComponents: any[] }, type: string) =>
|
|
257
|
+
response.addressComponents?.find((c: { types: string | string[] }) => c.types.includes(type))
|
|
258
|
+
?.longText || '';
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Constructs the secondary text for autocomplete suggestions from address components.
|
|
262
|
+
* Combines locality, administrative area, country, and postal code into a formatted string.
|
|
263
|
+
* @private
|
|
264
|
+
* @param {Object} place - The place object containing address components.
|
|
265
|
+
* @returns {string} Formatted secondary text (e.g., "Paris, Île-de-France, France, 75001").
|
|
266
|
+
*/
|
|
267
|
+
const getSecondaryText = (place: { addressComponents: any[] }) => {
|
|
120
268
|
const locality = getAddressComponent(place, 'locality');
|
|
121
269
|
const adminArea = getAddressComponent(place, 'administrative_area_level_1');
|
|
122
270
|
const postalCode = getAddressComponent(place, 'postal_code');
|
|
@@ -127,10 +275,12 @@
|
|
|
127
275
|
};
|
|
128
276
|
|
|
129
277
|
/**
|
|
130
|
-
*
|
|
131
|
-
* @
|
|
278
|
+
* Fetches autocomplete suggestions from the Google Places API based on user input.
|
|
279
|
+
* @private
|
|
280
|
+
* @param {string} inputValue - The user's input text to search for.
|
|
281
|
+
* @returns {Promise<void>}
|
|
132
282
|
*/
|
|
133
|
-
const
|
|
283
|
+
const makeAcRequest = async (inputValue: string) => {
|
|
134
284
|
if (inputValue === '') {
|
|
135
285
|
request.input = '';
|
|
136
286
|
results = [];
|
|
@@ -157,21 +307,19 @@
|
|
|
157
307
|
// Clear previous results
|
|
158
308
|
results = [];
|
|
159
309
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
// ieterate over suggestions and add results to an array
|
|
310
|
+
// Iterate over suggestions and add results to an array
|
|
163
311
|
for (const suggestion of suggestions) {
|
|
164
312
|
// get prediction text
|
|
165
313
|
//console.log(suggestion.placePrediction.toPlace());
|
|
166
314
|
let place = suggestion.placePrediction.toPlace();
|
|
167
|
-
await place.fetchFields({fields: [
|
|
315
|
+
await place.fetchFields({ fields: ['addressComponents'] });
|
|
168
316
|
|
|
169
317
|
const predictionText = suggestion.placePrediction.mainText;
|
|
170
318
|
const originalText = predictionText.text;
|
|
171
|
-
//
|
|
319
|
+
// Extract match positions (array of objects with startOffset, endOffset)
|
|
172
320
|
const matches = predictionText.matches;
|
|
173
321
|
|
|
174
|
-
//
|
|
322
|
+
// Apply highlighting logic to matched text segments
|
|
175
323
|
let highlightedText: { text: string; highlighted: boolean }[] = [];
|
|
176
324
|
|
|
177
325
|
// Sort matches just in case they aren't ordered (though they usually are)
|
|
@@ -188,7 +336,7 @@
|
|
|
188
336
|
secondaryText: getSecondaryText(place),
|
|
189
337
|
distance: formatDistance(
|
|
190
338
|
suggestion.placePrediction.distanceMeters,
|
|
191
|
-
|
|
339
|
+
validatedOptions.distance_units ?? 'km'
|
|
192
340
|
)
|
|
193
341
|
});
|
|
194
342
|
}
|
|
@@ -196,22 +344,32 @@
|
|
|
196
344
|
} catch (e: any) {
|
|
197
345
|
onError((e.name || 'An error occurred') + ' - ' + (e.message || 'see console for details.'));
|
|
198
346
|
}
|
|
199
|
-
}
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Debounced version of makeAcRequest that delays API calls to reduce request frequency.
|
|
351
|
+
* The debounce delay is reactive and updates when the validatedOptions.debounce value changes.
|
|
352
|
+
* @private
|
|
353
|
+
*/
|
|
354
|
+
const debouncedMakeAcRequest = $derived(debounce(makeAcRequest, validatedOptions?.debounce ?? 100));
|
|
200
355
|
|
|
201
356
|
/**
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
357
|
+
* Handles the selection of an autocomplete suggestion.
|
|
358
|
+
* Fetches detailed place data and invokes the onResponse callback.
|
|
359
|
+
* @private
|
|
360
|
+
* @param {Object} place - The selected place object from the autocomplete suggestion.
|
|
361
|
+
* @returns {Promise<void>}
|
|
362
|
+
* @see https://developers.google.com/maps/documentation/javascript/reference/autocomplete-data#AutocompleteSuggestion
|
|
363
|
+
*/
|
|
206
364
|
const onPlaceSelected = async (place: {
|
|
207
365
|
fetchFields: (arg0: { fields: string[] }) => any;
|
|
208
366
|
toJSON: () => any;
|
|
209
367
|
}): Promise<void> => {
|
|
210
368
|
try {
|
|
211
369
|
// console.log(place);
|
|
212
|
-
// console.log(
|
|
370
|
+
// console.log(validatedFetchFields);
|
|
213
371
|
await place.fetchFields({
|
|
214
|
-
fields:
|
|
372
|
+
fields: validatedFetchFields
|
|
215
373
|
});
|
|
216
374
|
let placeData = place.toJSON();
|
|
217
375
|
// reset search input and results
|
|
@@ -227,7 +385,10 @@
|
|
|
227
385
|
};
|
|
228
386
|
|
|
229
387
|
/**
|
|
230
|
-
*
|
|
388
|
+
* Initializes a new Google Places autocomplete session token.
|
|
389
|
+
* Session tokens group autocomplete and place details requests for billing optimization.
|
|
390
|
+
* @private
|
|
391
|
+
* @see https://developers.google.com/maps/documentation/javascript/place-autocomplete#session_tokens
|
|
231
392
|
*/
|
|
232
393
|
const setSessionToken = () => {
|
|
233
394
|
try {
|
|
@@ -238,31 +399,30 @@
|
|
|
238
399
|
};
|
|
239
400
|
|
|
240
401
|
/**
|
|
241
|
-
*
|
|
402
|
+
* Initializes the Google Maps JavaScript API and Places library.
|
|
403
|
+
* Loads required APIs, validates configuration, and sets up the autocomplete session.
|
|
404
|
+
* @private
|
|
242
405
|
*/
|
|
243
406
|
onMount(async (): Promise<void> => {
|
|
244
|
-
|
|
245
|
-
|
|
246
407
|
if (isDefaultOnResponse) {
|
|
247
408
|
console.warn(
|
|
248
409
|
'PlaceAutocomplete: The `onResponse` callback has not been provided. Selected place data will not be handled. See documentation for usage.'
|
|
249
410
|
);
|
|
250
411
|
}
|
|
251
|
-
if (
|
|
412
|
+
if (validatedOptions.autofocus) {
|
|
252
413
|
// focus on the input
|
|
253
414
|
inputRef.focus();
|
|
254
415
|
}
|
|
255
416
|
|
|
256
417
|
try {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
if(typeof gmaps !== 'undefined' && gmaps) {
|
|
261
|
-
await gmaps?.
|
|
262
|
-
}else{
|
|
263
|
-
|
|
418
|
+
// Await the promise that was stored in the context by the parent.
|
|
419
|
+
// If the parent has already finished, this resolves immediately.
|
|
420
|
+
// If the parent is still loading, this will wait.
|
|
421
|
+
if (typeof gmaps !== 'undefined' && gmaps) {
|
|
422
|
+
await gmaps?.initialisationPromise;
|
|
423
|
+
} else {
|
|
264
424
|
// Check if the API key is provided
|
|
265
|
-
if(PUBLIC_GOOGLE_MAPS_API_KEY === '' || !PUBLIC_GOOGLE_MAPS_API_KEY) {
|
|
425
|
+
if (PUBLIC_GOOGLE_MAPS_API_KEY === '' || !PUBLIC_GOOGLE_MAPS_API_KEY) {
|
|
266
426
|
throw new Error('Google Maps API key is required. Please provide a valid API key.');
|
|
267
427
|
}
|
|
268
428
|
|
|
@@ -270,7 +430,7 @@
|
|
|
270
430
|
// This will load the Google Maps script
|
|
271
431
|
// and set up the necessary objects
|
|
272
432
|
// for places API usage.
|
|
273
|
-
await initialiseGMapsNoContext({key: PUBLIC_GOOGLE_MAPS_API_KEY,
|
|
433
|
+
await initialiseGMapsNoContext({ key: PUBLIC_GOOGLE_MAPS_API_KEY, v: 'weekly' });
|
|
274
434
|
}
|
|
275
435
|
|
|
276
436
|
const { AutocompleteSessionToken, AutocompleteSuggestion } = await importLibrary('places');
|
|
@@ -287,7 +447,10 @@
|
|
|
287
447
|
}
|
|
288
448
|
});
|
|
289
449
|
/**
|
|
290
|
-
* Handles keyboard
|
|
450
|
+
* Handles keyboard navigation within the autocomplete suggestions list.
|
|
451
|
+
* Supports ArrowUp, ArrowDown, Enter, and Escape keys for navigation and selection.
|
|
452
|
+
* @private
|
|
453
|
+
* @param {KeyboardEvent} e - The keyboard event object.
|
|
291
454
|
*/
|
|
292
455
|
function onKeyDown(e: KeyboardEvent) {
|
|
293
456
|
if (e.key === 'ArrowDown') {
|
|
@@ -312,11 +475,15 @@
|
|
|
312
475
|
// Reset the action state after a short delay to allow CSS transition to finish
|
|
313
476
|
setTimeout(() => {
|
|
314
477
|
kbdAction = '';
|
|
315
|
-
},
|
|
478
|
+
}, 300);
|
|
316
479
|
}
|
|
317
480
|
|
|
318
|
-
|
|
319
|
-
|
|
481
|
+
/**
|
|
482
|
+
* Handles click events outside the input element to close the suggestions list.
|
|
483
|
+
* Resets the search input and clears results when clicking outside the component.
|
|
484
|
+
* @private
|
|
485
|
+
* @param {MouseEvent} event - The mouse event object.
|
|
486
|
+
*/
|
|
320
487
|
function handleClickOutside(event: MouseEvent) {
|
|
321
488
|
if (inputRef && !inputRef.contains(event.target as Node)) {
|
|
322
489
|
reset();
|
|
@@ -327,7 +494,7 @@
|
|
|
327
494
|
<svelte:window onclick={handleClickOutside} />
|
|
328
495
|
|
|
329
496
|
<section
|
|
330
|
-
class={
|
|
497
|
+
class={validatedOptions.classes?.section}
|
|
331
498
|
role="combobox"
|
|
332
499
|
aria-controls="autocomplete-listbox"
|
|
333
500
|
tabindex="0"
|
|
@@ -335,15 +502,15 @@
|
|
|
335
502
|
aria-expanded={results.length > 0}
|
|
336
503
|
aria-owns="autocomplete-listbox"
|
|
337
504
|
>
|
|
338
|
-
{#if
|
|
339
|
-
<label for="places-autocomplete-input" class={
|
|
340
|
-
{
|
|
505
|
+
{#if validatedOptions?.label ?? ''}
|
|
506
|
+
<label for="places-autocomplete-input" class={validatedOptions.classes?.label ?? ''}>
|
|
507
|
+
{validatedOptions.label}
|
|
341
508
|
</label>
|
|
342
509
|
{/if}
|
|
343
|
-
<div class={
|
|
344
|
-
{#if
|
|
345
|
-
<div class={
|
|
346
|
-
{@html
|
|
510
|
+
<div class={validatedOptions.classes?.container ?? ''}>
|
|
511
|
+
{#if validatedOptions.classes?.icon}
|
|
512
|
+
<div class={validatedOptions.classes.icon_container}>
|
|
513
|
+
{@html validatedOptions.classes.icon}
|
|
347
514
|
</div>
|
|
348
515
|
{/if}
|
|
349
516
|
|
|
@@ -352,9 +519,9 @@
|
|
|
352
519
|
type="text"
|
|
353
520
|
name="search"
|
|
354
521
|
bind:this={inputRef}
|
|
355
|
-
class={
|
|
356
|
-
placeholder={
|
|
357
|
-
autocomplete={
|
|
522
|
+
class={validatedOptions.classes?.input ?? ''}
|
|
523
|
+
placeholder={validatedOptions.placeholder}
|
|
524
|
+
autocomplete={validatedOptions.autocomplete}
|
|
358
525
|
aria-controls="options"
|
|
359
526
|
aria-autocomplete="list"
|
|
360
527
|
aria-owns="options"
|
|
@@ -369,24 +536,33 @@
|
|
|
369
536
|
<!-- oninput={makeAcRequest} -->
|
|
370
537
|
|
|
371
538
|
{#if results.length > 0}
|
|
372
|
-
<div class={
|
|
373
|
-
<kbd
|
|
374
|
-
|
|
539
|
+
<div class={validatedOptions.classes?.kbd_container ?? ''}>
|
|
540
|
+
<kbd
|
|
541
|
+
class="{validatedOptions.classes?.kbd_escape ?? ''} {kbdAction === 'escape'
|
|
542
|
+
? (validatedOptions.classes?.kbd_active ?? '')
|
|
543
|
+
: ''}">Esc</kbd
|
|
375
544
|
>
|
|
376
|
-
<kbd
|
|
545
|
+
<kbd
|
|
546
|
+
class="{validatedOptions.classes?.kbd_up ?? ''} {kbdAction === 'up'
|
|
547
|
+
? (validatedOptions.classes?.kbd_active ?? '')
|
|
548
|
+
: ''}">⇑</kbd
|
|
377
549
|
>
|
|
378
|
-
<kbd
|
|
379
|
-
|
|
550
|
+
<kbd
|
|
551
|
+
class="{validatedOptions.classes?.kbd_down ?? ''} {kbdAction === 'down'
|
|
552
|
+
? (validatedOptions.classes?.kbd_active ?? '')
|
|
553
|
+
: ''}"
|
|
554
|
+
>
|
|
555
|
+
⇓</kbd
|
|
380
556
|
>
|
|
381
557
|
</div>
|
|
382
|
-
<ul class={
|
|
558
|
+
<ul class={validatedOptions.classes?.ul ?? ''} id="autocomplete-listbox" role="listbox">
|
|
383
559
|
{#each results as p, i}
|
|
384
560
|
<li
|
|
385
561
|
role="option"
|
|
386
562
|
aria-selected={i === currentSuggestion}
|
|
387
563
|
class={[
|
|
388
|
-
|
|
389
|
-
i === currentSuggestion &&
|
|
564
|
+
validatedOptions.classes?.li ?? '',
|
|
565
|
+
i === currentSuggestion && validatedOptions.classes?.li_current
|
|
390
566
|
]}
|
|
391
567
|
onmouseenter={() => (currentSuggestion = i)}
|
|
392
568
|
id="option-{i + 1}"
|
|
@@ -394,19 +570,19 @@
|
|
|
394
570
|
<button
|
|
395
571
|
type="button"
|
|
396
572
|
class={[
|
|
397
|
-
|
|
398
|
-
i === currentSuggestion &&
|
|
573
|
+
validatedOptions.classes?.li_button,
|
|
574
|
+
i === currentSuggestion && validatedOptions.classes?.li_button_current
|
|
399
575
|
]}
|
|
400
576
|
onclick={() => onPlaceSelected(p.place)}
|
|
401
577
|
>
|
|
402
|
-
<div class={[
|
|
578
|
+
<div class={[validatedOptions.classes?.li_div_container ?? '']}>
|
|
403
579
|
<div
|
|
404
580
|
class={[
|
|
405
|
-
|
|
406
|
-
i === currentSuggestion &&
|
|
581
|
+
validatedOptions.classes?.li_div_one ?? '',
|
|
582
|
+
i === currentSuggestion && validatedOptions.classes?.li_div_current
|
|
407
583
|
]}
|
|
408
584
|
>
|
|
409
|
-
{#if
|
|
585
|
+
{#if validatedOptions.classes?.map_pin_icon}
|
|
410
586
|
<svg
|
|
411
587
|
xmlns="http://www.w3.org/2000/svg"
|
|
412
588
|
width="24"
|
|
@@ -417,20 +593,20 @@
|
|
|
417
593
|
stroke-width="2"
|
|
418
594
|
stroke-linecap="round"
|
|
419
595
|
stroke-linejoin="round"
|
|
420
|
-
class="size-5">{@html
|
|
596
|
+
class="size-5">{@html validatedOptions.classes.map_pin_icon}</svg
|
|
421
597
|
>
|
|
422
598
|
{/if}
|
|
423
599
|
|
|
424
|
-
<div class={[
|
|
600
|
+
<div class={[validatedOptions.classes?.li_div_p_container ?? '']}>
|
|
425
601
|
<p
|
|
426
602
|
class={[
|
|
427
|
-
i === currentSuggestion &&
|
|
428
|
-
|
|
603
|
+
i === currentSuggestion && validatedOptions.classes?.li_current,
|
|
604
|
+
validatedOptions.classes?.li_div_one_p
|
|
429
605
|
]}
|
|
430
606
|
>
|
|
431
607
|
{#each p.mainText as segment}
|
|
432
608
|
{#if segment.highlighted}
|
|
433
|
-
<span class={
|
|
609
|
+
<span class={validatedOptions.classes?.highlight ?? 'font-bold'}
|
|
434
610
|
>{segment.text}</span
|
|
435
611
|
>
|
|
436
612
|
{:else}
|
|
@@ -440,8 +616,8 @@
|
|
|
440
616
|
</p>
|
|
441
617
|
<p
|
|
442
618
|
class={[
|
|
443
|
-
i === currentSuggestion &&
|
|
444
|
-
|
|
619
|
+
i === currentSuggestion && validatedOptions.classes?.li_current,
|
|
620
|
+
validatedOptions.classes?.li_div_one_p_secondaryText
|
|
445
621
|
]}
|
|
446
622
|
>
|
|
447
623
|
{p.secondaryText}
|
|
@@ -449,12 +625,12 @@
|
|
|
449
625
|
</div>
|
|
450
626
|
</div>
|
|
451
627
|
</div>
|
|
452
|
-
{#if
|
|
453
|
-
<div class={[
|
|
628
|
+
{#if validatedOptions.distance && p.distance}
|
|
629
|
+
<div class={[validatedOptions.classes?.li_div_two]}>
|
|
454
630
|
<p
|
|
455
631
|
class={[
|
|
456
|
-
i === currentSuggestion &&
|
|
457
|
-
|
|
632
|
+
i === currentSuggestion && validatedOptions.classes?.li_current,
|
|
633
|
+
validatedOptions.classes?.li_div_two_p
|
|
458
634
|
]}
|
|
459
635
|
>
|
|
460
636
|
{p.distance}
|
|
@@ -470,13 +646,540 @@
|
|
|
470
646
|
</section>
|
|
471
647
|
|
|
472
648
|
<style>
|
|
473
|
-
/*
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
649
|
+
/* Component styles */
|
|
650
|
+
@layer properties {
|
|
651
|
+
@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or
|
|
652
|
+
((-moz-orient: inline) and (not (color: rgb(from red r g b)))) {
|
|
653
|
+
*,
|
|
654
|
+
:before,
|
|
655
|
+
:after,
|
|
656
|
+
::backdrop {
|
|
657
|
+
--tw-rotate-x: initial;
|
|
658
|
+
--tw-rotate-y: initial;
|
|
659
|
+
--tw-rotate-z: initial;
|
|
660
|
+
--tw-skew-x: initial;
|
|
661
|
+
--tw-skew-y: initial;
|
|
662
|
+
--tw-border-style: solid;
|
|
663
|
+
--tw-shadow: 0 0 #0000;
|
|
664
|
+
--tw-shadow-color: initial;
|
|
665
|
+
--tw-shadow-alpha: 100%;
|
|
666
|
+
--tw-inset-shadow: 0 0 #0000;
|
|
667
|
+
--tw-inset-shadow-color: initial;
|
|
668
|
+
--tw-inset-shadow-alpha: 100%;
|
|
669
|
+
--tw-ring-color: initial;
|
|
670
|
+
--tw-ring-shadow: 0 0 #0000;
|
|
671
|
+
--tw-inset-ring-color: initial;
|
|
672
|
+
--tw-inset-ring-shadow: 0 0 #0000;
|
|
673
|
+
--tw-ring-inset: initial;
|
|
674
|
+
--tw-ring-offset-width: 0px;
|
|
675
|
+
--tw-ring-offset-color: #fff;
|
|
676
|
+
--tw-ring-offset-shadow: 0 0 #0000;
|
|
677
|
+
--tw-divide-y-reverse: 0;
|
|
678
|
+
--tw-font-weight: initial;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
:root,
|
|
683
|
+
:host {
|
|
684
|
+
--font-sans:
|
|
685
|
+
ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
|
|
686
|
+
'Segoe UI Symbol', 'Noto Color Emoji';
|
|
687
|
+
--font-mono:
|
|
688
|
+
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New',
|
|
689
|
+
monospace;
|
|
690
|
+
-webkit-text-size-adjust: 100%;
|
|
691
|
+
-moz-tab-size: 4;
|
|
692
|
+
-o-tab-size: 4;
|
|
693
|
+
tab-size: 4;
|
|
694
|
+
line-height: 1.5;
|
|
695
|
+
font-family: var(
|
|
696
|
+
--default-font-family,
|
|
697
|
+
ui-sans-serif,
|
|
698
|
+
system-ui,
|
|
699
|
+
sans-serif,
|
|
700
|
+
'Apple Color Emoji',
|
|
701
|
+
'Segoe UI Emoji',
|
|
702
|
+
'Segoe UI Symbol',
|
|
703
|
+
'Noto Color Emoji'
|
|
704
|
+
);
|
|
705
|
+
font-feature-settings: var(--default-font-feature-settings, normal);
|
|
706
|
+
font-variation-settings: var(--default-font-variation-settings, normal);
|
|
707
|
+
-webkit-tap-highlight-color: transparent;
|
|
708
|
+
--color-red-50: #fef2f2;
|
|
709
|
+
--color-red-300: #fca5a5;
|
|
710
|
+
--color-red-400: #f87171;
|
|
711
|
+
--color-red-500: #ef4444;
|
|
712
|
+
--color-red-600: #dc2626;
|
|
713
|
+
--color-red-700: #b91c1c;
|
|
714
|
+
--color-red-800: #991b1b;
|
|
715
|
+
--color-green-50: #f0fdf4;
|
|
716
|
+
--color-green-100: #dcfce7;
|
|
717
|
+
--color-green-200: #bbf7d0;
|
|
718
|
+
--color-green-300: #86efac;
|
|
719
|
+
--color-green-400: #4ade80;
|
|
720
|
+
--color-green-800: #166534;
|
|
721
|
+
--color-emerald-300: #6ee7b7;
|
|
722
|
+
--color-emerald-400: #34d399;
|
|
723
|
+
--color-emerald-500: #10b981;
|
|
724
|
+
--color-emerald-600: #059669;
|
|
725
|
+
--color-emerald-700: #047857;
|
|
726
|
+
--color-sky-300: #7dd3fc;
|
|
727
|
+
--color-sky-400: #38bdf8;
|
|
728
|
+
--color-sky-500: #0ea5e9;
|
|
729
|
+
--color-sky-600: #0284c7;
|
|
730
|
+
--color-indigo-400: #818cf8;
|
|
731
|
+
--color-indigo-500: #6366f1;
|
|
732
|
+
--color-indigo-600: #4f46e5;
|
|
733
|
+
--color-violet-300: #c4b5fd;
|
|
734
|
+
--color-pink-300: #f9a8d4;
|
|
735
|
+
--color-slate-50: oklch(98.4% 0.003 247.858);
|
|
736
|
+
--color-slate-200: oklch(92.9% 0.013 255.508);
|
|
737
|
+
--color-slate-300: oklch(86.9% 0.022 252.894);
|
|
738
|
+
--color-slate-400: oklch(70.4% 0.04 256.788);
|
|
739
|
+
--color-slate-500: oklch(55.4% 0.046 257.417);
|
|
740
|
+
--color-slate-600: oklch(44.6% 0.043 257.281);
|
|
741
|
+
--color-slate-700: oklch(37.2% 0.044 257.287);
|
|
742
|
+
--color-slate-800: oklch(27.9% 0.041 260.031);
|
|
743
|
+
--color-slate-900: oklch(20.8% 0.042 265.755);
|
|
744
|
+
--color-gray-50: #f9fafb;
|
|
745
|
+
--color-gray-100: #f4f5f7;
|
|
746
|
+
--color-gray-200: #e5e7eb;
|
|
747
|
+
--color-gray-300: #d2d6dc;
|
|
748
|
+
--color-gray-400: #9fa6b2;
|
|
749
|
+
--color-gray-500: #6b7280;
|
|
750
|
+
--color-gray-600: #4b5563;
|
|
751
|
+
--color-gray-700: #374151;
|
|
752
|
+
--color-gray-800: #1f2937;
|
|
753
|
+
--color-gray-900: #111827;
|
|
754
|
+
--color-zinc-50: #f9fafb;
|
|
755
|
+
--color-zinc-100: #f4f5f7;
|
|
756
|
+
--color-zinc-200: #e5e7eb;
|
|
757
|
+
--color-zinc-300: #d2d6dc;
|
|
758
|
+
--color-zinc-400: #9fa6b2;
|
|
759
|
+
--color-zinc-500: #6b7280;
|
|
760
|
+
--color-zinc-600: #4b5563;
|
|
761
|
+
--color-zinc-700: #374151;
|
|
762
|
+
--color-zinc-800: #1f2937;
|
|
763
|
+
--color-zinc-900: #111827;
|
|
764
|
+
--color-black: #000;
|
|
765
|
+
--color-white: #fff;
|
|
766
|
+
--spacing: 0.25rem;
|
|
767
|
+
--container-md: 28rem;
|
|
768
|
+
--container-lg: 33rem;
|
|
769
|
+
--container-2xl: 40rem;
|
|
770
|
+
--text-xs: 0.8125rem;
|
|
771
|
+
--text-xs--line-height: 1.5rem;
|
|
772
|
+
--text-sm: 0.875rem;
|
|
773
|
+
--text-sm--line-height: 1.5rem;
|
|
774
|
+
--text-base: 1rem;
|
|
775
|
+
--text-base--line-height: 1.75rem;
|
|
776
|
+
--text-lg: 1.125rem;
|
|
777
|
+
--text-lg--line-height: 1.75rem;
|
|
778
|
+
--text-xl: 1.25rem;
|
|
779
|
+
--text-xl--line-height: 1.75rem;
|
|
780
|
+
--text-2xl: 1.5rem;
|
|
781
|
+
--text-2xl--line-height: 2rem;
|
|
782
|
+
--text-4xl: 2.25rem;
|
|
783
|
+
--text-4xl--line-height: 2.5rem;
|
|
784
|
+
--text-5xl: 3rem;
|
|
785
|
+
--text-5xl--line-height: 1;
|
|
786
|
+
--font-weight-normal: 400;
|
|
787
|
+
--font-weight-medium: 500;
|
|
788
|
+
--font-weight-semibold: 600;
|
|
789
|
+
--font-weight-bold: 700;
|
|
790
|
+
--font-weight-extrabold: 800;
|
|
791
|
+
--tracking-tight: -0.025em;
|
|
792
|
+
--leading-tight: 1.25;
|
|
793
|
+
--radius-sm: 0.25rem;
|
|
794
|
+
--radius-md: 0.375rem;
|
|
795
|
+
--radius-lg: 0.5rem;
|
|
796
|
+
--radius-xl: 0.75rem;
|
|
797
|
+
--radius-2xl: 1rem;
|
|
798
|
+
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
|
|
799
|
+
--animate-spin: spin 1s linear infinite;
|
|
800
|
+
--blur-xs: 4px;
|
|
801
|
+
--blur-sm: 8px;
|
|
802
|
+
--default-transition-duration: 0.15s;
|
|
803
|
+
--default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
804
|
+
--default-font-family: var(--font-sans);
|
|
805
|
+
--default-mono-font-family: var(--font-mono);
|
|
806
|
+
--color-primary-500: #fe795d;
|
|
807
|
+
}
|
|
808
|
+
.pac-section {
|
|
809
|
+
width: 100%;
|
|
810
|
+
}
|
|
811
|
+
.pac-container {
|
|
812
|
+
z-index: 10;
|
|
813
|
+
margin-top: calc(var(--spacing, 0.25rem) * 1);
|
|
814
|
+
transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,)
|
|
815
|
+
var(--tw-skew-y,);
|
|
816
|
+
border-radius: var(--radius-lg, 0.5rem);
|
|
817
|
+
position: relative;
|
|
818
|
+
}
|
|
819
|
+
.pac-icon-container {
|
|
820
|
+
pointer-events: none;
|
|
821
|
+
inset-block: calc(var(--spacing, 0.25rem) * 0);
|
|
822
|
+
left: calc(var(--spacing, 0.25rem) * 0);
|
|
823
|
+
padding-left: calc(var(--spacing, 0.25rem) * 3);
|
|
824
|
+
align-items: center;
|
|
825
|
+
display: flex;
|
|
826
|
+
position: absolute;
|
|
827
|
+
}
|
|
828
|
+
.pac-input {
|
|
829
|
+
border-radius: var(--radius-md, 0.375rem);
|
|
830
|
+
border-style: var(--tw-border-style);
|
|
831
|
+
background-color: var(--color-gray-100, oklch(96.7% 0.003 264.542));
|
|
832
|
+
width: 100%;
|
|
833
|
+
padding-inline: calc(var(--spacing, 0.25rem) * 4);
|
|
834
|
+
padding-block: calc(var(--spacing, 0.25rem) * 2.5);
|
|
835
|
+
padding-right: calc(var(--spacing, 0.25rem) * 20);
|
|
836
|
+
padding-left: calc(var(--spacing, 0.25rem) * 10);
|
|
837
|
+
color: var(--color-gray-900, oklch(21% 0.034 264.665));
|
|
838
|
+
--tw-shadow:
|
|
839
|
+
0 1px 3px 0 var(--tw-shadow-color, #0000001a),
|
|
840
|
+
0 1px 2px -1px var(--tw-shadow-color, #0000001a);
|
|
841
|
+
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width))
|
|
842
|
+
var(--tw-ring-color, currentcolor);
|
|
843
|
+
box-shadow:
|
|
844
|
+
var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow),
|
|
845
|
+
var(--tw-ring-shadow), var(--tw-shadow);
|
|
846
|
+
--tw-ring-color: var(--color-gray-300, oklch(87.2% 0.01 258.338));
|
|
847
|
+
--tw-ring-inset: inset;
|
|
848
|
+
border-width: 1px;
|
|
849
|
+
}
|
|
850
|
+
.pac-input:focus {
|
|
851
|
+
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width))
|
|
852
|
+
var(--tw-ring-color, currentcolor);
|
|
853
|
+
box-shadow:
|
|
854
|
+
var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow),
|
|
855
|
+
var(--tw-ring-shadow), var(--tw-shadow);
|
|
856
|
+
}
|
|
857
|
+
@media (min-width: 40rem) {
|
|
858
|
+
.pac-input {
|
|
859
|
+
font-size: var(--text-sm, 0.875rem);
|
|
860
|
+
line-height: var(--tw-leading, var(--text-sm--line-height, calc(1.25 / 0.875)));
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
.pac-kbd-container {
|
|
864
|
+
inset-block: calc(var(--spacing, 0.25rem) * 0);
|
|
865
|
+
right: calc(var(--spacing, 0.25rem) * 0);
|
|
866
|
+
padding-block: calc(var(--spacing, 0.25rem) * 1.5);
|
|
867
|
+
padding-right: calc(var(--spacing, 0.25rem) * 1.5);
|
|
868
|
+
display: flex;
|
|
869
|
+
position: absolute;
|
|
870
|
+
}
|
|
871
|
+
.pac-kbd-escape {
|
|
872
|
+
margin-right: calc(var(--spacing, 0.25rem) * 1);
|
|
873
|
+
width: calc(var(--spacing, 0.25rem) * 8);
|
|
874
|
+
border-radius: var(--radius-sm, 0.25rem);
|
|
875
|
+
border-style: var(--tw-border-style);
|
|
876
|
+
border-width: 1px;
|
|
877
|
+
border-color: var(--color-gray-300, oklch(87.2% 0.01 258.338));
|
|
878
|
+
padding-inline: calc(var(--spacing, 0.25rem) * 1);
|
|
879
|
+
font-family: var(
|
|
880
|
+
--font-sans,
|
|
881
|
+
ui-sans-serif,
|
|
882
|
+
system-ui,
|
|
883
|
+
sans-serif,
|
|
884
|
+
'Apple Color Emoji',
|
|
885
|
+
'Segoe UI Emoji',
|
|
886
|
+
'Segoe UI Symbol',
|
|
887
|
+
'Noto Color Emoji'
|
|
888
|
+
);
|
|
889
|
+
font-size: var(--text-xs, 0.75rem);
|
|
890
|
+
line-height: var(--tw-leading, var(--text-xs--line-height, calc(1 / 0.75)));
|
|
891
|
+
color: var(--color-gray-500, oklch(55.1% 0.027 264.364));
|
|
892
|
+
align-items: center;
|
|
893
|
+
display: inline-flex;
|
|
894
|
+
}
|
|
895
|
+
.pac-kbd-up {
|
|
896
|
+
width: calc(var(--spacing, 0.25rem) * 6);
|
|
897
|
+
border-radius: var(--radius-sm, 0.25rem);
|
|
898
|
+
border-style: var(--tw-border-style);
|
|
899
|
+
border-width: 1px;
|
|
900
|
+
border-color: var(--color-gray-300, oklch(87.2% 0.01 258.338));
|
|
901
|
+
padding-inline: calc(var(--spacing, 0.25rem) * 1);
|
|
902
|
+
font-family: var(
|
|
903
|
+
--font-sans,
|
|
904
|
+
ui-sans-serif,
|
|
905
|
+
system-ui,
|
|
906
|
+
sans-serif,
|
|
907
|
+
'Apple Color Emoji',
|
|
908
|
+
'Segoe UI Emoji',
|
|
909
|
+
'Segoe UI Symbol',
|
|
910
|
+
'Noto Color Emoji'
|
|
911
|
+
);
|
|
912
|
+
font-size: var(--text-xs, 0.75rem);
|
|
913
|
+
line-height: var(--tw-leading, var(--text-xs--line-height, calc(1 / 0.75)));
|
|
914
|
+
color: var(--color-gray-500, oklch(55.1% 0.027 264.364));
|
|
915
|
+
justify-content: center;
|
|
916
|
+
align-items: center;
|
|
917
|
+
display: inline-flex;
|
|
918
|
+
}
|
|
919
|
+
.pac-kbd-down {
|
|
920
|
+
width: calc(var(--spacing, 0.25rem) * 6);
|
|
921
|
+
border-radius: var(--radius-sm, 0.25rem);
|
|
922
|
+
border-style: var(--tw-border-style);
|
|
923
|
+
border-width: 1px;
|
|
924
|
+
border-color: var(--color-gray-400, oklch(70.7% 0.022 261.325));
|
|
925
|
+
padding-inline: calc(var(--spacing, 0.25rem) * 1);
|
|
926
|
+
font-family: var(
|
|
927
|
+
--font-sans,
|
|
928
|
+
ui-sans-serif,
|
|
929
|
+
system-ui,
|
|
930
|
+
sans-serif,
|
|
931
|
+
'Apple Color Emoji',
|
|
932
|
+
'Segoe UI Emoji',
|
|
933
|
+
'Segoe UI Symbol',
|
|
934
|
+
'Noto Color Emoji'
|
|
935
|
+
);
|
|
936
|
+
font-size: var(--text-xs, 0.75rem);
|
|
937
|
+
line-height: var(--tw-leading, var(--text-xs--line-height, calc(1 / 0.75)));
|
|
938
|
+
color: var(--color-gray-500, oklch(55.1% 0.027 264.364));
|
|
939
|
+
justify-content: center;
|
|
940
|
+
align-items: center;
|
|
941
|
+
display: inline-flex;
|
|
942
|
+
}
|
|
943
|
+
.pac-kbd-active {
|
|
944
|
+
background-color: var(--color-indigo-500, oklch(58.5% 0.233 277.117));
|
|
945
|
+
color: var(--color-white, #fff);
|
|
946
|
+
}
|
|
947
|
+
.pac-ul {
|
|
948
|
+
z-index: 50;
|
|
949
|
+
margin-top: calc(var(--spacing, 0.25rem) * 1);
|
|
950
|
+
margin-bottom: calc(var(--spacing, 0.25rem) * -2);
|
|
951
|
+
max-height: calc(var(--spacing, 0.25rem) * 60);
|
|
952
|
+
width: 100%;
|
|
953
|
+
list-style-type: none;
|
|
954
|
+
position: absolute;
|
|
955
|
+
}
|
|
956
|
+
:where(.pac-ul > :not(:last-child)) {
|
|
957
|
+
--tw-divide-y-reverse: 0;
|
|
958
|
+
border-bottom-style: var(--tw-border-style);
|
|
959
|
+
border-top-style: var(--tw-border-style);
|
|
960
|
+
border-top-width: calc(1px * var(--tw-divide-y-reverse));
|
|
961
|
+
border-bottom-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
|
|
962
|
+
border-color: var(--color-gray-100, oklch(96.7% 0.003 264.542));
|
|
963
|
+
}
|
|
964
|
+
.pac-ul {
|
|
965
|
+
border-radius: var(--radius-md, 0.375rem);
|
|
966
|
+
background-color: var(--color-white, #fff);
|
|
967
|
+
padding: calc(var(--spacing, 0.25rem) * 0);
|
|
968
|
+
font-size: var(--text-base, 1rem);
|
|
969
|
+
line-height: var(--tw-leading, var(--text-base--line-height, 1.5));
|
|
970
|
+
--tw-shadow:
|
|
971
|
+
0 10px 15px -3px var(--tw-shadow-color, #0000001a),
|
|
972
|
+
0 4px 6px -4px var(--tw-shadow-color, #0000001a);
|
|
973
|
+
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width))
|
|
974
|
+
var(--tw-ring-color, currentcolor);
|
|
975
|
+
box-shadow:
|
|
976
|
+
var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow),
|
|
977
|
+
var(--tw-ring-shadow), var(--tw-shadow);
|
|
978
|
+
--tw-ring-color: var(--color-black, #000);
|
|
979
|
+
overflow: auto;
|
|
980
|
+
}
|
|
981
|
+
.pac-ul:focus {
|
|
982
|
+
--tw-outline-style: none;
|
|
983
|
+
outline-style: none;
|
|
984
|
+
}
|
|
985
|
+
@media (min-width: 40rem) {
|
|
986
|
+
.pac-ul {
|
|
987
|
+
font-size: var(--text-sm, 0.875rem);
|
|
988
|
+
line-height: var(--tw-leading, var(--text-sm--line-height, calc(1.25 / 0.875)));
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
.pac-li {
|
|
992
|
+
cursor: default;
|
|
993
|
+
padding-inline: calc(var(--spacing, 0.25rem) * 2);
|
|
994
|
+
padding-block: calc(var(--spacing, 0.25rem) * 2);
|
|
995
|
+
color: var(--color-gray-900, oklch(21% 0.034 264.665));
|
|
996
|
+
-webkit-user-select: none;
|
|
997
|
+
-moz-user-select: none;
|
|
998
|
+
user-select: none;
|
|
999
|
+
}
|
|
1000
|
+
@media (hover: hover) {
|
|
1001
|
+
.pac-li:hover {
|
|
1002
|
+
background-color: var(--color-indigo-500, oklch(58.5% 0.233 277.117));
|
|
1003
|
+
color: var(--color-white, #fff);
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
@media (min-width: 64rem) {
|
|
1007
|
+
.pac-li {
|
|
1008
|
+
padding-inline: calc(var(--spacing, 0.25rem) * 4);
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
.pac-li-button {
|
|
1012
|
+
width: 100%;
|
|
1013
|
+
color: inherit;
|
|
1014
|
+
-webkit-text-decoration: inherit;
|
|
1015
|
+
text-decoration: inherit;
|
|
1016
|
+
font: inherit;
|
|
1017
|
+
cursor: pointer;
|
|
1018
|
+
background: 0 0;
|
|
1019
|
+
border: none;
|
|
1020
|
+
justify-content: space-between;
|
|
1021
|
+
padding: 0;
|
|
1022
|
+
display: flex;
|
|
1023
|
+
}
|
|
1024
|
+
.pac-li-div-container {
|
|
1025
|
+
justify-content: space-between;
|
|
1026
|
+
align-items: center;
|
|
1027
|
+
width: 100%;
|
|
1028
|
+
display: flex;
|
|
1029
|
+
}
|
|
1030
|
+
.pac-li-div-container p {
|
|
1031
|
+
margin-block: 0;
|
|
1032
|
+
margin: 0;
|
|
1033
|
+
}
|
|
1034
|
+
.pac-li-div-one {
|
|
1035
|
+
min-width: calc(var(--spacing, 0.25rem) * 0);
|
|
1036
|
+
align-items: center;
|
|
1037
|
+
-moz-column-gap: calc(var(--spacing, 0.25rem) * 3);
|
|
1038
|
+
column-gap: calc(var(--spacing, 0.25rem) * 3);
|
|
1039
|
+
flex: auto;
|
|
1040
|
+
display: flex;
|
|
1041
|
+
}
|
|
1042
|
+
.pac-map-icon-svg {
|
|
1043
|
+
height: calc(var(--spacing, 0.25rem) * 6);
|
|
1044
|
+
width: calc(var(--spacing, 0.25rem) * 6);
|
|
1045
|
+
flex-shrink: 0;
|
|
1046
|
+
}
|
|
1047
|
+
.pac-li-div-p-container {
|
|
1048
|
+
min-height: calc(var(--spacing, 0.25rem) * 10);
|
|
1049
|
+
flex-direction: column;
|
|
1050
|
+
justify-content: center;
|
|
1051
|
+
align-items: flex-start;
|
|
1052
|
+
display: flex;
|
|
1053
|
+
}
|
|
1054
|
+
.pac-li-div-one-p {
|
|
1055
|
+
font-size: var(--text-sm, 0.875rem);
|
|
1056
|
+
line-height: calc(var(--spacing, 0.25rem) * 4);
|
|
1057
|
+
}
|
|
1058
|
+
.pac-li-div-one-p-secondaryText {
|
|
1059
|
+
font-size: var(--text-xs, 0.75rem);
|
|
1060
|
+
line-height: calc(var(--spacing, 0.25rem) * 4);
|
|
1061
|
+
}
|
|
1062
|
+
.pac-li-current {
|
|
1063
|
+
background-color: var(--color-indigo-500, oklch(58.5% 0.233 277.117));
|
|
1064
|
+
color: var(--color-white, #fff);
|
|
1065
|
+
-webkit-text-decoration: inherit;
|
|
1066
|
+
text-decoration: inherit;
|
|
1067
|
+
}
|
|
1068
|
+
.pac-li-button-current {
|
|
1069
|
+
color: var(--color-white, #fff);
|
|
1070
|
+
}
|
|
1071
|
+
.pac-li-div-two {
|
|
1072
|
+
min-width: calc(var(--spacing, 0.25rem) * 16);
|
|
1073
|
+
flex-direction: column;
|
|
1074
|
+
flex-shrink: 0;
|
|
1075
|
+
align-items: flex-end;
|
|
1076
|
+
display: flex;
|
|
1077
|
+
}
|
|
1078
|
+
.pac-li-div-two-p {
|
|
1079
|
+
font-size: var(--text-xs, 0.75rem);
|
|
1080
|
+
line-height: var(--tw-leading, var(--text-xs--line-height, calc(1 / 0.75)));
|
|
1081
|
+
}
|
|
1082
|
+
.pac-highlight {
|
|
1083
|
+
--tw-font-weight: var(--font-weight-bold, 700);
|
|
1084
|
+
font-weight: var(--font-weight-bold, 700);
|
|
1085
|
+
}
|
|
1086
|
+
@property --tw-rotate-x {
|
|
1087
|
+
syntax: '*';
|
|
1088
|
+
inherits: false;
|
|
1089
|
+
}
|
|
1090
|
+
@property --tw-rotate-y {
|
|
1091
|
+
syntax: '*';
|
|
1092
|
+
inherits: false;
|
|
1093
|
+
}
|
|
1094
|
+
@property --tw-rotate-z {
|
|
1095
|
+
syntax: '*';
|
|
1096
|
+
inherits: false;
|
|
1097
|
+
}
|
|
1098
|
+
@property --tw-skew-x {
|
|
1099
|
+
syntax: '*';
|
|
1100
|
+
inherits: false;
|
|
1101
|
+
}
|
|
1102
|
+
@property --tw-skew-y {
|
|
1103
|
+
syntax: '*';
|
|
1104
|
+
inherits: false;
|
|
1105
|
+
}
|
|
1106
|
+
@property --tw-border-style {
|
|
1107
|
+
syntax: '*';
|
|
1108
|
+
inherits: false;
|
|
1109
|
+
initial-value: solid;
|
|
1110
|
+
}
|
|
1111
|
+
@property --tw-shadow {
|
|
1112
|
+
syntax: '*';
|
|
1113
|
+
inherits: false;
|
|
1114
|
+
initial-value: 0 0 #0000;
|
|
1115
|
+
}
|
|
1116
|
+
@property --tw-shadow-color {
|
|
1117
|
+
syntax: '*';
|
|
1118
|
+
inherits: false;
|
|
1119
|
+
}
|
|
1120
|
+
@property --tw-shadow-alpha {
|
|
1121
|
+
syntax: '<percentage>';
|
|
1122
|
+
inherits: false;
|
|
1123
|
+
initial-value: 100%;
|
|
1124
|
+
}
|
|
1125
|
+
@property --tw-inset-shadow {
|
|
1126
|
+
syntax: '*';
|
|
1127
|
+
inherits: false;
|
|
1128
|
+
initial-value: 0 0 #0000;
|
|
1129
|
+
}
|
|
1130
|
+
@property --tw-inset-shadow-color {
|
|
1131
|
+
syntax: '*';
|
|
1132
|
+
inherits: false;
|
|
1133
|
+
}
|
|
1134
|
+
@property --tw-inset-shadow-alpha {
|
|
1135
|
+
syntax: '<percentage>';
|
|
1136
|
+
inherits: false;
|
|
1137
|
+
initial-value: 100%;
|
|
1138
|
+
}
|
|
1139
|
+
@property --tw-ring-color {
|
|
1140
|
+
syntax: '*';
|
|
1141
|
+
inherits: false;
|
|
1142
|
+
}
|
|
1143
|
+
@property --tw-ring-shadow {
|
|
1144
|
+
syntax: '*';
|
|
1145
|
+
inherits: false;
|
|
1146
|
+
initial-value: 0 0 #0000;
|
|
1147
|
+
}
|
|
1148
|
+
@property --tw-inset-ring-color {
|
|
1149
|
+
syntax: '*';
|
|
1150
|
+
inherits: false;
|
|
1151
|
+
}
|
|
1152
|
+
@property --tw-inset-ring-shadow {
|
|
1153
|
+
syntax: '*';
|
|
1154
|
+
inherits: false;
|
|
1155
|
+
initial-value: 0 0 #0000;
|
|
1156
|
+
}
|
|
1157
|
+
@property --tw-ring-inset {
|
|
1158
|
+
syntax: '*';
|
|
1159
|
+
inherits: false;
|
|
1160
|
+
}
|
|
1161
|
+
@property --tw-ring-offset-width {
|
|
1162
|
+
syntax: '<length>';
|
|
1163
|
+
inherits: false;
|
|
1164
|
+
initial-value: 0;
|
|
1165
|
+
}
|
|
1166
|
+
@property --tw-ring-offset-color {
|
|
1167
|
+
syntax: '*';
|
|
1168
|
+
inherits: false;
|
|
1169
|
+
initial-value: #fff;
|
|
1170
|
+
}
|
|
1171
|
+
@property --tw-ring-offset-shadow {
|
|
1172
|
+
syntax: '*';
|
|
1173
|
+
inherits: false;
|
|
1174
|
+
initial-value: 0 0 #0000;
|
|
1175
|
+
}
|
|
1176
|
+
@property --tw-divide-y-reverse {
|
|
1177
|
+
syntax: '*';
|
|
1178
|
+
inherits: false;
|
|
1179
|
+
initial-value: 0;
|
|
1180
|
+
}
|
|
1181
|
+
@property --tw-font-weight {
|
|
1182
|
+
syntax: '*';
|
|
1183
|
+
inherits: false;
|
|
481
1184
|
}
|
|
482
1185
|
</style>
|