@salla.sa/ui-address-autocomplete-widget 0.1.0
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 +501 -0
- package/dist/index.js +1597 -0
- package/package.json +41 -0
package/README.md
ADDED
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
# @salla.sa/ui-address-autocomplete-widget
|
|
2
|
+
|
|
3
|
+
A framework-agnostic address autocomplete web component built with Lit and Google Places API. Works seamlessly with React, Vue, Angular, or vanilla JavaScript.
|
|
4
|
+
|
|
5
|
+
## 🚀 Default Configuration
|
|
6
|
+
|
|
7
|
+
The component is **pre-configured to work with Salla's API (`api.salla.dev`)** out of the box. No additional proxy setup needed!
|
|
8
|
+
|
|
9
|
+
**Default Endpoints:**
|
|
10
|
+
- Autocomplete: `https://api.salla.dev/store/v1/checkout/address/autocomplete/query`
|
|
11
|
+
- Details: `https://api.salla.dev/store/v1/checkout/address/autocomplete/details`
|
|
12
|
+
|
|
13
|
+
**Expected Response Format:**
|
|
14
|
+
|
|
15
|
+
All responses must be wrapped in the standard Salla API format:
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
// Autocomplete response
|
|
19
|
+
{
|
|
20
|
+
"success": true,
|
|
21
|
+
"status": 200,
|
|
22
|
+
"data": [
|
|
23
|
+
{
|
|
24
|
+
"id": "ChIJOwg_06VPwokRYv534QaPC8g",
|
|
25
|
+
"formatted_address": "Empire State Building, New York, NY, USA",
|
|
26
|
+
"description": "Empire State Building",
|
|
27
|
+
"types": ["establishment", "point_of_interest"]
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Details response
|
|
33
|
+
{
|
|
34
|
+
"success": true,
|
|
35
|
+
"status": 200,
|
|
36
|
+
"data": {
|
|
37
|
+
"id": "ChIJOwg_06VPwokRYv534QaPC8g",
|
|
38
|
+
"formatted_address": "20 W 34th St., New York, NY 10001, USA",
|
|
39
|
+
"address_components": [
|
|
40
|
+
{
|
|
41
|
+
"long_name": "20",
|
|
42
|
+
"short_name": "20",
|
|
43
|
+
"types": ["street_number"]
|
|
44
|
+
}
|
|
45
|
+
// ... more components
|
|
46
|
+
],
|
|
47
|
+
"geometry": {
|
|
48
|
+
"location": { "lat": 40.748817, "lng": -73.985428 }
|
|
49
|
+
},
|
|
50
|
+
"types": ["street_address"]
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Error response
|
|
55
|
+
{
|
|
56
|
+
"success": false,
|
|
57
|
+
"status": 400,
|
|
58
|
+
"message": "Input is required"
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
You can override the `proxy-url` prop if you want to use your own backend proxy (must follow the same response format).
|
|
63
|
+
|
|
64
|
+
### Why Backend Proxy?
|
|
65
|
+
- ✅ No CORS issues - API calls from server-side
|
|
66
|
+
- ✅ API key hidden from users
|
|
67
|
+
- ✅ Full control over security & rate limiting
|
|
68
|
+
- ✅ No external SDK dependencies (~100KB saved)
|
|
69
|
+
|
|
70
|
+
**See [CORS_EXPLANATION.md](./CORS_EXPLANATION.md) for detailed explanation.**
|
|
71
|
+
|
|
72
|
+
## Features
|
|
73
|
+
|
|
74
|
+
✅ **Framework Agnostic** - Works with any framework or vanilla JS
|
|
75
|
+
✅ **Full TypeScript Support** - Complete type definitions included
|
|
76
|
+
✅ **No SDK Required** - Uses REST API via backend proxy (no Google SDK loading)
|
|
77
|
+
✅ **Session Token Management** - Optimized billing with automatic session handling
|
|
78
|
+
✅ **Address Validation Support** - Detects if validation is available for the country
|
|
79
|
+
✅ **UX Best Practices** - Keyboard navigation, loading states, error handling
|
|
80
|
+
✅ **Customizable** - Extensive props for location bias, country restrictions, and more
|
|
81
|
+
✅ **Highlighted Matches** - Visual highlighting of matched text in suggestions
|
|
82
|
+
✅ **Throttled Requests** - Efficient API usage with request throttling
|
|
83
|
+
|
|
84
|
+
## Installation
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npm install @salla.sa/ui-address-autocomplete-widget
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Usage
|
|
91
|
+
|
|
92
|
+
### Quick Start (Using Salla API)
|
|
93
|
+
|
|
94
|
+
The component works immediately with Salla's backend API:
|
|
95
|
+
|
|
96
|
+
```html
|
|
97
|
+
<!DOCTYPE html>
|
|
98
|
+
<html>
|
|
99
|
+
<head>
|
|
100
|
+
<script type="module">
|
|
101
|
+
import '@salla.sa/ui-address-autocomplete-widget';
|
|
102
|
+
|
|
103
|
+
const autocomplete = document.querySelector('salla-address-autocomplete');
|
|
104
|
+
|
|
105
|
+
// Optional: Set auth token if required by your Salla integration
|
|
106
|
+
autocomplete.authToken = 'your-salla-auth-token';
|
|
107
|
+
|
|
108
|
+
autocomplete.addEventListener('place-select', (e) => {
|
|
109
|
+
console.log('Selected place:', e.detail.place);
|
|
110
|
+
console.log('Validation support:', e.detail.validationSupport);
|
|
111
|
+
});
|
|
112
|
+
</script>
|
|
113
|
+
</head>
|
|
114
|
+
<body>
|
|
115
|
+
<salla-address-autocomplete
|
|
116
|
+
placeholder="Enter an address..."
|
|
117
|
+
label="Delivery Address"
|
|
118
|
+
></salla-address-autocomplete>
|
|
119
|
+
</body>
|
|
120
|
+
</html>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Using Custom Backend Proxy
|
|
124
|
+
|
|
125
|
+
If you want to use your own backend proxy instead of Salla's API:
|
|
126
|
+
|
|
127
|
+
```html
|
|
128
|
+
<salla-address-autocomplete
|
|
129
|
+
proxy-url="http://localhost:3001/api/places"
|
|
130
|
+
placeholder="Enter an address..."
|
|
131
|
+
label="Delivery Address"
|
|
132
|
+
></salla-address-autocomplete>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
See [proxy-examples/](./proxy-examples/) for complete backend setup guide.
|
|
136
|
+
|
|
137
|
+
### React
|
|
138
|
+
|
|
139
|
+
```tsx
|
|
140
|
+
import '@salla.sa/ui-address-autocomplete-widget';
|
|
141
|
+
|
|
142
|
+
function CheckoutForm() {
|
|
143
|
+
const [authToken, setAuthToken] = useState('');
|
|
144
|
+
|
|
145
|
+
const handlePlaceSelect = (e: CustomEvent) => {
|
|
146
|
+
const { place, validationSupport } = e.detail;
|
|
147
|
+
console.log('Selected:', place);
|
|
148
|
+
console.log('Country:', validationSupport.countryCode);
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
return (
|
|
152
|
+
<salla-address-autocomplete
|
|
153
|
+
auth-token={authToken}
|
|
154
|
+
placeholder="Enter delivery address..."
|
|
155
|
+
label="Address"
|
|
156
|
+
included-region-codes={JSON.stringify(['US', 'CA'])}
|
|
157
|
+
onplace-select={handlePlaceSelect}
|
|
158
|
+
/>
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Vue 3
|
|
164
|
+
|
|
165
|
+
```vue
|
|
166
|
+
<template>
|
|
167
|
+
<salla-address-autocomplete
|
|
168
|
+
:auth-token="authToken"
|
|
169
|
+
placeholder="Enter address..."
|
|
170
|
+
label="Address"
|
|
171
|
+
:included-region-codes="['SA', 'AE']"
|
|
172
|
+
@place-select="handlePlaceSelect"
|
|
173
|
+
/>
|
|
174
|
+
</template>
|
|
175
|
+
|
|
176
|
+
<script setup lang="ts">
|
|
177
|
+
import { ref } from 'vue';
|
|
178
|
+
import '@salla.sa/ui-address-autocomplete-widget';
|
|
179
|
+
|
|
180
|
+
const authToken = ref('');
|
|
181
|
+
|
|
182
|
+
const handlePlaceSelect = (e: CustomEvent) => {
|
|
183
|
+
console.log('Selected place:', e.detail.place);
|
|
184
|
+
};
|
|
185
|
+
</script>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Angular
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
// app.module.ts
|
|
192
|
+
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
|
193
|
+
import '@salla.sa/ui-address-autocomplete-widget';
|
|
194
|
+
|
|
195
|
+
@NgModule({
|
|
196
|
+
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
|
197
|
+
})
|
|
198
|
+
export class AppModule {}
|
|
199
|
+
|
|
200
|
+
// component.html
|
|
201
|
+
<salla-address-autocomplete
|
|
202
|
+
[attr.auth-token]="authToken"
|
|
203
|
+
placeholder="Enter address..."
|
|
204
|
+
label="Address"
|
|
205
|
+
(place-select)="handlePlaceSelect($event)"
|
|
206
|
+
></salla-address-autocomplete>
|
|
207
|
+
|
|
208
|
+
// component.ts
|
|
209
|
+
authToken = '';
|
|
210
|
+
|
|
211
|
+
handlePlaceSelect(event: CustomEvent) {
|
|
212
|
+
console.log('Selected:', event.detail.place);
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Properties
|
|
217
|
+
|
|
218
|
+
| Property | Type | Default | Description |
|
|
219
|
+
|----------|------|---------|-------------|
|
|
220
|
+
| `proxyUrl` | `string` | `'https://api.salla.dev'` | Base URL for proxy server |
|
|
221
|
+
| `authToken` | `string\|null` | `null` | Optional bearer token for proxy authentication |
|
|
222
|
+
| `placeholder` | `string` | `''` | Input placeholder text |
|
|
223
|
+
| `value` | `string` | `''` | Initial/controlled value |
|
|
224
|
+
| `label` | `string\|null` | `null` | Label text above input |
|
|
225
|
+
| `className` | `string` | `''` | CSS class for wrapper element |
|
|
226
|
+
| `country` | `string\|null` | `null` | Inline country filter (e.g., `"SA"` or `"SA,AE"`). Sets `includedRegionCodes` |
|
|
227
|
+
| `includedRegionCodes` | `string[]\|null` | `null` | Restrict to specific countries (e.g., `['SA', 'AE']`). Sent as `country=SA,AE` query parameter |
|
|
228
|
+
| `locationBias` | `object\|null` | `null` | Bias results to location (radius + center) |
|
|
229
|
+
| `locationRestriction` | `object\|null` | `null` | Restrict results to location bounds |
|
|
230
|
+
| `types` | `string[]\|null` | `null` | Filter by place types (e.g., `['geocode', 'establishment']`) |
|
|
231
|
+
| `fields` | `string[]` | `['formatted_address', 'geometry']` | Place data fields to fetch (cost optimized) |
|
|
232
|
+
| `strictBounds` | `boolean` | `false` | Only return results within bounds |
|
|
233
|
+
| `useSessionToken` | `boolean` | `true` | Enable session tokens (UUID v4) for billing optimization |
|
|
234
|
+
| `onValidateAddress` | `function\|null` | `null` | Backend validation callback |
|
|
235
|
+
| `debounceDelay` | `number` | `300` | Milliseconds to wait after typing stops |
|
|
236
|
+
| `minChars` | `number` | `3` | Minimum characters before search |
|
|
237
|
+
|
|
238
|
+
### Default Fields (Cost Optimized)
|
|
239
|
+
|
|
240
|
+
```javascript
|
|
241
|
+
[
|
|
242
|
+
'formatted_address', // Full address string
|
|
243
|
+
'geometry' // Lat/lng coordinates
|
|
244
|
+
]
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**Note:** Default configuration fetches **only essential fields** to minimize API costs (~$5/1000 requests).
|
|
248
|
+
|
|
249
|
+
To include country detection and validation support, add `address_components`:
|
|
250
|
+
```javascript
|
|
251
|
+
autocomplete.fields = ['formatted_address', 'geometry', 'address_components'];
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Events
|
|
255
|
+
|
|
256
|
+
### `place-select`
|
|
257
|
+
|
|
258
|
+
Fired when a user selects an address from the dropdown.
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
interface PlaceSelectEvent {
|
|
262
|
+
detail: {
|
|
263
|
+
place: PlaceDetails; // Complete place object with requested fields
|
|
264
|
+
validationSupport: {
|
|
265
|
+
isSupported: boolean | null; // true/false/null (if unknown)
|
|
266
|
+
countryCode: string | null; // ISO country code
|
|
267
|
+
};
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Example:
|
|
273
|
+
```javascript
|
|
274
|
+
autocomplete.addEventListener('place-select', (e) => {
|
|
275
|
+
const { place, validationSupport } = e.detail;
|
|
276
|
+
|
|
277
|
+
if (validationSupport.isSupported) {
|
|
278
|
+
// Address Validation API is supported for this country
|
|
279
|
+
// You can use validateAddress() method
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
console.log('Address:', place.formatted_address);
|
|
283
|
+
console.log('Coordinates:', place.geometry.location);
|
|
284
|
+
console.log('Country:', validationSupport.countryCode);
|
|
285
|
+
});
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### `place_changed`
|
|
289
|
+
|
|
290
|
+
Alias for `place-select` (for backward compatibility).
|
|
291
|
+
|
|
292
|
+
### `input`
|
|
293
|
+
|
|
294
|
+
Fired on every input change.
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
interface InputEvent {
|
|
298
|
+
detail: {
|
|
299
|
+
value: string;
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
## Methods
|
|
305
|
+
|
|
306
|
+
### `validateAddress(place: PlaceDetails)`
|
|
307
|
+
|
|
308
|
+
Validates an address using your backend API. Requires `onValidateAddress` callback.
|
|
309
|
+
|
|
310
|
+
```javascript
|
|
311
|
+
const autocomplete = document.querySelector('salla-address-autocomplete');
|
|
312
|
+
|
|
313
|
+
autocomplete.onValidateAddress = async ({ place, sessionToken, validationSupport }) => {
|
|
314
|
+
// Call your backend API
|
|
315
|
+
const response = await fetch('/api/validate-address', {
|
|
316
|
+
method: 'POST',
|
|
317
|
+
headers: { 'Content-Type': 'application/json' },
|
|
318
|
+
body: JSON.stringify({
|
|
319
|
+
address: place.formatted_address,
|
|
320
|
+
sessionToken,
|
|
321
|
+
countryCode: validationSupport.countryCode
|
|
322
|
+
})
|
|
323
|
+
});
|
|
324
|
+
return response.json();
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
// Later, when user submits the form:
|
|
328
|
+
autocomplete.addEventListener('place-select', async (e) => {
|
|
329
|
+
const result = await autocomplete.validateAddress(e.detail.place);
|
|
330
|
+
console.log('Validation result:', result);
|
|
331
|
+
});
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### `getValidationSupport(place: PlaceDetails)`
|
|
335
|
+
|
|
336
|
+
Returns validation support information for a place.
|
|
337
|
+
|
|
338
|
+
```javascript
|
|
339
|
+
const support = autocomplete.getValidationSupport(place);
|
|
340
|
+
console.log(support); // { isSupported: true, countryCode: 'US' }
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
## Advanced Examples
|
|
344
|
+
|
|
345
|
+
### Country-Restricted Search
|
|
346
|
+
|
|
347
|
+
```html
|
|
348
|
+
<salla-address-autocomplete
|
|
349
|
+
placeholder="Enter address in Saudi Arabia..."
|
|
350
|
+
country="SA"
|
|
351
|
+
></salla-address-autocomplete>
|
|
352
|
+
|
|
353
|
+
<!-- OR using JavaScript for multiple countries: -->
|
|
354
|
+
<salla-address-autocomplete
|
|
355
|
+
id="multi-country"
|
|
356
|
+
placeholder="Enter address in Saudi Arabia or UAE..."
|
|
357
|
+
></salla-address-autocomplete>
|
|
358
|
+
|
|
359
|
+
<script>
|
|
360
|
+
const autocomplete = document.getElementById('multi-country');
|
|
361
|
+
autocomplete.includedRegionCodes = ['SA', 'AE'];
|
|
362
|
+
// OR: autocomplete.country = 'SA,AE';
|
|
363
|
+
</script>
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### Location Bias (Prefer nearby results)
|
|
367
|
+
|
|
368
|
+
```javascript
|
|
369
|
+
autocomplete.locationBias = {
|
|
370
|
+
radius: 50000, // 50km radius
|
|
371
|
+
center: { lat: 24.7136, lng: 46.6753 } // Riyadh coordinates
|
|
372
|
+
};
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### Custom Fields (Cost Optimization)
|
|
376
|
+
|
|
377
|
+
```javascript
|
|
378
|
+
// Minimal fields for cost savings
|
|
379
|
+
autocomplete.fields = ['formatted_address', 'geometry'];
|
|
380
|
+
|
|
381
|
+
// With address components for validation
|
|
382
|
+
autocomplete.fields = [
|
|
383
|
+
'formatted_address',
|
|
384
|
+
'address_components',
|
|
385
|
+
'geometry',
|
|
386
|
+
'types'
|
|
387
|
+
];
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### Address Validation with Backend
|
|
391
|
+
|
|
392
|
+
```javascript
|
|
393
|
+
autocomplete.onValidateAddress = async ({ place, sessionToken, validationSupport }) => {
|
|
394
|
+
if (!validationSupport.isSupported) {
|
|
395
|
+
return { valid: true, message: 'Validation not available for this country' };
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
const response = await fetch('https://your-api.com/validate', {
|
|
399
|
+
method: 'POST',
|
|
400
|
+
headers: { 'Content-Type': 'application/json' },
|
|
401
|
+
body: JSON.stringify({
|
|
402
|
+
address: place.formatted_address,
|
|
403
|
+
sessionToken
|
|
404
|
+
})
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
return response.json();
|
|
408
|
+
};
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
### Using Bearer Token Authentication
|
|
412
|
+
|
|
413
|
+
If your proxy requires authentication, use the `authToken` prop:
|
|
414
|
+
|
|
415
|
+
```html
|
|
416
|
+
<salla-address-autocomplete
|
|
417
|
+
proxy-url="https://your-api.com/places"
|
|
418
|
+
auth-token="your-bearer-token-here"
|
|
419
|
+
placeholder="Enter address..."
|
|
420
|
+
></salla-address-autocomplete>
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
JavaScript:
|
|
424
|
+
```javascript
|
|
425
|
+
const autocomplete = document.querySelector('salla-address-autocomplete');
|
|
426
|
+
autocomplete.authToken = await getAuthToken(); // Get token from your auth system
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
React:
|
|
430
|
+
```tsx
|
|
431
|
+
<salla-address-autocomplete
|
|
432
|
+
proxy-url="https://your-api.com/places"
|
|
433
|
+
auth-token={authToken}
|
|
434
|
+
placeholder="Enter address..."
|
|
435
|
+
/>
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
## Styling
|
|
439
|
+
|
|
440
|
+
The component uses Shadow DOM with default styles. You can customize via CSS custom properties:
|
|
441
|
+
|
|
442
|
+
```css
|
|
443
|
+
salla-address-autocomplete {
|
|
444
|
+
--input-border-color: #d1d5db;
|
|
445
|
+
--input-focus-color: #3b82f6;
|
|
446
|
+
--dropdown-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
|
|
447
|
+
}
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
Or provide custom styles via `className`:
|
|
451
|
+
|
|
452
|
+
```html
|
|
453
|
+
<salla-address-autocomplete
|
|
454
|
+
class-name="my-custom-class"
|
|
455
|
+
></salla-address-autocomplete>
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
## Google Places API Setup
|
|
459
|
+
|
|
460
|
+
1. Go to [Google Cloud Console](https://console.cloud.google.com/)
|
|
461
|
+
2. Enable **Places API** and **Geocoding API**
|
|
462
|
+
3. Create an API key with restrictions
|
|
463
|
+
4. Add HTTP referrer restrictions for security
|
|
464
|
+
|
|
465
|
+
## Cost Optimization Tips
|
|
466
|
+
|
|
467
|
+
1. **Use session tokens** (`useSessionToken: true`) - Groups requests for better pricing
|
|
468
|
+
2. **Smart place details optimization** - Automatically skips details API call when location data is already in autocomplete response (saves 1 API call per selection when data is available)
|
|
469
|
+
3. **Fetch only needed fields** - Each field tier has different pricing (default is cost-optimized)
|
|
470
|
+
4. **Use address validation** - Free autocomplete in 53 countries when using validation API
|
|
471
|
+
5. **Restrict by country** - Reduces irrelevant results
|
|
472
|
+
6. **Debounce requests** - Built-in 300ms debouncing reduces API calls by ~93%
|
|
473
|
+
7. **Minimum characters** - Default 3 characters before search starts
|
|
474
|
+
|
|
475
|
+
## Browser Support
|
|
476
|
+
|
|
477
|
+
- Chrome/Edge 90+
|
|
478
|
+
- Firefox 88+
|
|
479
|
+
- Safari 14+
|
|
480
|
+
- All modern browsers with Custom Elements v1 support
|
|
481
|
+
|
|
482
|
+
## TypeScript Support
|
|
483
|
+
|
|
484
|
+
Full TypeScript definitions included:
|
|
485
|
+
|
|
486
|
+
```typescript
|
|
487
|
+
import type {
|
|
488
|
+
PlaceDetails,
|
|
489
|
+
AutocompletePrediction,
|
|
490
|
+
ValidationSupport,
|
|
491
|
+
LocationBias
|
|
492
|
+
} from '@salla.sa/ui-address-autocomplete-widget';
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
## License
|
|
496
|
+
|
|
497
|
+
MIT
|
|
498
|
+
|
|
499
|
+
## Support
|
|
500
|
+
|
|
501
|
+
For issues and questions, please visit: [GitHub Issues](https://github.com/salla-sa/ui-address-autocomplete-widget/issues)
|