places-autocomplete-svelte 2.2.20 → 2.2.21

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