places-autocomplete-svelte 2.2.20 β†’ 2.2.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,47 +2,87 @@
2
2
 
3
3
  [![npm version](https://badge.fury.io/js/places-autocomplete-svelte.svg)](https://badge.fury.io/js/places-autocomplete-svelte)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![Google Maps Platform Awards 2025](https://img.shields.io/badge/Google%20Maps%20Platform-Awards%202025%20Winner-4285F4?style=flat&logo=google-maps&logoColor=white)](https://mapsplatform.google.com/awards/)
5
6
 
6
- A flexible, accessible, and secure [Svelte](https://kit.svelte.dev) component leveraging the [Google Maps Places Autocomplete API (New)](https://developers.google.com/maps/documentation/javascript/place-autocomplete-overview).
7
+ A flexible, accessible, and secure [Svelte](https://kit.svelte.dev) component leveraging the [Google Maps Places Autocomplete API (New)](https://developers.google.com/maps/documentation/javascript/place-autocomplete-overview). **Winner of the Google Maps Platform Awards 2025**, recognising excellence in Google Maps Platform development.
7
8
 
8
9
  The component handles API loading, session tokens, debounced fetching, and accessibility, allowing you to focus on building your application. It intelligently manages the Google Maps API loader, creating a shared instance via Svelte's context that prevents conflicts with other map components on the same page.
9
10
 
10
11
  **Two initialisation patterns:**
11
12
  - **Simple/Automatic**: Pass your API key directly to the component for basic use cases
12
- - **Advanced/Manual**: Initialise the loader once in a parent component when using multiple Google Maps libraries or components
13
-
14
- ## Available: Standalone JavaScript Library
15
-
16
- Need this functionality for a non-Svelte project? Check out our companion vanilla JavaScript library, `places-autocomplete-js`, which offers the same core Google Places (New) Autocomplete features.
17
- [View `places-autocomplete-js` on GitHub](https://github.com/alexpechkarev/places-autocomplete-js)
13
+ - **Advanced/Manual**: Initialise the loader once in a parent component when using multiple Google Maps libraries or components
14
+
15
+ ## Table of Contents
16
+
17
+ - [Features](#features)
18
+ - [Demo](#demo)
19
+ - [Recognition](#recognition)
20
+ - [Requirements](#requirements)
21
+ - [Installation](#installation)
22
+ - [Usage](#usage)
23
+ - [Basic Usage](#basic-usage-automatic-initialisation)
24
+ - [Advanced Usage](#advanced-usage-manual-initialisation)
25
+ - [Props](#props)
26
+ - [Component Methods](#component-methods-imperative-api)
27
+ - [Options](#options)
28
+ - [Styling](#styling)
29
+ - [Events](#events)
30
+ - [TypeScript](#typescript)
31
+ - [Security](#security)
32
+ - [Accessibility](#accessibility)
33
+ - [Google Places API & Billing](#google-places-api--billing)
34
+ - [Standalone JavaScript Library](#standalone-javascript-library)
35
+ - [Contributing](#contributing)
36
+ - [License](#license)
18
37
 
19
38
  ## Features
20
39
 
21
- * Integrates with the modern **Google Maps Places Autocomplete API (New)**.
22
- * **Automatic Shared Loader:** Intelligently creates a single Google Maps loader instance and shares it via Svelte's context.
23
- * **Highly Accessible:** Follows WAI-ARIA patterns for comboboxes, with full keyboard navigation and screen reader support.
24
- * **Secure:** Safely renders suggestions to protect against XSS attacks.
25
- * Automatically handles **session tokens** for cost management.
26
- * **Debounced Input:** Limits API calls while the user is typing (configurable).
27
- * **Suggestion Highlighting:** Automatically highlights the portion of text matching the user's input.
28
- * **Imperative API:** Exposes `clear()`, `focus()`, and `getRequestParams()` methods for direct control.
29
- * **Customisable Styling:** Easily override default styles using the `options.classes` prop.
30
- * **TypeScript Support:** Fully written in TypeScript with included type definitions.
31
- * **Event Handling:** Provides `onResponse` and `onError` callbacks.
40
+ ### Core Functionality
41
+ * πŸ—ΊοΈ Integrates with the modern **Google Maps Places Autocomplete API (New)**
42
+ * πŸ”„ **Automatic Shared Loader:** Intelligently creates a single Google Maps loader instance and shares it via Svelte's context
43
+ * πŸ’° Automatically handles **session tokens** for optimal cost management
44
+ * ⚑ **Debounced Input:** Configurable delay to minimise API calls while typing
45
+ * ✨ **Suggestion Highlighting:** Automatically highlights matched text in suggestions
46
+
47
+ ### Accessibility & User Experience
48
+ * β™Ώ **WCAG Compliant:** Follows WAI-ARIA patterns for comboboxes
49
+ * ⌨️ **Full Keyboard Navigation:** Arrow keys, Enter, and Escape support
50
+ * πŸ“’ **Screen Reader Support:** Proper ARIA attributes for assistive technologies
51
+
52
+ ### Developer Experience
53
+ * 🎨 **Customisable Styling:** Override default styles via `options.classes` prop
54
+ * πŸ”§ **Imperative API:** Direct control with `clear()`, `focus()`, `getRequestParams()`, `setRequestParams()`, `setFetchFields()`, and `getFetchFields()` methods
55
+ * πŸ“˜ **TypeScript Support:** Fully typed with comprehensive type definitions
56
+ * πŸ” **Secure:** XSS protection with safe rendering of suggestions
57
+ * 🎯 **Event Handling:** `onResponse` and `onError` callbacks for complete control
32
58
 
33
59
  ## Demo
34
60
 
35
- See a live demo of the component in action: [Basic Example](https://places-autocomplete-demo.pages.dev/)
61
+ Explore live examples showcasing different features and use cases:
62
+
63
+ **[πŸš€ Basic Example](https://places-autocomplete-demo.pages.dev/)** - Get started with the simplest implementation
36
64
 
37
- [Reactive parameters](https://places-autocomplete-demo.pages.dev/examples/reactive-parameters) - change the search criteria based on user input, like filtering by country or change results language.
65
+ **[πŸ”„ Reactive Parameters](https://places-autocomplete-demo.pages.dev/examples/reactive-parameters)** - Dynamically change search criteria based on user input, such as filtering by country or switching languages
38
66
 
39
- [Customise request parameters](https://places-autocomplete-demo.pages.dev/examples/customise-request-parameters) - construct a `requestParams` object and control various aspects of the search, including language, region, and more.
67
+ **[βš™οΈ Custom Request Parameters](https://places-autocomplete-demo.pages.dev/examples/customise-request-parameters)** - Configure advanced search options including language, region, location bias, and place types
40
68
 
41
- [Retain Input Value After Selection](https://places-autocomplete-demo.pages.dev/examples/retain-input-value) -
42
- This example demonstrates how to configure the component to keep the selected address visible in the input field after a suggestion is chosen.
69
+ **[πŸ“ Retain Input Value](https://places-autocomplete-demo.pages.dev/examples/retain-input-value)** - Keep the selected address visible in the input field after selection
43
70
 
44
71
  <img src="places-autocomplete-svelte.gif" alt="A video demonstrating the Places Autocomplete Svelte component in action, showing address suggestions and selection.">
45
72
 
73
+ ## Recognition
74
+
75
+ ### πŸ† Google Maps Platform Awards 2025 Winner
76
+ <p align="left">
77
+ <a href="https://mapsplatform.google.com/awards/">
78
+ <img src="badge.svg" alt="Google Maps Platform Awards 2025 Winner" width="200">
79
+ </a>
80
+ </p>
81
+
82
+ This component has been recognised as a winner of the **Google Maps Platform Awards 2025** by the Google Developer Program. This award celebrates outstanding projects that demonstrate exceptional use of Google Maps Platform APIs, innovation, and contribution to the developer community.
83
+
84
+ [Learn more about the Google Maps Platform Awards](https://developers.google.com/maps)
85
+
46
86
  ## Requirements
47
87
 
48
88
  * **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.
@@ -88,18 +128,19 @@ For simple use cases, just pass your API key to the component. It will automatic
88
128
 
89
129
  ### Advanced Usage (Manual Initialisation)
90
130
 
91
- For applications that need multiple Google Maps libraries (e.g., `places`, `maps`, `marker`) or multiple map components, initialise the loader once in a parent component. This approach:
131
+ For applications using multiple Google Maps libraries (e.g., `places`, `maps`, `marker`) or multiple map components, initialise the loader once in a parent component.
92
132
 
93
- - Loads all required libraries in a single API call (more efficient)
94
- - Prevents "Loader must not be called again" errors
95
- - Shares the loader instance across all child components via Svelte context
96
- - Works seamlessly with SvelteKit's SSR (only initialises in the browser)
133
+ **Benefits:**
134
+ - βœ… Loads all required libraries in a single API call (more efficient)
135
+ - βœ… Prevents "Loader must not be called again" errors
136
+ - βœ… Shares the loader instance across all child components via Svelte context
137
+ - βœ… Works seamlessly with SvelteKit's SSR (only initialises in the browser)
97
138
 
98
139
  **When to use manual initialisation:**
99
- - Using multiple Google Maps components on the same page
100
- - Need to load multiple libraries (`maps`, `marker`, `geometry`, etc.)
101
- - Building a layout that shares map functionality across routes
102
- - Want centralised error handling for the loader
140
+ - Multiple Google Maps components on the same page
141
+ - Multiple libraries needed (`maps`, `marker`, `geometry`, etc.)
142
+ - Shared map functionality across routes
143
+ - Centralised error handling for the loader
103
144
 
104
145
  ```javascript
105
146
  // In +layout.svelte or +page.svelte
@@ -108,6 +149,7 @@ For applications that need multiple Google Maps libraries (e.g., `places`, `maps
108
149
  import { PlaceAutocomplete } from 'places-autocomplete-svelte';
109
150
  import { setGMapsContext, initialiseGMaps, importLibrary } from 'places-autocomplete-svelte/gmaps';
110
151
  import { onMount } from 'svelte';
152
+ import type { PlaceResult } from 'places-autocomplete-svelte/interfaces';
111
153
 
112
154
  // 1. Set the context at the top level (must be synchronous)
113
155
  setGMapsContext();
@@ -127,8 +169,6 @@ For applications that need multiple Google Maps libraries (e.g., `places`, `maps
127
169
 
128
170
  onMount(async () => {
129
171
  const { Map } = await importLibrary('maps');
130
- const { AdvancedMarkerElement } = await importLibrary('marker');
131
-
132
172
  const mapElement = document.getElementById('map');
133
173
  if (mapElement) {
134
174
  map = new Map(mapElement, {
@@ -142,7 +182,6 @@ For applications that need multiple Google Maps libraries (e.g., `places`, `maps
142
182
  // 4. Handle autocomplete responses
143
183
  const handleResponse = (response: PlaceResult) => {
144
184
  console.log('Selected:', response.formattedAddress);
145
- // Update map with selected location
146
185
  if (response.location && map) {
147
186
  map.setCenter(response.location);
148
187
  map.setZoom(15);
@@ -225,6 +264,12 @@ Get a reference to the component instance using `bind:this` to call its methods
225
264
 
226
265
  <button onclick={() => autocompleteComponent?.clear()}>Clear</button>
227
266
  <button onclick={() => autocompleteComponent?.focus()}>Focus</button>
267
+ <button onclick={() => autocompleteComponent?.setRequestParams({ region: 'FR', language: 'fr' })}>
268
+ Switch to French
269
+ </button>
270
+ <button onclick={() => autocompleteComponent?.setOptions({ placeholder: 'Search locations...', debounce: 300 })}>
271
+ Update Options
272
+ </button>
228
273
  ```
229
274
 
230
275
  | Method | Signature | Description |
@@ -232,6 +277,11 @@ Get a reference to the component instance using `bind:this` to call its methods
232
277
  | `clear()` | `() => void` | Clears the input, removes suggestions, and resets the session token. |
233
278
  | `focus()` | `() => void` | Sets focus on the text input field. |
234
279
  | `getRequestParams()` | `() => RequestParams` | Returns the current internal `requestParams` object. |
280
+ | `setRequestParams(params)` | `(params: Partial<RequestParams>) => void` | Dynamically updates request parameters. Useful for changing search criteria (region, language, location bias, etc.). Parameters are merged with existing ones. |
281
+ | `setFetchFields(fields)` | `(fields: string[]) => void` | Dynamically updates the Place Data Fields to fetch when a place is selected. |
282
+ | `getFetchFields()` | `() => string[]` | Returns the current array of Place Data Fields that will be requested. |
283
+ | `setOptions(options)` | `(options: Partial<ComponentOptions>) => void` | Dynamically updates the component's configuration options. Merges the provided options with existing settings. |
284
+ | `getOptions()` | `() => ComponentOptions` | Returns the current validated options used by the component. Useful for inspecting configuration settings. |
235
285
 
236
286
  ## Options
237
287
 
@@ -247,41 +297,82 @@ Get a reference to the component instance using `bind:this` to call its methods
247
297
  | `classes` | `Partial<ComponentClasses>` | `{}` | Object to override default CSS classes. See Styling section. |
248
298
  | `clear_input` | `boolean` | `true` | If `false`, retains the `formattedAddress` in the input after selection. |
249
299
 
250
- ## Styling (`options.classes`)
300
+ ## Styling
251
301
 
252
- Customise the component by providing your own CSS classes via `options.classes`.
302
+ ### Default Styles
253
303
 
254
- **Available Class Keys:**
304
+ The component includes built-in styles with `.pac-` prefixed CSS classes, providing a complete, accessible UI out of the box. These styles are:
255
305
 
256
- * `section`: The main container `section`.
257
- * `container`: The `div` containing the input and suggestions list.
258
- * `label`: The `label` element.
259
- * `input`: The main text `input` element.
260
- * `icon_container`: Container for the optional icon.
261
- * `icon`: SVG string for the icon.
262
- * `ul`: The `<ul>` element for the suggestions list.
263
- * `li`: Each `<li>` suggestion item.
264
- * `li_current`: Class added to the currently highlighted `<li>`.
265
- * `li_div_container`: Container `div` within each list item.
266
- * `li_div_one`: First inner `div` (contains the main text).
267
- * `li_div_one_p`: The `<p>` tag containing the main suggestion text.
268
- * `li_div_two`: Second inner `div` (contains the distance).
269
- * `li_div_two_p`: The `<p>` tag containing the distance text.
270
- * `kbd_container`: Container for the keyboard hint keys.
271
- * `kbd_escape`: The `<kbd>` tag for the 'Esc' hint.
272
- * `kbd_up`: The `<kbd>` tag for the 'Up Arrow' hint.
273
- * `kbd_down`: The `<kbd>` tag for the 'Down Arrow' hint.
274
- * `highlight`: The class applied to the `<span>` wrapping the matched text. Defaults to `'font-bold'`.
306
+ * **Framework-agnostic**: Pure CSS with no dependencies on Tailwind or other frameworks
307
+ * **Modern design**: Clean, professional appearance with proper spacing, shadows, and hover effects
308
+ * **Fully functional**: Includes keyboard navigation indicators, loading states, and responsive behavior
309
+ * **Customisable**: All styles can be overridden via the `options.classes` prop
275
310
 
276
- **Example:**
311
+ The default styles include:
312
+ - Rounded input with shadow and focus states
313
+ - Dropdown list with scroll behavior and dividers
314
+ - Keyboard navigation hints (Esc, ↑, ↓)
315
+ - Highlighted current selection with color transitions
316
+ - Distance display for location-based results
317
+ - Icon support with proper alignment
318
+ - Responsive layout for mobile and desktop
319
+
320
+ ### Customisation (`options.classes`)
321
+
322
+ Override any default styling by providing your own CSS classes via `options.classes`. Your custom classes will replace the default `.pac-` classes for the specified elements.
323
+
324
+ **Available Class Keys:**
325
+
326
+ * `section`: The main container `section` (default: `.pac-section`)
327
+ * `container`: The `div` containing the input and suggestions list (default: `.pac-container`)
328
+ * `label`: The `label` element
329
+ * `input`: The main text `input` element (default: `.pac-input`)
330
+ * `icon_container`: Container for the optional icon (default: `.pac-icon-container`)
331
+ * `icon`: SVG string for the icon
332
+ * `ul`: The `<ul>` element for the suggestions list (default: `.pac-ul`)
333
+ * `li`: Each `<li>` suggestion item (default: `.pac-li`)
334
+ * `li_current`: Class added to the currently highlighted `<li>` (default: `.pac-li-current`)
335
+ * `li_button`: The `<button>` within each list item (default: `.pac-li-button`)
336
+ * `li_button_current`: Class added to the currently highlighted button (default: `.pac-li-button-current`)
337
+ * `li_div_container`: Container `div` within each list item (default: `.pac-li-div-container`)
338
+ * `li_div_one`: First inner `div` containing the main text (default: `.pac-li-div-one`)
339
+ * `li_div_one_p`: The `<p>` tag containing the main suggestion text (default: `.pac-li-div-one-p`)
340
+ * `li_div_one_p_secondaryText`: The `<p>` tag for secondary text (default: `.pac-li-div-one-p-secondaryText`)
341
+ * `li_div_p_container`: Container for paragraphs (default: `.pac-li-div-p-container`)
342
+ * `li_div_two`: Second inner `div` containing the distance (default: `.pac-li-div-two`)
343
+ * `li_div_two_p`: The `<p>` tag containing the distance text (default: `.pac-li-div-two-p`)
344
+ * `kbd_container`: Container for the keyboard hint keys (default: `.pac-kbd-container`)
345
+ * `kbd_escape`: The `<kbd>` tag for the 'Esc' hint (default: `.pac-kbd-escape`)
346
+ * `kbd_up`: The `<kbd>` tag for the 'Up Arrow' hint (default: `.pac-kbd-up`)
347
+ * `kbd_down`: The `<kbd>` tag for the 'Down Arrow' hint (default: `.pac-kbd-down`)
348
+ * `kbd_active`: Class applied to active keyboard hints (default: `.pac-kbd-active`)
349
+ * `map_pin_icon`: SVG string for the map pin icon
350
+ * `highlight`: The class applied to the `<span>` wrapping the matched text (default: `.pac-highlight`)
351
+
352
+ **Example - Using with Tailwind CSS:**
277
353
 
278
354
  ```javascript
279
355
  const options = {
280
356
  classes: {
281
- input: 'form-input w-full rounded-md shadow-sm',
282
- ul: 'absolute bg-white shadow-lg rounded-md mt-1 w-full z-10',
357
+ input: 'w-full px-4 py-2.5 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500',
358
+ ul: 'absolute mt-1 w-full bg-white shadow-lg rounded-md border border-gray-200 max-h-60 overflow-auto',
359
+ li: 'px-4 py-2 hover:bg-blue-500 hover:text-white cursor-pointer',
283
360
  li_current: 'bg-blue-500 text-white',
284
- highlight: 'text-blue-700 font-semibold'
361
+ highlight: 'font-semibold text-blue-700'
362
+ }
363
+ };
364
+ ```
365
+
366
+ **Example - Using with Custom CSS:**
367
+
368
+ ```javascript
369
+ const options = {
370
+ classes: {
371
+ section: 'autocomplete-wrapper',
372
+ input: 'search-input',
373
+ ul: 'suggestions-list',
374
+ li: 'suggestion-item',
375
+ li_current: 'suggestion-item--active'
285
376
  }
286
377
  };
287
378
  ```
@@ -295,47 +386,79 @@ const options = {
295
386
 
296
387
  ## TypeScript
297
388
 
298
- This component is written in TypeScript with full type definitions included.
389
+ This component is fully written in TypeScript with comprehensive type definitions.
299
390
 
300
- **Available imports:**
391
+ ### Available Imports
301
392
 
393
+ **Component:**
302
394
  ```typescript
303
- // Component
304
395
  import { PlaceAutocomplete } from 'places-autocomplete-svelte';
396
+ ```
305
397
 
306
- // Types and interfaces
398
+ **Types and Interfaces:**
399
+ ```typescript
307
400
  import type {
308
- PlaceResult,
309
- ComponentOptions,
310
- RequestParams,
311
- FormattedAddress,
312
- ComponentClasses,
313
- Props
401
+ PlaceResult, // Place data returned from API
402
+ ComponentOptions, // UI and behavior configuration
403
+ RequestParams, // Autocomplete request parameters
404
+ FormattedAddress, // Standardised address structure
405
+ ComponentClasses, // CSS class overrides
406
+ Props // Component props
314
407
  } from 'places-autocomplete-svelte/interfaces';
408
+ ```
315
409
 
316
- // Google Maps loader helpers
410
+ **Google Maps Loader Helpers:**
411
+ ```typescript
317
412
  import {
318
- setGMapsContext,
319
- getGMapsContext,
320
- hasGMapsContext,
321
- initialiseGMaps,
322
- initialiseGMapsNoContext,
323
- importLibrary,
324
- type GMapsContext,
325
- type APIOptions
413
+ setGMapsContext, // Create shared context
414
+ getGMapsContext, // Retrieve context
415
+ hasGMapsContext, // Check if context exists
416
+ initialiseGMaps, // Initialise with context
417
+ initialiseGMapsNoContext, // Initialise standalone
418
+ importLibrary, // Load Google Maps libraries
419
+ type GMapsContext, // Context type
420
+ type APIOptions // Loader options type
326
421
  } from 'places-autocomplete-svelte/gmaps';
327
422
  ```
328
423
 
329
- ## Google Places API & Billing
424
+ ## Security
330
425
 
331
426
  * This component uses the Google Maps JavaScript API (Places library). Usage is subject to Google's terms and pricing.
332
- * It uses **Session Tokens** automatically to group Autocomplete requests, which can reduce costs.
333
- * Place Details requests (via `fetchFields`) are billed separately. Only request the fields you need to manage costs.
427
+ * **Session Tokens** are used automatically to group Autocomplete requests, which can reduce costs.
428
+ * Place Details requests (via `fetchFields`) are billed separately. **Only request the fields you need** to manage costs effectively.
429
+ * For detailed pricing information, see [Google Maps Platform Pricing](https://developers.google.com/maps/documentation/javascript/usage-and-billing).
430
+
431
+ ## Standalone JavaScript Library
432
+
433
+ Need this functionality for a non-Svelte project? Check out our companion vanilla JavaScript library:
434
+
435
+ **[places-autocomplete-js](https://github.com/alexpechkarev/places-autocomplete-js)** - Same core Google Places (New) Autocomplete features, framework-agnostic implementation.
334
436
 
335
437
  ## Contributing
336
438
 
337
- Contributions are welcome! Please feel free to open an issue or submit a pull request.
439
+ Contributions are welcome! We appreciate bug reports, feature requests, and pull requests.
440
+
441
+ **How to contribute:**
442
+ 1. Fork the repository
443
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
444
+ 3. Commit your changes (`git commit -m 'Add amazing feature'`)
445
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
446
+ 5. Open a Pull Request
447
+
448
+ Please ensure your code follows the existing style and includes appropriate tests.
449
+
450
+ ## Author
451
+
452
+ **Alexander Pechkarev**
453
+ - GitHub: [@alexpechkarev](https://github.com/alexpechkarev)
454
+ - Email: alexpechkarev@gmail.com
338
455
 
339
456
  ## License
340
457
 
341
- [MIT](LICENSE)
458
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
459
+
460
+ ---
461
+
462
+ <p align="center">
463
+ <sub>Built with ❀️ using Svelte 5 and Google Maps Platform</sub>
464
+ </p>