places-autocomplete-svelte 2.2.23 → 2.2.24
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 +156 -11
- package/dist/PlaceAutocomplete.svelte +196 -22
- package/dist/PlaceAutocomplete.svelte.d.ts +8 -1
- package/dist/helpers.d.ts +111 -0
- package/dist/helpers.js +138 -7
- package/dist/interfaces.d.ts +34 -1
- package/package.json +13 -12
package/README.md
CHANGED
|
@@ -50,6 +50,7 @@ The component handles API loading, session tokens, debounced fetching, and acces
|
|
|
50
50
|
* 💰 Automatically handles **session tokens** for optimal cost management
|
|
51
51
|
* ⚡ **Debounced Input:** Configurable delay to minimise API calls while typing
|
|
52
52
|
* ✨ **Suggestion Highlighting:** Automatically highlights matched text in suggestions
|
|
53
|
+
* 🌍 **Internationally Neutral:** No default regional restrictions - works globally out of the box
|
|
53
54
|
|
|
54
55
|
### Accessibility & User Experience
|
|
55
56
|
* ♿ **WCAG Compliant:** Follows WAI-ARIA patterns for comboboxes
|
|
@@ -58,7 +59,7 @@ The component handles API loading, session tokens, debounced fetching, and acces
|
|
|
58
59
|
|
|
59
60
|
### Developer Experience
|
|
60
61
|
* 🎨 **Customisable Styling:** Override default styles via `options.classes` prop
|
|
61
|
-
* 🔧 **Imperative API:** Direct control with `clear()`, `focus()`, `getRequestParams()`, `setRequestParams()`, `setFetchFields()`, and `
|
|
62
|
+
* 🔧 **Imperative API:** Direct control with `clear()`, `focus()`, `getRequestParams()`, `setRequestParams()`, `setFetchFields()`, `getFetchFields()`, and `setInputValue()` methods
|
|
62
63
|
* 📘 **TypeScript Support:** Fully typed with comprehensive type definitions
|
|
63
64
|
* 🔐 **Secure:** XSS protection with safe rendering of suggestions
|
|
64
65
|
* 🎯 **Event Handling:** `onResponse` and `onError` callbacks for complete control
|
|
@@ -94,7 +95,6 @@ This component has been recognised as a winner of the **Google Maps Platform Awa
|
|
|
94
95
|
## Requirements
|
|
95
96
|
|
|
96
97
|
* **Svelte 5+** - This component requires Svelte 5.0.0 or higher and uses Svelte 5 features including runes (`$state`, `$derived`, etc.)
|
|
97
|
-
* **Node.js 18+** - Required for development and building
|
|
98
98
|
* **Google Maps API Key** with the "Places API" enabled. Refer to [Use API Keys](https://developers.google.com/maps/documentation/javascript/get-api-key) for detailed instructions.
|
|
99
99
|
|
|
100
100
|
## Installation
|
|
@@ -122,6 +122,21 @@ For simple use cases, just pass your API key to the component. It will automatic
|
|
|
122
122
|
// Get API Key securely (e.g., from environment variables)
|
|
123
123
|
const PUBLIC_GOOGLE_MAPS_API_KEY = import.meta.env.VITE_PUBLIC_GOOGLE_MAPS_API_KEY;
|
|
124
124
|
|
|
125
|
+
// Optional: Set regional preferences (component works globally by default)
|
|
126
|
+
const requestParams = {
|
|
127
|
+
language: 'en-US', // Set language preference
|
|
128
|
+
region: 'US', // Set regional bias
|
|
129
|
+
// includedRegionCodes: ['US', 'CA'] // Restrict to specific regions
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
// Optional: Configure UI and behaviour
|
|
133
|
+
const options = {
|
|
134
|
+
show_place_type: true, // Show place type icons
|
|
135
|
+
distance: true, // Show distance (if origin provided)
|
|
136
|
+
response_type: 'json', // Return JSON object (default)
|
|
137
|
+
placeholder: 'Search for places...'
|
|
138
|
+
};
|
|
139
|
+
|
|
125
140
|
const handleResponse = (response: PlaceResult) => {
|
|
126
141
|
console.log('Selected:', response.formattedAddress);
|
|
127
142
|
};
|
|
@@ -133,6 +148,8 @@ For simple use cases, just pass your API key to the component. It will automatic
|
|
|
133
148
|
|
|
134
149
|
<PlaceAutocomplete
|
|
135
150
|
{PUBLIC_GOOGLE_MAPS_API_KEY}
|
|
151
|
+
{requestParams}
|
|
152
|
+
{options}
|
|
136
153
|
onResponse={handleResponse}
|
|
137
154
|
onError={handleError}
|
|
138
155
|
/>
|
|
@@ -259,8 +276,8 @@ This component is built to be accessible and follows the [WAI-ARIA Authoring Pra
|
|
|
259
276
|
| `onResponse` | `(response: PlaceResult) => void` | Yes | - | Callback triggered when a user selects a place. Receives the full place details object. |
|
|
260
277
|
| `onError` | `(error: string) => void` | Yes | - | Callback triggered when an error occurs (API loading, network issues, etc.). |
|
|
261
278
|
| `fetchFields` | `string[]` | No | `['formattedAddress', 'addressComponents']` | Place Data Fields to request from the API. See [Place Data Fields](https://developers.google.com/maps/documentation/javascript/place-data-fields). **Affects API billing.** |
|
|
262
|
-
| `requestParams` | `Partial<RequestParams>` | No | `{ inputOffset:
|
|
263
|
-
| `options` | `Partial<ComponentOptions>` | No | `{ debounce: 100 }` | UI and
|
|
279
|
+
| `requestParams` | `Partial<RequestParams>` | No | `{ inputOffset: 0 }` | Parameters for the Autocomplete API request. By default, the component is internationally neutral (no default `language` or `region`), allowing the Google Maps API to use browser settings and IP-based location detection. You can specify parameters like `language`, `region` (for biasing results), or `includedRegionCodes` (for filtering results) to customize behaviour. See the RequestParams interface for all options. |
|
|
280
|
+
| `options` | `Partial<ComponentOptions>` | No | `{ debounce: 100 }` | UI and behaviour options (placeholder, debounce delay, distance display, custom classes, etc.). See ComponentOptions interface. |
|
|
264
281
|
|
|
265
282
|
*Either `PUBLIC_GOOGLE_MAPS_API_KEY` prop OR manual initialisation with `initialiseGMaps()` is required.
|
|
266
283
|
|
|
@@ -287,6 +304,9 @@ Get a reference to the component instance using `bind:this` to call its methods
|
|
|
287
304
|
<button onclick={() => autocompleteComponent?.setOptions({ placeholder: 'Search locations...', debounce: 300 })}>
|
|
288
305
|
Update Options
|
|
289
306
|
</button>
|
|
307
|
+
<button onclick={() => autocompleteComponent?.setInputValue(48.8584, 2.2945)}>
|
|
308
|
+
Set to Eiffel Tower
|
|
309
|
+
</button>
|
|
290
310
|
```
|
|
291
311
|
|
|
292
312
|
| Method | Signature | Description |
|
|
@@ -299,6 +319,94 @@ Get a reference to the component instance using `bind:this` to call its methods
|
|
|
299
319
|
| `getFetchFields()` | `() => string[]` | Returns the current array of Place Data Fields that will be requested. |
|
|
300
320
|
| `setOptions(options)` | `(options: Partial<ComponentOptions>) => void` | Dynamically updates the component's configuration options. Merges the provided options with existing settings. |
|
|
301
321
|
| `getOptions()` | `() => ComponentOptions` | Returns the current validated options used by the component. Useful for inspecting configuration settings. |
|
|
322
|
+
| `setInputValue(latitude, longitude)` | `(latitude: number, longitude: number) => Promise<void>` | Sets the input by finding and selecting a place for the given coordinates. Performs reverse geocoding to convert lat/lng to a place, then triggers `onResponse`. **Requires Geocoding API to be enabled.** |
|
|
323
|
+
|
|
324
|
+
### Reverse Geocoding with `setInputValue`
|
|
325
|
+
|
|
326
|
+
The `setInputValue` method allows you to programmatically set a location by coordinates, useful for integrating with geolocation APIs or map click events:
|
|
327
|
+
|
|
328
|
+
```javascript
|
|
329
|
+
// Example: Set location from user's current position
|
|
330
|
+
navigator.geolocation.getCurrentPosition(async (position) => {
|
|
331
|
+
try {
|
|
332
|
+
await autocompleteComponent.setInputValue(
|
|
333
|
+
position.coords.latitude,
|
|
334
|
+
position.coords.longitude
|
|
335
|
+
);
|
|
336
|
+
console.log('Location set successfully');
|
|
337
|
+
} catch (error) {
|
|
338
|
+
console.error('Failed to set location:', error);
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
// Example: Set specific landmark (Eiffel Tower)
|
|
343
|
+
await autocompleteComponent.setInputValue(48.8584, 2.2945);
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
**Important:** This method requires the **Geocoding API** to be enabled in your Google Cloud Console project. The method:
|
|
347
|
+
1. Performs reverse geocoding to convert coordinates to a place
|
|
348
|
+
2. Fetches place details using your configured `fetchFields`
|
|
349
|
+
3. Triggers the `onResponse` callback with the place data
|
|
350
|
+
4. Updates the input field (respects `clear_input` option)
|
|
351
|
+
|
|
352
|
+
## Advanced Response Handling
|
|
353
|
+
|
|
354
|
+
### Response Types
|
|
355
|
+
|
|
356
|
+
Control the format of data returned by the `onResponse` callback using the `response_type` option:
|
|
357
|
+
|
|
358
|
+
**JSON Format (Default):**
|
|
359
|
+
```javascript
|
|
360
|
+
const options = {
|
|
361
|
+
response_type: 'json' // Default
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
const handleResponse = (response: PlaceResult) => {
|
|
365
|
+
console.log(response.formattedAddress); // "123 Main St, City, Country"
|
|
366
|
+
console.log(response.location); // { lat: 40.7128, lng: -74.0060 }
|
|
367
|
+
console.log(response.addressComponents); // Array of address components
|
|
368
|
+
};
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
**Google Maps Place Instance:**
|
|
372
|
+
```javascript
|
|
373
|
+
const options = {
|
|
374
|
+
response_type: 'place'
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
const handleResponse = (place: google.maps.places.Place) => {
|
|
378
|
+
// Access to full Place API methods
|
|
379
|
+
console.log(place.formattedAddress);
|
|
380
|
+
console.log(place.location);
|
|
381
|
+
|
|
382
|
+
// Access photos (if fetchFields includes 'photos')
|
|
383
|
+
const photos = place.photos;
|
|
384
|
+
if (photos && photos.length > 0) {
|
|
385
|
+
const photoUrl = photos[0].getURI({ maxHeight: 1200 });
|
|
386
|
+
console.log('Photo URL:', photoUrl);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// Convert to JSON when needed
|
|
390
|
+
const jsonData = place.toJSON();
|
|
391
|
+
console.log('JSON format:', jsonData);
|
|
392
|
+
};
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### Place Type Icons
|
|
396
|
+
|
|
397
|
+
Enable visual categorisation of suggestions with place type icons:
|
|
398
|
+
|
|
399
|
+
```javascript
|
|
400
|
+
const options = {
|
|
401
|
+
show_place_type: true,
|
|
402
|
+
distance: false, // Must be false when using place type icons
|
|
403
|
+
fetchFields: ['formattedAddress', 'primaryType'] // Ensure primaryType is included
|
|
404
|
+
};
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
**Important:** `show_place_type` and `distance` are mutually exclusive - only one can be enabled at a time. When `show_place_type` is `true`, the distance display is automatically disabled.
|
|
408
|
+
|
|
409
|
+
This displays categorized icons (🏪 Shopping, 🍽️ Dining, 🏨 Lodging, etc.) on the right side of each suggestion, helping users quickly identify the type of place.
|
|
302
410
|
|
|
303
411
|
## Options
|
|
304
412
|
|
|
@@ -306,13 +414,15 @@ Get a reference to the component instance using `bind:this` to call its methods
|
|
|
306
414
|
| :--- | :--- | :--- | :--- |
|
|
307
415
|
| `placeholder` | `string` | `''` | Placeholder text for the input field. |
|
|
308
416
|
| `debounce` | `number` | `100` | Delay in ms before firing API request. Set to `0` to disable. |
|
|
309
|
-
| `distance` | `boolean` | `
|
|
417
|
+
| `distance` | `boolean` | `false` | Show distance from `requestParams.origin` (if provided). **Mutually exclusive with `show_place_type`.** |
|
|
310
418
|
| `distance_units` | `'km' \| 'miles'` | `'km'` | Units for displaying distance. |
|
|
311
419
|
| `label` | `string` | `''` | Optional label text displayed above the input. |
|
|
312
420
|
| `autofocus` | `boolean` | `false` | Automatically focus the input on mount. |
|
|
313
421
|
| `autocomplete` | `string` | `'off'` | The `autocomplete` attribute for the input field. |
|
|
314
422
|
| `classes` | `Partial<ComponentClasses>` | `{}` | Object to override default CSS classes. See Styling section. |
|
|
315
423
|
| `clear_input` | `boolean` | `true` | If `false`, retains the `formattedAddress` in the input after selection. |
|
|
424
|
+
| `response_type` | `'json' \| 'place'` | `'json'` | Return format: `'json'` for JSON object (`.toJSON()`), `'place'` for Google Maps Place instance with access to methods like `.getPhotos()`. |
|
|
425
|
+
| `show_place_type` | `boolean` | `false` | Display place type icons (shopping, dining, etc.) on the right side of suggestion items. **Mutually exclusive with `distance`.** |
|
|
316
426
|
|
|
317
427
|
## Styling
|
|
318
428
|
|
|
@@ -322,14 +432,14 @@ The component includes built-in styles with `.pac-` prefixed CSS classes, provid
|
|
|
322
432
|
|
|
323
433
|
* **Framework-agnostic**: Pure CSS with no dependencies on Tailwind or other frameworks
|
|
324
434
|
* **Modern design**: Clean, professional appearance with proper spacing, shadows, and hover effects
|
|
325
|
-
* **Fully functional**: Includes keyboard navigation indicators, loading states, and responsive
|
|
435
|
+
* **Fully functional**: Includes keyboard navigation indicators, loading states, and responsive behaviour
|
|
326
436
|
* **Customisable**: All styles can be overridden via the `options.classes` prop
|
|
327
437
|
|
|
328
438
|
The default styles include:
|
|
329
439
|
- Rounded input with shadow and focus states
|
|
330
|
-
- Dropdown list with scroll
|
|
440
|
+
- Dropdown list with scroll behaviour and dividers
|
|
331
441
|
- Keyboard navigation hints (Esc, ↑, ↓)
|
|
332
|
-
- Highlighted current selection with
|
|
442
|
+
- Highlighted current selection with colour transitions
|
|
333
443
|
- Distance display for location-based results
|
|
334
444
|
- Icon support with proper alignment
|
|
335
445
|
- Responsive layout for mobile and desktop
|
|
@@ -358,7 +468,10 @@ Override any default styling by providing your own CSS classes via `options.clas
|
|
|
358
468
|
* `li_div_p_container`: Container for paragraphs (default: `.pac-li-div-p-container`)
|
|
359
469
|
* `li_div_two`: Second inner `div` containing the distance (default: `.pac-li-div-two`)
|
|
360
470
|
* `li_div_two_p`: The `<p>` tag containing the distance text (default: `.pac-li-div-two-p`)
|
|
361
|
-
* `
|
|
471
|
+
* `li_div_two_p_place_type`: Container for place type display (default: `.pac-li-div-two-p-place_type`)
|
|
472
|
+
* `li_div_two_p_place_type_icon`: The place type icon element (default: `.pac-li-div-two-p-place_type-icon`)
|
|
473
|
+
* `li_div_two_p_place_type_label`: The place type label text (default: `.pac-li-div-two-p-place_type-label`)
|
|
474
|
+
* `kbd_container`: Container for the keyboard hint keys (default: `.pac-kbd-container`))
|
|
362
475
|
* `kbd_escape`: The `<kbd>` tag for the 'Esc' hint (default: `.pac-kbd-escape`)
|
|
363
476
|
* `kbd_up`: The `<kbd>` tag for the 'Up Arrow' hint (default: `.pac-kbd-up`)
|
|
364
477
|
* `kbd_down`: The `<kbd>` tag for the 'Down Arrow' hint (default: `.pac-kbd-down`)
|
|
@@ -375,7 +488,11 @@ const options = {
|
|
|
375
488
|
ul: 'absolute mt-1 w-full bg-white shadow-lg rounded-md border border-gray-200 max-h-60 overflow-auto',
|
|
376
489
|
li: 'px-4 py-2 hover:bg-blue-500 hover:text-white cursor-pointer',
|
|
377
490
|
li_current: 'bg-blue-500 text-white',
|
|
378
|
-
highlight: 'font-semibold text-blue-700'
|
|
491
|
+
highlight: 'font-semibold text-blue-700',
|
|
492
|
+
// Place type styling
|
|
493
|
+
li_div_two_p_place_type: 'flex items-center gap-1 text-gray-500',
|
|
494
|
+
li_div_two_p_place_type_icon: 'w-4 h-4',
|
|
495
|
+
li_div_two_p_place_type_label: 'text-xs font-medium'
|
|
379
496
|
}
|
|
380
497
|
};
|
|
381
498
|
```
|
|
@@ -416,7 +533,7 @@ import { PlaceAutocomplete } from 'places-autocomplete-svelte';
|
|
|
416
533
|
```typescript
|
|
417
534
|
import type {
|
|
418
535
|
PlaceResult, // Place data returned from API
|
|
419
|
-
ComponentOptions, // UI and
|
|
536
|
+
ComponentOptions, // UI and behaviour configuration
|
|
420
537
|
RequestParams, // Autocomplete request parameters
|
|
421
538
|
FormattedAddress, // Standardised address structure
|
|
422
539
|
ComponentClasses, // CSS class overrides
|
|
@@ -445,6 +562,34 @@ import {
|
|
|
445
562
|
* Place Details requests (via `fetchFields`) are billed separately. **Only request the fields you need** to manage costs effectively.
|
|
446
563
|
* For detailed pricing information, see [Google Maps Platform Pricing](https://developers.google.com/maps/documentation/javascript/usage-and-billing).
|
|
447
564
|
|
|
565
|
+
## Troubleshooting
|
|
566
|
+
|
|
567
|
+
Common issues and how to resolve them:
|
|
568
|
+
|
|
569
|
+
### No Suggestions Appear / "This API project is not authorised..."
|
|
570
|
+
|
|
571
|
+
This is typically an issue with your Google Maps API key.
|
|
572
|
+
|
|
573
|
+
* **Check API Key Restrictions:** Ensure your key is correctly restricted. For web use, you should have an **HTTP referrer** restriction matching your website's domain (e.g., `yourdomain.com/*`). For local development, you might need to add `localhost:*` or your specific local server address.
|
|
574
|
+
* **Enable APIs:** In the Google Cloud Console, make sure you have enabled both the **Places API** and the **Maps JavaScript API** for your project. The `setInputValue()` method also requires the **Geocoding API**.
|
|
575
|
+
* **Enable Billing:** Your Google Cloud project must have a valid billing account attached.
|
|
576
|
+
* **Check for Errors:** Open your browser's developer console and check for any error messages from the Google Maps script.
|
|
577
|
+
|
|
578
|
+
### "Loader must not be called again" Error
|
|
579
|
+
|
|
580
|
+
This error occurs when you have multiple Google Maps components on the same page (or across different routes in a SvelteKit app) and each one tries to initialize the Google Maps loader independently.
|
|
581
|
+
|
|
582
|
+
**Solution:** Use the **Advanced Usage (Manual Initialisation)** pattern.
|
|
583
|
+
1. Call `setGMapsContext()` once in a shared parent component (like `+layout.svelte`).
|
|
584
|
+
2. Call `initialiseGMaps()` once in the same parent component, inside a `if (browser)` block.
|
|
585
|
+
3. The `PlaceAutocomplete` component (and any other Google Maps components) will then automatically use the shared loader instance, preventing the error.
|
|
586
|
+
|
|
587
|
+
### Component or Styles Not Loading Correctly
|
|
588
|
+
|
|
589
|
+
* **Check Installation:** Make sure the `places-autocomplete-svelte` package is correctly installed in your `node_modules`.
|
|
590
|
+
* **SvelteKit / Vite Config:** Ensure your bundler is correctly processing Svelte components from `node_modules`. This is usually handled automatically.
|
|
591
|
+
* **CSS Conflicts:** If the styling looks broken, you may have global styles that are conflicting with the component's default `.pac-` classes. You can either debug the conflicting styles or use the `options.classes` prop to replace the default classes with your own (e.g., Tailwind CSS classes), giving you full control over styling.
|
|
592
|
+
|
|
448
593
|
## Standalone JavaScript Library
|
|
449
594
|
|
|
450
595
|
Need this functionality for a non-Svelte project? Check out our companion vanilla JavaScript library:
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
* @see https://github.com/alexpechkarev/places-autocomplete-svelte
|
|
6
6
|
* @version 1.0.0
|
|
7
7
|
* @license MIT
|
|
8
|
-
*
|
|
8
|
+
*
|
|
9
9
|
* A production-ready, accessible autocomplete component for Google Places API (New).
|
|
10
10
|
* Built with Svelte 5 runes for optimal reactivity and performance.
|
|
11
|
-
*
|
|
11
|
+
*
|
|
12
12
|
* @features
|
|
13
13
|
* - Full keyboard navigation (ArrowUp, ArrowDown, Enter, Escape)
|
|
14
14
|
* - Session token management for billing optimization
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
* - Text highlighting in suggestions
|
|
19
19
|
* - ARIA-compliant accessibility
|
|
20
20
|
* - Imperative API for programmatic control
|
|
21
|
-
*
|
|
22
|
-
*
|
|
21
|
+
*
|
|
22
|
+
*
|
|
23
23
|
* @publicMethods
|
|
24
24
|
* - `clear()` - Clears input and resets session
|
|
25
25
|
* - `focus()` - Focuses the input field
|
|
@@ -27,7 +27,8 @@
|
|
|
27
27
|
* - `setRequestParams(params)` - Updates request parameters dynamically
|
|
28
28
|
* - `setFetchFields(fields)` - Updates Place Data Fields to fetch
|
|
29
29
|
* - `getFetchFields()` - Returns current fetch fields
|
|
30
|
-
*
|
|
30
|
+
* - `setInputValue(latitude, longitude)` - Finds and selects a place by coordinates
|
|
31
|
+
*
|
|
31
32
|
*/
|
|
32
33
|
|
|
33
34
|
import { onMount, untrack } from 'svelte';
|
|
@@ -45,7 +46,9 @@
|
|
|
45
46
|
formatDistance,
|
|
46
47
|
validateFetchFields,
|
|
47
48
|
createHighlightedSegments,
|
|
48
|
-
debounce
|
|
49
|
+
debounce,
|
|
50
|
+
ITINERARY_CATEGORIES,
|
|
51
|
+
ITINERARY_SVG_ICONS
|
|
49
52
|
} from './helpers.js';
|
|
50
53
|
|
|
51
54
|
let gmaps: GMapsContext | undefined;
|
|
@@ -116,7 +119,7 @@
|
|
|
116
119
|
* @param {PlaceResult} [placeData] - Optional place data to populate the input field with.
|
|
117
120
|
* @private
|
|
118
121
|
*/
|
|
119
|
-
const reset = (placeData?: PlaceResult) => {
|
|
122
|
+
export const reset = (placeData?: PlaceResult) => {
|
|
120
123
|
currentSuggestion = -1;
|
|
121
124
|
if (validatedOptions?.clear_input == false) {
|
|
122
125
|
if (placeData && placeData.formattedAddress) {
|
|
@@ -227,10 +230,9 @@
|
|
|
227
230
|
* showDistance: true
|
|
228
231
|
* });
|
|
229
232
|
*/
|
|
230
|
-
export function setOptions(options: typeof validatedOptions){
|
|
233
|
+
export function setOptions(options: typeof validatedOptions) {
|
|
231
234
|
validatedOptions = validateOptions(options);
|
|
232
|
-
}
|
|
233
|
-
|
|
235
|
+
}
|
|
234
236
|
|
|
235
237
|
/**
|
|
236
238
|
* Returns the current validated options used by the component.
|
|
@@ -245,6 +247,71 @@
|
|
|
245
247
|
return validatedOptions;
|
|
246
248
|
}
|
|
247
249
|
|
|
250
|
+
/**
|
|
251
|
+
* Sets the input value by finding and selecting a place for the given coordinates.
|
|
252
|
+
* Performs reverse geocoding to convert latitude/longitude to a place, then fetches
|
|
253
|
+
* place details and triggers the onResponse callback.
|
|
254
|
+
* @public
|
|
255
|
+
* @param {number} latitude - The latitude coordinate of the location.
|
|
256
|
+
* @param {number} longitude - The longitude coordinate of the location.
|
|
257
|
+
* @returns {Promise<void>} A promise that resolves when the place has been found and selected.
|
|
258
|
+
* @throws {Error} If the geocoding fails or no place is found for the coordinates.
|
|
259
|
+
* @example
|
|
260
|
+
* // Set input to a specific location (e.g., Eiffel Tower)
|
|
261
|
+
* await autocompleteComponent.setInputValue(48.8584, 2.2945);
|
|
262
|
+
*/
|
|
263
|
+
export async function setInputValue(latitude: number, longitude: number): Promise<void> {
|
|
264
|
+
try {
|
|
265
|
+
// Ensure placesApi is loaded
|
|
266
|
+
if (!placesApi.AutocompleteSuggestion) {
|
|
267
|
+
throw new Error('Places API not loaded yet. Please wait for component initialisation.');
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Import the geocoding library
|
|
271
|
+
const { Geocoder } = await importLibrary('geocoding');
|
|
272
|
+
const geocoder = new Geocoder();
|
|
273
|
+
|
|
274
|
+
// Perform reverse geocoding
|
|
275
|
+
const response = await geocoder.geocode({
|
|
276
|
+
location: { lat: latitude, lng: longitude }
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
if (!response.results || response.results.length === 0) {
|
|
280
|
+
throw new Error('No place found for the given coordinates.');
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Get the first result (most specific)
|
|
284
|
+
const geocodeResult = response.results[0];
|
|
285
|
+
|
|
286
|
+
// Import the Place class to create a Place object from the place ID
|
|
287
|
+
const { Place } = await importLibrary('places');
|
|
288
|
+
const place = new Place({
|
|
289
|
+
id: geocodeResult.place_id
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
// Fetch the place details with the configured fields
|
|
293
|
+
await place.fetchFields({
|
|
294
|
+
fields: validatedFetchFields
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
// Convert to JSON format
|
|
298
|
+
const placeData = place.toJSON() as PlaceResult;
|
|
299
|
+
|
|
300
|
+
// Reset search input and results
|
|
301
|
+
reset(placeData);
|
|
302
|
+
|
|
303
|
+
// Trigger the onResponse callback
|
|
304
|
+
onResponse(placeData);
|
|
305
|
+
} catch (e: any) {
|
|
306
|
+
// Handle errors
|
|
307
|
+
onError(
|
|
308
|
+
(e.name || 'An error occurred') +
|
|
309
|
+
' - ' +
|
|
310
|
+
(e.message || 'error setting input value from coordinates')
|
|
311
|
+
);
|
|
312
|
+
throw e;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
248
315
|
|
|
249
316
|
/**
|
|
250
317
|
* Extracts a specific address component from the place response.
|
|
@@ -329,7 +396,35 @@
|
|
|
329
396
|
|
|
330
397
|
// Create highlighted segments
|
|
331
398
|
highlightedText = createHighlightedSegments(originalText, matches);
|
|
399
|
+
//console.log(suggestion.placePrediction.types);
|
|
400
|
+
|
|
401
|
+
// Extract the types array for cleaner code
|
|
402
|
+
const types = suggestion.placePrediction.types;
|
|
403
|
+
let placeType = {
|
|
404
|
+
icon: '',
|
|
405
|
+
label: ''
|
|
406
|
+
};
|
|
332
407
|
|
|
408
|
+
if (validatedOptions.show_place_type) {
|
|
409
|
+
if (Array.isArray(types) && types.length > 0) {
|
|
410
|
+
// Look through the array until we find a type we actually recognize
|
|
411
|
+
const matchedType = types.find(
|
|
412
|
+
(type: string) => typeof type === 'string' && type in ITINERARY_CATEGORIES
|
|
413
|
+
);
|
|
414
|
+
|
|
415
|
+
// If we found a match, get its label; otherwise, use 'Default'
|
|
416
|
+
const categoryLabel = matchedType
|
|
417
|
+
? ITINERARY_CATEGORIES[matchedType as keyof typeof ITINERARY_CATEGORIES]
|
|
418
|
+
: 'Default';
|
|
419
|
+
|
|
420
|
+
placeType = {
|
|
421
|
+
icon: ITINERARY_SVG_ICONS[categoryLabel as keyof typeof ITINERARY_SVG_ICONS] || '',
|
|
422
|
+
label: categoryLabel
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// const category = ITINERARY_CATEGORIES[suggestion.placePrediction.placeType] || 'Default';
|
|
333
428
|
results.push({
|
|
334
429
|
place: place,
|
|
335
430
|
mainText: highlightedText,
|
|
@@ -337,7 +432,8 @@
|
|
|
337
432
|
distance: formatDistance(
|
|
338
433
|
suggestion.placePrediction.distanceMeters,
|
|
339
434
|
validatedOptions.distance_units ?? 'km'
|
|
340
|
-
)
|
|
435
|
+
),
|
|
436
|
+
placeType: placeType
|
|
341
437
|
});
|
|
342
438
|
}
|
|
343
439
|
//console.log('Autocomplete suggestions:', results);
|
|
@@ -351,7 +447,9 @@
|
|
|
351
447
|
* The debounce delay is reactive and updates when the validatedOptions.debounce value changes.
|
|
352
448
|
* @private
|
|
353
449
|
*/
|
|
354
|
-
const debouncedMakeAcRequest = $derived(
|
|
450
|
+
const debouncedMakeAcRequest = $derived(
|
|
451
|
+
debounce(makeAcRequest, validatedOptions?.debounce ?? 100)
|
|
452
|
+
);
|
|
355
453
|
|
|
356
454
|
/**
|
|
357
455
|
* Handles the selection of an autocomplete suggestion.
|
|
@@ -366,12 +464,11 @@
|
|
|
366
464
|
toJSON: () => any;
|
|
367
465
|
}): Promise<void> => {
|
|
368
466
|
try {
|
|
369
|
-
// console.log(place);
|
|
370
|
-
// console.log(validatedFetchFields);
|
|
371
467
|
await place.fetchFields({
|
|
372
468
|
fields: validatedFetchFields
|
|
373
469
|
});
|
|
374
|
-
|
|
470
|
+
// return place as json or full place class instance
|
|
471
|
+
let placeData = validatedOptions.response_type === 'json' ? place.toJSON() : place;
|
|
375
472
|
// reset search input and results
|
|
376
473
|
reset(placeData);
|
|
377
474
|
onResponse(placeData);
|
|
@@ -406,7 +503,7 @@
|
|
|
406
503
|
onMount(async (): Promise<void> => {
|
|
407
504
|
if (isDefaultOnResponse) {
|
|
408
505
|
console.warn(
|
|
409
|
-
'PlaceAutocomplete
|
|
506
|
+
'[PlaceAutocomplete] No onResponse callback provided. Place selection events will not be handled. Please provide an onResponse function to handle place selections. See: https://places-autocomplete-svelte.uk/docs'
|
|
410
507
|
);
|
|
411
508
|
}
|
|
412
509
|
if (validatedOptions.autofocus) {
|
|
@@ -593,7 +690,7 @@
|
|
|
593
690
|
stroke-width="2"
|
|
594
691
|
stroke-linecap="round"
|
|
595
692
|
stroke-linejoin="round"
|
|
596
|
-
class="size-5">{@html validatedOptions.classes.map_pin_icon}</svg
|
|
693
|
+
class="size-5 shrink-0">{@html validatedOptions.classes.map_pin_icon}</svg
|
|
597
694
|
>
|
|
598
695
|
{/if}
|
|
599
696
|
|
|
@@ -625,7 +722,7 @@
|
|
|
625
722
|
</div>
|
|
626
723
|
</div>
|
|
627
724
|
</div>
|
|
628
|
-
{#if validatedOptions.distance && p.distance}
|
|
725
|
+
{#if validatedOptions.distance && p.distance && !validatedOptions.show_place_type}
|
|
629
726
|
<div class={[validatedOptions.classes?.li_div_two]}>
|
|
630
727
|
<p
|
|
631
728
|
class={[
|
|
@@ -637,6 +734,33 @@
|
|
|
637
734
|
</p>
|
|
638
735
|
</div>
|
|
639
736
|
{/if}
|
|
737
|
+
{#if validatedOptions.show_place_type && p.placeType && !validatedOptions.distance}
|
|
738
|
+
<div class={[validatedOptions.classes?.li_div_two]}>
|
|
739
|
+
<div
|
|
740
|
+
class={[
|
|
741
|
+
i === currentSuggestion && validatedOptions.classes?.li_current,
|
|
742
|
+
validatedOptions.classes?.li_div_two_p_place_type
|
|
743
|
+
]}
|
|
744
|
+
>
|
|
745
|
+
<div
|
|
746
|
+
class={[
|
|
747
|
+
i === currentSuggestion && validatedOptions.classes?.li_current,
|
|
748
|
+
validatedOptions.classes?.li_div_two_p_place_type_icon
|
|
749
|
+
]}
|
|
750
|
+
>
|
|
751
|
+
{@html p.placeType.icon}
|
|
752
|
+
</div>
|
|
753
|
+
<div
|
|
754
|
+
class={[
|
|
755
|
+
i === currentSuggestion && validatedOptions.classes?.li_current,
|
|
756
|
+
validatedOptions.classes?.li_div_two_p_place_type_label
|
|
757
|
+
]}
|
|
758
|
+
>
|
|
759
|
+
{p.placeType.label}
|
|
760
|
+
</div>
|
|
761
|
+
</div>
|
|
762
|
+
</div>
|
|
763
|
+
{/if}
|
|
640
764
|
</button>
|
|
641
765
|
</li>
|
|
642
766
|
{/each}
|
|
@@ -689,8 +813,8 @@
|
|
|
689
813
|
monospace;
|
|
690
814
|
-webkit-text-size-adjust: 100%;
|
|
691
815
|
-moz-tab-size: 4;
|
|
692
|
-
|
|
693
|
-
|
|
816
|
+
-o-tab-size: 4;
|
|
817
|
+
tab-size: 4;
|
|
694
818
|
line-height: 1.5;
|
|
695
819
|
font-family: var(
|
|
696
820
|
--default-font-family,
|
|
@@ -805,6 +929,13 @@
|
|
|
805
929
|
--default-mono-font-family: var(--font-mono);
|
|
806
930
|
--color-primary-500: #fe795d;
|
|
807
931
|
}
|
|
932
|
+
.size-5 {
|
|
933
|
+
width: 20px;
|
|
934
|
+
height: 20px;
|
|
935
|
+
}
|
|
936
|
+
.shrink-0 {
|
|
937
|
+
flex-shrink: 0;
|
|
938
|
+
}
|
|
808
939
|
.pac-section {
|
|
809
940
|
width: 100%;
|
|
810
941
|
}
|
|
@@ -867,6 +998,11 @@
|
|
|
867
998
|
padding-right: calc(var(--spacing, 0.25rem) * 1.5);
|
|
868
999
|
display: flex;
|
|
869
1000
|
position: absolute;
|
|
1001
|
+
/* max-height: 40px; */
|
|
1002
|
+
align-content: center;
|
|
1003
|
+
align-items: center;
|
|
1004
|
+
flex-wrap: wrap;
|
|
1005
|
+
flex-direction: row;
|
|
870
1006
|
}
|
|
871
1007
|
.pac-kbd-escape {
|
|
872
1008
|
margin-right: calc(var(--spacing, 0.25rem) * 1);
|
|
@@ -995,7 +1131,7 @@
|
|
|
995
1131
|
color: var(--color-gray-900, oklch(21% 0.034 264.665));
|
|
996
1132
|
-webkit-user-select: none;
|
|
997
1133
|
-moz-user-select: none;
|
|
998
|
-
|
|
1134
|
+
user-select: none;
|
|
999
1135
|
}
|
|
1000
1136
|
@media (hover: hover) {
|
|
1001
1137
|
.pac-li:hover {
|
|
@@ -1035,7 +1171,7 @@
|
|
|
1035
1171
|
min-width: calc(var(--spacing, 0.25rem) * 0);
|
|
1036
1172
|
align-items: center;
|
|
1037
1173
|
-moz-column-gap: calc(var(--spacing, 0.25rem) * 3);
|
|
1038
|
-
|
|
1174
|
+
column-gap: calc(var(--spacing, 0.25rem) * 3);
|
|
1039
1175
|
flex: auto;
|
|
1040
1176
|
display: flex;
|
|
1041
1177
|
}
|
|
@@ -1058,6 +1194,7 @@
|
|
|
1058
1194
|
.pac-li-div-one-p-secondaryText {
|
|
1059
1195
|
font-size: var(--text-xs, 0.75rem);
|
|
1060
1196
|
line-height: calc(var(--spacing, 0.25rem) * 4);
|
|
1197
|
+
text-align: left;
|
|
1061
1198
|
}
|
|
1062
1199
|
.pac-li-current {
|
|
1063
1200
|
background-color: var(--color-indigo-500, oklch(58.5% 0.233 277.117));
|
|
@@ -1079,6 +1216,43 @@
|
|
|
1079
1216
|
font-size: var(--text-xs, 0.75rem);
|
|
1080
1217
|
line-height: var(--tw-leading, var(--text-xs--line-height, calc(1 / 0.75)));
|
|
1081
1218
|
}
|
|
1219
|
+
.pac-li-div-two-p-place_type {
|
|
1220
|
+
font-size: var(--text-xs, 0.75rem);
|
|
1221
|
+
line-height: var(--tw-leading, var(--text-xs--line-height, calc(1 / 0.75)));
|
|
1222
|
+
display: flex;
|
|
1223
|
+
flex-direction: row;
|
|
1224
|
+
align-items: center;
|
|
1225
|
+
/* justify-content: space-between; */
|
|
1226
|
+
justify-content: flex-end;
|
|
1227
|
+
width: 100%;
|
|
1228
|
+
/* min-width: 120px; */
|
|
1229
|
+
gap: 0.5rem;
|
|
1230
|
+
}
|
|
1231
|
+
.pac-li-div-two-p-place_type-icon {
|
|
1232
|
+
flex-shrink: 0;
|
|
1233
|
+
}
|
|
1234
|
+
.pac-li-div-two-p-place_type-label {
|
|
1235
|
+
/* text-wrap: left; */
|
|
1236
|
+
display: none;
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
@media (min-width: 48rem) {
|
|
1240
|
+
.pac-li-div-two-p-place_type {
|
|
1241
|
+
font-size: var(--text-xs, 0.75rem);
|
|
1242
|
+
line-height: var(--tw-leading, var(--text-xs--line-height, calc(1 / 0.75)));
|
|
1243
|
+
display: flex;
|
|
1244
|
+
flex-direction: row;
|
|
1245
|
+
align-items: center;
|
|
1246
|
+
justify-content: flex-start;
|
|
1247
|
+
width: 100%;
|
|
1248
|
+
min-width: 120px;
|
|
1249
|
+
gap: 0.5rem;
|
|
1250
|
+
}
|
|
1251
|
+
.pac-li-div-two-p-place_type-label {
|
|
1252
|
+
/* text-wrap: left; */
|
|
1253
|
+
display: inline;
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1082
1256
|
.pac-highlight {
|
|
1083
1257
|
--tw-font-weight: var(--font-weight-bold, 700);
|
|
1084
1258
|
font-weight: var(--font-weight-bold, 700);
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import type { Props } from './interfaces.js';
|
|
1
|
+
import type { PlaceResult, Props } from './interfaces.js';
|
|
2
2
|
declare const PlaceAutocomplete: import("svelte").Component<Props, {
|
|
3
|
+
/**
|
|
4
|
+
* Resets the search input and clears the suggestions list.
|
|
5
|
+
* Optionally populates the input with the formatted address of the selected place.
|
|
6
|
+
* @param {PlaceResult} [placeData] - Optional place data to populate the input field with.
|
|
7
|
+
* @private
|
|
8
|
+
*/ reset: (placeData?: PlaceResult) => void;
|
|
3
9
|
clear: () => void;
|
|
4
10
|
focus: () => void;
|
|
5
11
|
getRequestParams: () => import("./interfaces.js").RequestParams;
|
|
@@ -8,6 +14,7 @@ declare const PlaceAutocomplete: import("svelte").Component<Props, {
|
|
|
8
14
|
getFetchFields: () => string[];
|
|
9
15
|
setOptions: (options: import("./interfaces.js").ComponentOptions) => void;
|
|
10
16
|
getOptions: () => import("./interfaces.js").ComponentOptions;
|
|
17
|
+
setInputValue: (latitude: number, longitude: number) => Promise<void>;
|
|
11
18
|
}, "onResponse" | "onError">;
|
|
12
19
|
type PlaceAutocomplete = ReturnType<typeof PlaceAutocomplete>;
|
|
13
20
|
export default PlaceAutocomplete;
|
package/dist/helpers.d.ts
CHANGED
|
@@ -63,3 +63,114 @@ export declare function createHighlightedSegments(originalText: string, matches:
|
|
|
63
63
|
* @param delay The debounce delay in milliseconds.
|
|
64
64
|
*/
|
|
65
65
|
export declare const debounce: <T extends (...args: any[]) => void>(func: T, delay: number) => (...args: Parameters<T>) => void;
|
|
66
|
+
export declare const ITINERARY_CATEGORIES: {
|
|
67
|
+
car_rental: string;
|
|
68
|
+
car_dealer: string;
|
|
69
|
+
gas_station: string;
|
|
70
|
+
electric_vehicle_charging_station: string;
|
|
71
|
+
parking: string;
|
|
72
|
+
airport: string;
|
|
73
|
+
bus_station: string;
|
|
74
|
+
train_station: string;
|
|
75
|
+
subway_station: string;
|
|
76
|
+
taxi_stand: string;
|
|
77
|
+
ferry_terminal: string;
|
|
78
|
+
restaurant: string;
|
|
79
|
+
cafe: string;
|
|
80
|
+
coffee_shop: string;
|
|
81
|
+
bar: string;
|
|
82
|
+
pub: string;
|
|
83
|
+
night_club: string;
|
|
84
|
+
bakery: string;
|
|
85
|
+
fast_food_restaurant: string;
|
|
86
|
+
ice_cream_shop: string;
|
|
87
|
+
pizza_restaurant: string;
|
|
88
|
+
steak_house: string;
|
|
89
|
+
sushi_restaurant: string;
|
|
90
|
+
hotel: string;
|
|
91
|
+
hostel: string;
|
|
92
|
+
motel: string;
|
|
93
|
+
resort_hotel: string;
|
|
94
|
+
bed_and_breakfast: string;
|
|
95
|
+
campground: string;
|
|
96
|
+
rv_park: string;
|
|
97
|
+
lodging: string;
|
|
98
|
+
cottage: string;
|
|
99
|
+
inn: string;
|
|
100
|
+
guest_house: string;
|
|
101
|
+
tourist_attraction: string;
|
|
102
|
+
museum: string;
|
|
103
|
+
art_gallery: string;
|
|
104
|
+
cultural_landmark: string;
|
|
105
|
+
historical_landmark: string;
|
|
106
|
+
monument: string;
|
|
107
|
+
performing_arts_theater: string;
|
|
108
|
+
aquarium: string;
|
|
109
|
+
zoo: string;
|
|
110
|
+
visitor_center: string;
|
|
111
|
+
town_square: string;
|
|
112
|
+
landmark: string;
|
|
113
|
+
place_of_worship: string;
|
|
114
|
+
park: string;
|
|
115
|
+
national_park: string;
|
|
116
|
+
state_park: string;
|
|
117
|
+
beach: string;
|
|
118
|
+
hiking_area: string;
|
|
119
|
+
amusement_park: string;
|
|
120
|
+
water_park: string;
|
|
121
|
+
botanical_garden: string;
|
|
122
|
+
golf_course: string;
|
|
123
|
+
gym: string;
|
|
124
|
+
natural_feature: string;
|
|
125
|
+
shopping_mall: string;
|
|
126
|
+
supermarket: string;
|
|
127
|
+
grocery_store: string;
|
|
128
|
+
clothing_store: string;
|
|
129
|
+
electronics_store: string;
|
|
130
|
+
souvenir_shop: string;
|
|
131
|
+
gift_shop: string;
|
|
132
|
+
duty_free_store: string;
|
|
133
|
+
hospital: string;
|
|
134
|
+
pharmacy: string;
|
|
135
|
+
atm: string;
|
|
136
|
+
bank: string;
|
|
137
|
+
post_office: string;
|
|
138
|
+
police: string;
|
|
139
|
+
neighborhood: string;
|
|
140
|
+
sublocality: string;
|
|
141
|
+
route: string;
|
|
142
|
+
street_address: string;
|
|
143
|
+
intersection: string;
|
|
144
|
+
locality: string;
|
|
145
|
+
administrative_area_level_4: string;
|
|
146
|
+
country: string;
|
|
147
|
+
administrative_area_level_1: string;
|
|
148
|
+
administrative_area_level_2: string;
|
|
149
|
+
administrative_area_level_3: string;
|
|
150
|
+
administrative_area_level_5: string;
|
|
151
|
+
sublocality_level_1: string;
|
|
152
|
+
sublocality_level_2: string;
|
|
153
|
+
sublocality_level_3: string;
|
|
154
|
+
sublocality_level_4: string;
|
|
155
|
+
sublocality_level_5: string;
|
|
156
|
+
default: string;
|
|
157
|
+
};
|
|
158
|
+
export declare const ITINERARY_SVG_ICONS: {
|
|
159
|
+
Automotive: string;
|
|
160
|
+
Transport: string;
|
|
161
|
+
"Food and Drink": string;
|
|
162
|
+
Lodging: string;
|
|
163
|
+
Sightseeing: string;
|
|
164
|
+
Recreation: string;
|
|
165
|
+
Shopping: string;
|
|
166
|
+
Health: string;
|
|
167
|
+
Finance: string;
|
|
168
|
+
Geographical: string;
|
|
169
|
+
Navigation: string;
|
|
170
|
+
City: string;
|
|
171
|
+
District: string;
|
|
172
|
+
Airport: string;
|
|
173
|
+
"Subway Station": string;
|
|
174
|
+
"Train Station": string;
|
|
175
|
+
Default: string;
|
|
176
|
+
};
|
package/dist/helpers.js
CHANGED
|
@@ -15,7 +15,7 @@ export const requestParamsDefault = {
|
|
|
15
15
|
* https://developers.google.com/maps/documentation/javascript/place-types
|
|
16
16
|
*
|
|
17
17
|
* ['postal_code','premise','street_address','route']
|
|
18
|
-
*
|
|
18
|
+
*
|
|
19
19
|
*/
|
|
20
20
|
//includedPrimaryTypes: ['postal_code','premise','street_address','route'],
|
|
21
21
|
includedPrimaryTypes: [],
|
|
@@ -25,7 +25,7 @@ export const requestParamsDefault = {
|
|
|
25
25
|
* An empty set will not restrict the results.
|
|
26
26
|
* If both locationRestriction and includedRegionCodes are set, the results will be located in the area of intersection.
|
|
27
27
|
*/
|
|
28
|
-
includedRegionCodes: [
|
|
28
|
+
includedRegionCodes: [],
|
|
29
29
|
/**
|
|
30
30
|
* @type number optional
|
|
31
31
|
* A zero-based Unicode character offset of input indicating the cursor position in input.
|
|
@@ -192,9 +192,9 @@ export const validateRequestParams = (requestParams) => {
|
|
|
192
192
|
const validatedParams = {
|
|
193
193
|
input: String(''),
|
|
194
194
|
sessionToken: String(''),
|
|
195
|
-
includedRegionCodes: ['GB'],
|
|
196
|
-
language: 'en-GB',
|
|
197
|
-
region: 'GB',
|
|
195
|
+
//includedRegionCodes: ['GB'],
|
|
196
|
+
//language: 'en-GB',
|
|
197
|
+
//region: 'GB',
|
|
198
198
|
};
|
|
199
199
|
// iterate over requestParams
|
|
200
200
|
for (const key in requestParams) {
|
|
@@ -315,6 +315,9 @@ export const componentClasses = {
|
|
|
315
315
|
li_div_one_p_secondaryText: 'pac-li-div-one-p-secondaryText', //'text-xs text-left leading-2',
|
|
316
316
|
li_div_two: 'pac-li-div-two', //'shrink-0 flex flex-col items-end min-w-16',
|
|
317
317
|
li_div_two_p: 'pac-li-div-two-p', //'mt-1 text-xs/5',
|
|
318
|
+
li_div_two_p_place_type: 'pac-li-div-two-p-place_type',
|
|
319
|
+
li_div_two_p_place_type_icon: 'pac-li-div-two-p-place_type-icon',
|
|
320
|
+
li_div_two_p_place_type_label: 'pac-li-div-two-p-place_type-label',
|
|
318
321
|
highlight: 'pac-highlight', //'font-bold',
|
|
319
322
|
map_pin_icon: '<path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"/><circle cx="12" cy="10" r="3"/>',
|
|
320
323
|
};
|
|
@@ -325,12 +328,16 @@ export const componentOptions = {
|
|
|
325
328
|
autofocus: false,
|
|
326
329
|
autocomplete: 'off',
|
|
327
330
|
placeholder: 'Start typing your address',
|
|
328
|
-
distance:
|
|
331
|
+
distance: false,
|
|
329
332
|
distance_units: 'km',
|
|
330
333
|
classes: componentClasses,
|
|
331
334
|
label: '',
|
|
332
335
|
debounce: 100,
|
|
333
|
-
clear_input: true
|
|
336
|
+
clear_input: true,
|
|
337
|
+
// Return Value: Object a JSON object with all the requested Place properties
|
|
338
|
+
// or as google.maps.places.Place class instance
|
|
339
|
+
response_type: 'json', // 'json' | 'place',
|
|
340
|
+
show_place_type: false, // show place type in the autocomplete suggestions
|
|
334
341
|
};
|
|
335
342
|
/**
|
|
336
343
|
* Validate and cast component options
|
|
@@ -415,3 +422,127 @@ export const debounce = (func, delay) => {
|
|
|
415
422
|
}, delay);
|
|
416
423
|
};
|
|
417
424
|
};
|
|
425
|
+
// Itinerary category mapping
|
|
426
|
+
export const ITINERARY_CATEGORIES = {
|
|
427
|
+
// --- TRANSPORT & AUTO ---
|
|
428
|
+
"car_rental": "Automotive",
|
|
429
|
+
"car_dealer": "Automotive",
|
|
430
|
+
"gas_station": "Automotive",
|
|
431
|
+
"electric_vehicle_charging_station": "Automotive",
|
|
432
|
+
"parking": "Automotive",
|
|
433
|
+
"airport": "Airport",
|
|
434
|
+
"bus_station": "Transport",
|
|
435
|
+
"train_station": "Train Station",
|
|
436
|
+
"subway_station": "Subway Station",
|
|
437
|
+
"taxi_stand": "Transport",
|
|
438
|
+
"ferry_terminal": "Transport",
|
|
439
|
+
// --- DINING & NIGHTLIFE ---
|
|
440
|
+
"restaurant": "Food and Drink",
|
|
441
|
+
"cafe": "Food and Drink",
|
|
442
|
+
"coffee_shop": "Food and Drink",
|
|
443
|
+
"bar": "Food and Drink",
|
|
444
|
+
"pub": "Food and Drink",
|
|
445
|
+
"night_club": "Food and Drink",
|
|
446
|
+
"bakery": "Food and Drink",
|
|
447
|
+
"fast_food_restaurant": "Food and Drink",
|
|
448
|
+
"ice_cream_shop": "Food and Drink",
|
|
449
|
+
"pizza_restaurant": "Food and Drink",
|
|
450
|
+
"steak_house": "Food and Drink",
|
|
451
|
+
"sushi_restaurant": "Food and Drink",
|
|
452
|
+
// --- LODGING ---
|
|
453
|
+
"hotel": "Lodging",
|
|
454
|
+
"hostel": "Lodging",
|
|
455
|
+
"motel": "Lodging",
|
|
456
|
+
"resort_hotel": "Lodging",
|
|
457
|
+
"bed_and_breakfast": "Lodging",
|
|
458
|
+
"campground": "Lodging",
|
|
459
|
+
"rv_park": "Lodging",
|
|
460
|
+
"lodging": "Lodging",
|
|
461
|
+
"cottage": "Lodging",
|
|
462
|
+
"inn": "Lodging",
|
|
463
|
+
"guest_house": "Lodging",
|
|
464
|
+
// --- SIGHTSEEING & CULTURE ---
|
|
465
|
+
"tourist_attraction": "Sightseeing",
|
|
466
|
+
"museum": "Sightseeing",
|
|
467
|
+
"art_gallery": "Sightseeing",
|
|
468
|
+
"cultural_landmark": "Sightseeing",
|
|
469
|
+
"historical_landmark": "Sightseeing",
|
|
470
|
+
"monument": "Sightseeing",
|
|
471
|
+
"performing_arts_theater": "Sightseeing",
|
|
472
|
+
"aquarium": "Sightseeing",
|
|
473
|
+
"zoo": "Sightseeing",
|
|
474
|
+
"visitor_center": "Sightseeing",
|
|
475
|
+
"town_square": "Sightseeing",
|
|
476
|
+
"landmark": "Sightseeing",
|
|
477
|
+
"place_of_worship": "Sightseeing",
|
|
478
|
+
// --- RECREATION & PARKS ---
|
|
479
|
+
"park": "Recreation",
|
|
480
|
+
"national_park": "Recreation",
|
|
481
|
+
"state_park": "Recreation",
|
|
482
|
+
"beach": "Recreation",
|
|
483
|
+
"hiking_area": "Recreation",
|
|
484
|
+
"amusement_park": "Recreation",
|
|
485
|
+
"water_park": "Recreation",
|
|
486
|
+
"botanical_garden": "Recreation",
|
|
487
|
+
"golf_course": "Recreation",
|
|
488
|
+
"gym": "Recreation",
|
|
489
|
+
"natural_feature": "Recreation",
|
|
490
|
+
// --- SHOPPING ---
|
|
491
|
+
"shopping_mall": "Shopping",
|
|
492
|
+
"supermarket": "Shopping",
|
|
493
|
+
"grocery_store": "Shopping",
|
|
494
|
+
"clothing_store": "Shopping",
|
|
495
|
+
"electronics_store": "Shopping",
|
|
496
|
+
"souvenir_shop": "Shopping", // Simplified name
|
|
497
|
+
"gift_shop": "Shopping",
|
|
498
|
+
"duty_free_store": "Shopping",
|
|
499
|
+
// --- ESSENTIAL SERVICES ---
|
|
500
|
+
"hospital": "Health",
|
|
501
|
+
"pharmacy": "Health",
|
|
502
|
+
"atm": "Finance",
|
|
503
|
+
"bank": "Finance",
|
|
504
|
+
"post_office": "Services",
|
|
505
|
+
"police": "Services",
|
|
506
|
+
// --- GEOGRAPHICAL ---
|
|
507
|
+
"neighborhood": "Geographical",
|
|
508
|
+
"sublocality": "Geographical",
|
|
509
|
+
// --- NAVIGATION ---
|
|
510
|
+
"route": "Navigation",
|
|
511
|
+
"street_address": "Navigation",
|
|
512
|
+
"intersection": "Navigation",
|
|
513
|
+
// -- CITY --
|
|
514
|
+
'locality': 'City',
|
|
515
|
+
'administrative_area_level_4': 'City',
|
|
516
|
+
'country': 'Country',
|
|
517
|
+
'administrative_area_level_1': 'City',
|
|
518
|
+
'administrative_area_level_2': 'City',
|
|
519
|
+
'administrative_area_level_3': 'City',
|
|
520
|
+
'administrative_area_level_5': 'City',
|
|
521
|
+
'sublocality_level_1': 'Neighborhood',
|
|
522
|
+
'sublocality_level_2': 'Neighborhood',
|
|
523
|
+
'sublocality_level_3': 'Neighborhood',
|
|
524
|
+
'sublocality_level_4': 'Neighborhood',
|
|
525
|
+
'sublocality_level_5': 'Neighborhood',
|
|
526
|
+
// --- DEFAULT ---
|
|
527
|
+
"default": "Default"
|
|
528
|
+
};
|
|
529
|
+
// Itinerary category SVG icons
|
|
530
|
+
export const ITINERARY_SVG_ICONS = {
|
|
531
|
+
"Automotive": `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" style="display:inline-block"; viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 17h2c.6 0 1-.4 1-1v-3c0-.9-.7-1.7-1.5-1.9C18.7 10.6 16 10 16 10s-1.3-1.4-2.2-2.3c-.5-.4-1.1-.7-1.8-.7H5c-.6 0-1.1.4-1.4.9l-1.4 2.9A3.7 3.7 0 0 0 2 12v4c0 .6.4 1 1 1h2"/><circle cx="7" cy="17" r="2"/><path d="M9 17h6"/><circle cx="17" cy="17" r="2"/></svg>`,
|
|
532
|
+
"Transport": `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" style="display:inline-block"; viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17.8 19.2 16 11l3.5-3.5C21 6 21.5 4 21 3c-1-.5-3 0-4.5 1.5L13 8 4.8 6.2c-.5-.1-.9.1-1.1.5l-.3.5c-.2.5-.1 1 .3 1.3L9 12l-2 3H4l-1 1 3 2 2 3 1-1v-3l3-2 3.5 5.3c.3.4.8.5 1.3.3l.5-.2c.4-.3.6-.7.5-1.2z"/></svg>`,
|
|
533
|
+
"Food and Drink": `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" style="display:inline-block"; viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 2v7c0 1.1.9 2 2 2h4a2 2 0 0 0 2-2V2"/><path d="M7 2v20"/><path d="M21 15V2v0a5 5 0 0 0-5 5v6c0 1.1.9 2 2 2h3Zm0 0v7"/></svg>`,
|
|
534
|
+
"Lodging": `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" style="display:inline-block"; viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 4v16"/><path d="M2 8h18a2 2 0 0 1 2 2v10"/><path d="M2 17h20"/><path d="M6 8v9"/></svg>`,
|
|
535
|
+
"Sightseeing": `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" style="display:inline-block"; viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-binoculars-icon lucide-binoculars"><path d="M10 10h4"/><path d="M19 7V4a1 1 0 0 0-1-1h-2a1 1 0 0 0-1 1v3"/><path d="M20 21a2 2 0 0 0 2-2v-3.851c0-1.39-2-2.962-2-4.829V8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v11a2 2 0 0 0 2 2z"/><path d="M 22 16 L 2 16"/><path d="M4 21a2 2 0 0 1-2-2v-3.851c0-1.39 2-2.962 2-4.829V8a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v11a2 2 0 0 1-2 2z"/><path d="M9 7V4a1 1 0 0 0-1-1H6a1 1 0 0 0-1 1v3"/></svg>`,
|
|
536
|
+
"Recreation": `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" style="display:inline-block"; viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-kayak-icon lucide-kayak"><path d="M18 17a1 1 0 0 0-1 1v1a2 2 0 1 0 2-2z"/><path d="M20.97 3.61a.45.45 0 0 0-.58-.58C10.2 6.6 6.6 10.2 3.03 20.39a.45.45 0 0 0 .58.58C13.8 17.4 17.4 13.8 20.97 3.61"/><path d="m6.707 6.707 10.586 10.586"/><path d="M7 5a2 2 0 1 0-2 2h1a1 1 0 0 0 1-1z"/></svg>`,
|
|
537
|
+
"Shopping": `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" style="display:inline-block"; viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4Z"/><path d="M3 6h18"/><path d="M16 10a4 4 0 0 1-8 0"/></svg>`,
|
|
538
|
+
"Health": `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" style="display:inline-block"; viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 7v4"/><path d="M14 21v-3a2 2 0 0 0-4 0v3"/><path d="M14 9h-4"/><path d="M18 11h2a2 2 0 0 1 2 2v6a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-9a2 2 0 0 1 2-2h2"/><path d="M18 21V5a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v16"/></svg>`,
|
|
539
|
+
"Finance": `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" style="display:inline-block"; viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="14" x="2" y="5" rx="2"/><line x1="2" y1="10" x2="22" y2="10"/></svg>`,
|
|
540
|
+
"Geographical": `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" style="display:inline-block"; viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m20 20-6-10.6c-.4-.7-1.5-.7-1.9 0L6 20"/><path d="M7 16h10"/><path d="M12 4a8 8 0 0 1 8 8v2a2 2 0 0 1-2 2h-1"/><path d="M7 16H6a2 2 0 0 1-2-2v-2a8 8 0 0 1 8-8"/></svg>`,
|
|
541
|
+
"Navigation": `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" style="display:inline-block"; viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-navigation-icon lucide-navigation"><polygon points="3 11 22 2 13 21 11 13 3 11"/></svg>`,
|
|
542
|
+
"City": `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" style="display:inline-block"; viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-building2-icon lucide-building-2"><path d="M10 12h4"/><path d="M10 8h4"/><path d="M14 21v-3a2 2 0 0 0-4 0v3"/><path d="M6 10H4a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-2"/><path d="M6 21V5a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v16"/></svg>`,
|
|
543
|
+
"District": `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" style="display:inline-block"; viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-land-plot-icon lucide-land-plot"><path d="m12 8 6-3-6-3v10"/><path d="m8 11.99-5.5 3.14a1 1 0 0 0 0 1.74l8.5 4.86a2 2 0 0 0 2 0l8.5-4.86a1 1 0 0 0 0-1.74L16 12"/><path d="m6.49 12.85 11.02 6.3"/><path d="M17.51 12.85 6.5 19.15"/></svg>`,
|
|
544
|
+
"Airport": `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" style="display:inline-block"; viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-plane-icon lucide-plane"><path d="M17.8 19.2 16 11l3.5-3.5C21 6 21.5 4 21 3c-1-.5-3 0-4.5 1.5L13 8 4.8 6.2c-.5-.1-.9.1-1.1.5l-.3.5c-.2.5-.1 1 .3 1.3L9 12l-2 3H4l-1 1 3 2 2 3 1-1v-3l3-2 3.5 5.3c.3.4.8.5 1.3.3l.5-.2c.4-.3.6-.7.5-1.2z"/></svg>`,
|
|
545
|
+
"Subway Station": `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" style="display:inline-block"; viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-subway-icon lucide-subway"><path d="M12 22a10 10 0 0 0 10-10V8l-5-5H7L2 8v4a10 10 0 0 0 10 10Z"/><path d="M12 22V8"/><path d="M7 13h10"/><path d="M7 17h10"/></svg>`,
|
|
546
|
+
"Train Station": `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" style="display:inline-block"; viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-train-icon lucide-train"><path d="M2 10h20"/><path d="M2 10a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-5Z"/><circle cx="7" cy="15" r="2"/><circle cx="17" cy="15" r="2"/></svg>`,
|
|
547
|
+
"Default": `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" style="display:inline-block"; viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"/><circle cx="12" cy="10" r="3"/></svg>`
|
|
548
|
+
};
|
package/dist/interfaces.d.ts
CHANGED
|
@@ -64,7 +64,7 @@ export interface ComponentClasses {
|
|
|
64
64
|
* Controls browser autofill behavior for the input field.
|
|
65
65
|
* @type {"on" | "off"}
|
|
66
66
|
*/
|
|
67
|
-
export type AutoFill = "on" | "off" |
|
|
67
|
+
export type AutoFill = "on" | "off" | "new-password";
|
|
68
68
|
/**
|
|
69
69
|
* Distance measurement units for displaying place distances.
|
|
70
70
|
* @type {"km" | "miles"}
|
|
@@ -93,6 +93,28 @@ export interface ComponentOptions {
|
|
|
93
93
|
debounce?: number;
|
|
94
94
|
/** Clear the input field after selecting a place. @default true */
|
|
95
95
|
clear_input?: boolean;
|
|
96
|
+
/** Format of the place data returned in onResponse callback. @default "json" */
|
|
97
|
+
response_type?: 'json' | 'object';
|
|
98
|
+
/** Show the place type in the autocomplete suggestions. @default false */
|
|
99
|
+
show_place_type?: boolean;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Photo Class
|
|
103
|
+
*/
|
|
104
|
+
export interface Photo {
|
|
105
|
+
authorAttributions?: {
|
|
106
|
+
displayName?: string;
|
|
107
|
+
uri?: string;
|
|
108
|
+
photoURI?: string;
|
|
109
|
+
}[];
|
|
110
|
+
flagContentURI?: string;
|
|
111
|
+
googleMapsURI?: string;
|
|
112
|
+
heightPx?: number;
|
|
113
|
+
widthPx?: number;
|
|
114
|
+
getURI(options?: {
|
|
115
|
+
maxHeight?: number;
|
|
116
|
+
maxWidth?: number;
|
|
117
|
+
}): string;
|
|
96
118
|
}
|
|
97
119
|
/**
|
|
98
120
|
* Detailed information about a selected place returned by the Google Places API.
|
|
@@ -121,6 +143,17 @@ export interface PlaceResult {
|
|
|
121
143
|
lat: number;
|
|
122
144
|
lng: number;
|
|
123
145
|
};
|
|
146
|
+
photos?: Photo[];
|
|
147
|
+
/**
|
|
148
|
+
* Returns the URL of the photo with the specified options.
|
|
149
|
+
* @param options - Options for the photo URL.
|
|
150
|
+
* @returns The URL of the photo.
|
|
151
|
+
*/
|
|
152
|
+
getURI(options?: {
|
|
153
|
+
maxHeight?: number;
|
|
154
|
+
maxWidth?: number;
|
|
155
|
+
}): string;
|
|
156
|
+
toJSON(): PlaceResult;
|
|
124
157
|
/** Additional place data fields as requested via fetchFields prop (e.g., displayName, types, photos). */
|
|
125
158
|
[key: string]: unknown;
|
|
126
159
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "places-autocomplete-svelte",
|
|
3
3
|
"license": "MIT",
|
|
4
|
-
"version": "2.2.
|
|
4
|
+
"version": "2.2.24",
|
|
5
5
|
"description": "A flexible, accessible, and secure Svelte component leveraging the Google Maps Places Autocomplete API (New). Winner of the Google Maps Platform Awards 2025, recognising excellence in Google Maps Platform development.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"svelte",
|
|
@@ -76,8 +76,8 @@
|
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
78
78
|
"@sveltejs/adapter-auto": "^7.0.0",
|
|
79
|
-
"@sveltejs/adapter-cloudflare": "^7.2.
|
|
80
|
-
"@sveltejs/kit": "^2.
|
|
79
|
+
"@sveltejs/adapter-cloudflare": "^7.2.6",
|
|
80
|
+
"@sveltejs/kit": "^2.50.2",
|
|
81
81
|
"@sveltejs/package": "^2.5.7",
|
|
82
82
|
"@sveltejs/vite-plugin-svelte": "^6.2.4",
|
|
83
83
|
"@tailwindcss/postcss": "^4.1.18",
|
|
@@ -85,23 +85,24 @@
|
|
|
85
85
|
"@tailwindcss/vite": "^4.1.18",
|
|
86
86
|
"@types/eslint": "^9.6.1",
|
|
87
87
|
"@types/google.maps": "^3.58.1",
|
|
88
|
-
"@types/node": "^25.0
|
|
89
|
-
"autoprefixer": "^10.4.
|
|
88
|
+
"@types/node": "^25.2.0",
|
|
89
|
+
"autoprefixer": "^10.4.24",
|
|
90
90
|
"eslint": "^9.39.2",
|
|
91
91
|
"eslint-config-prettier": "^10.1.8",
|
|
92
92
|
"eslint-plugin-svelte": "^3.14.0",
|
|
93
|
-
"globals": "^17.
|
|
93
|
+
"globals": "^17.3.0",
|
|
94
94
|
"postcss": "^8.5.6",
|
|
95
|
-
"prettier": "^3.
|
|
95
|
+
"prettier": "^3.8.1",
|
|
96
96
|
"prettier-plugin-svelte": "^3.4.1",
|
|
97
|
-
"publint": "^0.3.
|
|
98
|
-
"svelte": "^5.
|
|
99
|
-
"svelte-check": "^4.3.
|
|
97
|
+
"publint": "^0.3.17",
|
|
98
|
+
"svelte": "^5.49.1",
|
|
99
|
+
"svelte-check": "^4.3.6",
|
|
100
100
|
"tailwindcss": "^4.1.18",
|
|
101
101
|
"tslib": "^2.8.1",
|
|
102
102
|
"typescript": "^5.9.3",
|
|
103
|
-
"typescript-eslint": "^8.
|
|
104
|
-
"vite": "^7.3.1"
|
|
103
|
+
"typescript-eslint": "^8.54.0",
|
|
104
|
+
"vite": "^7.3.1",
|
|
105
|
+
"vitest": "^4.0.18"
|
|
105
106
|
},
|
|
106
107
|
"svelte": "./dist/index.js",
|
|
107
108
|
"types": "./dist/PlaceAutocomplete.svelte.d.ts",
|