@liquidcommerce/elements-sdk 2.7.0 → 2.7.2
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 +83 -2750
- package/dist/index.checkout.esm.js +6898 -6837
- package/dist/index.esm.js +11463 -10993
- package/dist/types/auto-initialize/shared-utils.d.ts +5 -0
- package/dist/types/constants/core.constant.d.ts +0 -4
- package/dist/types/core/base-component.service.d.ts +2 -1
- package/dist/types/core/pubsub/interfaces/checkout.interface.d.ts +1 -0
- package/dist/types/enums/core.enum.d.ts +11 -0
- package/dist/types/interfaces/configs/product-list.interface.d.ts +2 -2
- package/dist/types/interfaces/core.interface.d.ts +5 -4
- package/dist/types/modules/address/address-input.component.d.ts +11 -0
- package/dist/types/modules/checkout/components/checkout-stripe-form.component.d.ts +2 -1
- package/dist/types/modules/product-list/components/card-components/index.d.ts +3 -0
- package/dist/types/modules/product-list/components/card-components/product-badge.d.ts +8 -0
- package/dist/types/modules/product-list/components/card-components/product-fulfillments.d.ts +2 -0
- package/dist/types/modules/product-list/components/card-components/product-price-and-personalization.d.ts +13 -0
- package/dist/types/modules/product-list/components/card-components/product-title.d.ts +6 -0
- package/dist/types/modules/product-list/components/index.d.ts +1 -0
- package/dist/types/modules/product-list/components/product-list-engraving.component.d.ts +5 -1
- package/dist/types/modules/product-list/components/product-list-product-pre-cart.component.d.ts +28 -0
- package/dist/types/modules/product-list/components/product-list-retailers.component.d.ts +10 -2
- package/dist/types/modules/product-list/product-list-card.component.d.ts +0 -5
- package/dist/types/modules/product-list/product-list.commands.d.ts +11 -2
- package/dist/types/modules/product-list/product-list.interface.d.ts +1 -0
- package/dist/types/modules/ui-components/engraving/engraving-form.component.d.ts +11 -2
- package/dist/types/modules/ui-components/lce-element/lce-element.component.d.ts +2 -1
- package/dist/types/utils/dom-compat.d.ts +2 -0
- package/docs/gitbook/actions.md +964 -0
- package/docs/gitbook/address.md +48 -0
- package/docs/gitbook/cart.md +65 -0
- package/docs/gitbook/checkout.md +131 -0
- package/docs/gitbook/events.md +1765 -0
- package/docs/gitbook/overview.md +166 -0
- package/docs/gitbook/product.md +64 -0
- package/docs/gitbook/quick-start-guide.md +393 -0
- package/docs/v1/README.md +210 -0
- package/docs/v1/api/actions/address-actions.md +281 -0
- package/docs/v1/api/actions/cart-actions.md +337 -0
- package/docs/v1/api/actions/checkout-actions.md +387 -0
- package/docs/v1/api/actions/product-actions.md +115 -0
- package/docs/v1/api/client.md +482 -0
- package/docs/v1/api/configuration.md +1 -0
- package/docs/v1/api/injection-methods.md +247 -0
- package/docs/v1/api/typescript-types.md +1 -0
- package/docs/v1/api/ui-helpers.md +200 -0
- package/docs/v1/examples/advanced-patterns.md +96 -0
- package/docs/v1/examples/checkout-flow.md +91 -0
- package/docs/v1/examples/custom-theming.md +63 -0
- package/docs/v1/examples/multi-product-page.md +90 -0
- package/docs/v1/examples/simple-product-page.md +89 -0
- package/docs/v1/getting-started/concepts.md +507 -0
- package/docs/v1/getting-started/installation.md +328 -0
- package/docs/v1/getting-started/quick-start.md +405 -0
- package/docs/v1/guides/address-component.md +431 -0
- package/docs/v1/guides/best-practices.md +324 -0
- package/docs/v1/guides/cart-component.md +737 -0
- package/docs/v1/guides/checkout-component.md +672 -0
- package/docs/v1/guides/events.md +926 -0
- package/docs/v1/guides/product-component.md +686 -0
- package/docs/v1/guides/product-list-component.md +598 -0
- package/docs/v1/guides/theming.md +216 -0
- package/docs/v1/integration/angular.md +39 -0
- package/docs/v1/integration/laravel.md +41 -0
- package/docs/v1/integration/nextjs.md +60 -0
- package/docs/v1/integration/proxy-setup.md +89 -0
- package/docs/v1/integration/react.md +64 -0
- package/docs/v1/integration/vanilla-js.md +84 -0
- package/docs/v1/integration/vue.md +34 -0
- package/docs/v1/reference/browser-support.md +44 -0
- package/docs/v1/reference/error-handling.md +70 -0
- package/docs/v1/reference/performance.md +54 -0
- package/docs/v1/reference/troubleshooting.md +64 -0
- package/package.json +1 -1
- package/docs/ACTIONS.md +0 -1301
- package/docs/BROWSER_SUPPORT.md +0 -279
- package/docs/CONFIGURATION.md +0 -997
- package/docs/DOCUMENTATION_INDEX.md +0 -319
- package/docs/EVENTS.md +0 -798
- package/docs/PROXY.md +0 -228
- package/docs/THEMING.md +0 -681
- package/docs/TROUBLESHOOTING.md +0 -793
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
# Address Component
|
|
2
|
+
|
|
3
|
+
The Address component manages delivery location for availability checking and accurate pricing throughout the SDK.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The Address component:
|
|
8
|
+
- Provides location input via Google Places integration
|
|
9
|
+
- Allows manual address entry
|
|
10
|
+
- Stores location for cart/checkout
|
|
11
|
+
- Enables location-based pricing
|
|
12
|
+
- Determines product availability
|
|
13
|
+
- Supports fulfillment type selection
|
|
14
|
+
|
|
15
|
+
## How It Works
|
|
16
|
+
|
|
17
|
+
The address component is **embedded in the product component by default**. Users set their address when viewing products, and this address is used throughout the cart and checkout flow.
|
|
18
|
+
|
|
19
|
+
### Automatic Address Prompting
|
|
20
|
+
|
|
21
|
+
When a user tries to add a product to cart without setting an address:
|
|
22
|
+
|
|
23
|
+
1. Address input drawer opens automatically
|
|
24
|
+
2. User enters their address
|
|
25
|
+
3. Address is saved
|
|
26
|
+
4. Add-to-cart action resumes automatically
|
|
27
|
+
|
|
28
|
+
No additional code needed - this is handled automatically.
|
|
29
|
+
|
|
30
|
+
## Standalone Usage
|
|
31
|
+
|
|
32
|
+
Use the standalone address component when you need a dedicated address selection page:
|
|
33
|
+
|
|
34
|
+
```javascript
|
|
35
|
+
const client = await Elements('YOUR_API_KEY', { env: 'production' });
|
|
36
|
+
|
|
37
|
+
await client.injectAddressElement('address-container', {
|
|
38
|
+
onAddressSet: (address) => {
|
|
39
|
+
console.log('Address set:', address);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```html
|
|
45
|
+
<div id="address-container"></div>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Address Actions
|
|
49
|
+
|
|
50
|
+
### Set Address via Google Places ID
|
|
51
|
+
|
|
52
|
+
The recommended method - provides accurate geocoding:
|
|
53
|
+
|
|
54
|
+
```javascript
|
|
55
|
+
await window.elements.actions.address.setAddressByPlacesId('ChIJOwg_06VPwokRYv534QaPC8g');
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**How to get a Places ID:**
|
|
59
|
+
|
|
60
|
+
Visit [Google Place IDs](https://developers.google.com/maps/documentation/places/web-service/place-id#find-id) for details on obtaining a Places ID.
|
|
61
|
+
|
|
62
|
+
### Set Address Manually
|
|
63
|
+
|
|
64
|
+
For custom address flows without Google Places:
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
await window.elements.actions.address.setAddressManually(
|
|
68
|
+
{
|
|
69
|
+
one: '123 Main Street',
|
|
70
|
+
two: 'Apt 4', // Optional
|
|
71
|
+
city: 'New York',
|
|
72
|
+
state: 'NY',
|
|
73
|
+
zip: '10001'
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
latitude: 40.7128,
|
|
77
|
+
longitude: -74.0060
|
|
78
|
+
}
|
|
79
|
+
);
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Requirements:**
|
|
83
|
+
- `one`: Street address (required)
|
|
84
|
+
- `two`: Apartment, suite, etc. (optional)
|
|
85
|
+
- `city`: City name (required)
|
|
86
|
+
- `state`: Two-letter state code (required)
|
|
87
|
+
- `zip`: ZIP/postal code (required)
|
|
88
|
+
- `latitude`: Number between -90 and 90 (required)
|
|
89
|
+
- `longitude`: Number between -180 and 180 (required)
|
|
90
|
+
|
|
91
|
+
### Get Address Details
|
|
92
|
+
|
|
93
|
+
Retrieve the current address:
|
|
94
|
+
|
|
95
|
+
```javascript
|
|
96
|
+
const addressData = window.elements.actions.address.getDetails();
|
|
97
|
+
|
|
98
|
+
console.log(addressData);
|
|
99
|
+
// {
|
|
100
|
+
// id: 'ChIJ...',
|
|
101
|
+
// address: {
|
|
102
|
+
// one: '123 Main Street',
|
|
103
|
+
// two: 'Apt 4',
|
|
104
|
+
// city: 'New York',
|
|
105
|
+
// state: 'NY',
|
|
106
|
+
// zip: '10001'
|
|
107
|
+
// },
|
|
108
|
+
// coordinates: {
|
|
109
|
+
// latitude: 40.7128,
|
|
110
|
+
// longitude: -74.0060
|
|
111
|
+
// },
|
|
112
|
+
// formattedAddress: '123 Main Street, Apt 4, New York, NY 10001'
|
|
113
|
+
// }
|
|
114
|
+
|
|
115
|
+
// Returns null if no address is set
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Clear Address
|
|
119
|
+
|
|
120
|
+
Remove the current address:
|
|
121
|
+
|
|
122
|
+
```javascript
|
|
123
|
+
await window.elements.actions.address.clear();
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
This will:
|
|
127
|
+
- Clear stored address
|
|
128
|
+
- Trigger address prompts on next cart action
|
|
129
|
+
- Update all components that depend on location
|
|
130
|
+
|
|
131
|
+
## Events
|
|
132
|
+
|
|
133
|
+
### Address Updated
|
|
134
|
+
|
|
135
|
+
Fired when a new address is set:
|
|
136
|
+
|
|
137
|
+
```javascript
|
|
138
|
+
window.addEventListener('lce:actions.address_updated', (event) => {
|
|
139
|
+
const { address, coordinates, formattedAddress } = event.detail.data;
|
|
140
|
+
|
|
141
|
+
console.log('New address:', formattedAddress);
|
|
142
|
+
console.log('Coordinates:', coordinates);
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Address Cleared
|
|
147
|
+
|
|
148
|
+
Fired when address is removed:
|
|
149
|
+
|
|
150
|
+
```javascript
|
|
151
|
+
window.addEventListener('lce:actions.address_cleared', (event) => {
|
|
152
|
+
console.log('Address has been cleared');
|
|
153
|
+
});
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Address Failed
|
|
157
|
+
|
|
158
|
+
Fired when address setting fails:
|
|
159
|
+
|
|
160
|
+
```javascript
|
|
161
|
+
window.addEventListener('lce:actions.address_failed', (event) => {
|
|
162
|
+
const { error } = event.detail.data;
|
|
163
|
+
console.error('Address error:', error);
|
|
164
|
+
});
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Customization
|
|
168
|
+
|
|
169
|
+
### Theme Configuration
|
|
170
|
+
|
|
171
|
+
Customize address component appearance:
|
|
172
|
+
|
|
173
|
+
```javascript
|
|
174
|
+
const client = await Elements('YOUR_API_KEY', {
|
|
175
|
+
env: 'production',
|
|
176
|
+
customTheme: {
|
|
177
|
+
address: {
|
|
178
|
+
theme: {
|
|
179
|
+
backgroundColor: '#ffffff'
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Use Cases
|
|
187
|
+
|
|
188
|
+
### Dedicated Location Page
|
|
189
|
+
|
|
190
|
+
Create a dedicated page for address selection:
|
|
191
|
+
|
|
192
|
+
```html
|
|
193
|
+
<!DOCTYPE html>
|
|
194
|
+
<html>
|
|
195
|
+
<head>
|
|
196
|
+
<title>Set Delivery Location</title>
|
|
197
|
+
<script
|
|
198
|
+
defer
|
|
199
|
+
data-liquid-commerce-elements
|
|
200
|
+
data-token="YOUR_API_KEY"
|
|
201
|
+
data-env="production"
|
|
202
|
+
type="text/javascript"
|
|
203
|
+
src="https://assets-elements.liquidcommerce.us/all/elements.js"
|
|
204
|
+
></script>
|
|
205
|
+
</head>
|
|
206
|
+
<body>
|
|
207
|
+
<h1>Where should we deliver?</h1>
|
|
208
|
+
<div id="address"></div>
|
|
209
|
+
|
|
210
|
+
<script>
|
|
211
|
+
window.addEventListener('lce:actions.client_ready', async () => {
|
|
212
|
+
await window.elements.injectAddressElement('address');
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
window.addEventListener('lce:actions.address_updated', () => {
|
|
216
|
+
// Redirect to product page after address is set
|
|
217
|
+
window.location.href = '/products';
|
|
218
|
+
});
|
|
219
|
+
</script>
|
|
220
|
+
</body>
|
|
221
|
+
</html>
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Custom Address Input with Validation
|
|
225
|
+
|
|
226
|
+
```javascript
|
|
227
|
+
document.getElementById('save-address-btn').addEventListener('click', async () => {
|
|
228
|
+
const address = {
|
|
229
|
+
one: document.getElementById('street').value,
|
|
230
|
+
two: document.getElementById('apt').value,
|
|
231
|
+
city: document.getElementById('city').value,
|
|
232
|
+
state: document.getElementById('state').value,
|
|
233
|
+
zip: document.getElementById('zip').value
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
// Get coordinates from your geocoding service
|
|
237
|
+
const coords = await geocodeAddress(address);
|
|
238
|
+
|
|
239
|
+
try {
|
|
240
|
+
await window.elements.actions.address.setAddressManually(address, coords);
|
|
241
|
+
showSuccessMessage('Address saved!');
|
|
242
|
+
} catch (error) {
|
|
243
|
+
showErrorMessage('Invalid address');
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Pre-fill Address from User Account
|
|
249
|
+
|
|
250
|
+
```javascript
|
|
251
|
+
// After user logs in, set their saved address
|
|
252
|
+
window.addEventListener('lce:actions.client_ready', async () => {
|
|
253
|
+
if (userIsLoggedIn && !currentAddressSet) {
|
|
254
|
+
await window.elements.actions.address.setAddressManually(
|
|
255
|
+
user.savedAddress,
|
|
256
|
+
user.savedCoordinates
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Location-Based Product Filtering
|
|
263
|
+
|
|
264
|
+
```javascript
|
|
265
|
+
window.addEventListener('lce:actions.address_updated', async (event) => {
|
|
266
|
+
const { coordinates } = event.detail.data;
|
|
267
|
+
|
|
268
|
+
// Fetch products available in this location
|
|
269
|
+
const availableProducts = await fetch('/api/products', {
|
|
270
|
+
method: 'POST',
|
|
271
|
+
body: JSON.stringify({ latitude: coordinates.latitude, longitude: coordinates.longitude })
|
|
272
|
+
}).then(r => r.json());
|
|
273
|
+
|
|
274
|
+
// Update UI with available products
|
|
275
|
+
displayProducts(availableProducts);
|
|
276
|
+
});
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Multi-Location Switcher
|
|
280
|
+
|
|
281
|
+
```javascript
|
|
282
|
+
const locations = [
|
|
283
|
+
{ name: 'Home', placesId: 'ChIJ...' },
|
|
284
|
+
{ name: 'Work', placesId: 'ChIJ...' },
|
|
285
|
+
{ name: 'Mom\'s House', placesId: 'ChIJ...' }
|
|
286
|
+
];
|
|
287
|
+
|
|
288
|
+
document.getElementById('location-select').addEventListener('change', async (e) => {
|
|
289
|
+
const selectedLocation = locations[e.target.value];
|
|
290
|
+
|
|
291
|
+
await window.elements.actions.address.setAddressByPlacesId(
|
|
292
|
+
selectedLocation.placesId
|
|
293
|
+
);
|
|
294
|
+
|
|
295
|
+
showNotification(`Switched to ${selectedLocation.name}`);
|
|
296
|
+
});
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## Address Persistence
|
|
300
|
+
|
|
301
|
+
### Storage
|
|
302
|
+
|
|
303
|
+
Addresses are stored in:
|
|
304
|
+
- SDK internal store
|
|
305
|
+
- LocalStorage (for persistence)
|
|
306
|
+
- Session (until explicitly cleared)
|
|
307
|
+
|
|
308
|
+
### Lifespan
|
|
309
|
+
|
|
310
|
+
Addresses persist:
|
|
311
|
+
- Across page refreshes
|
|
312
|
+
- Across browser sessions
|
|
313
|
+
- Until explicitly cleared by user or code
|
|
314
|
+
|
|
315
|
+
### Privacy
|
|
316
|
+
|
|
317
|
+
Addresses are:
|
|
318
|
+
- Stored locally in the browser
|
|
319
|
+
- Not sent to external servers except for availability checking
|
|
320
|
+
- Cleared when user logs out (if you implement logout handling)
|
|
321
|
+
|
|
322
|
+
## Best Practices
|
|
323
|
+
|
|
324
|
+
### Request Early
|
|
325
|
+
|
|
326
|
+
Set address as early as possible in the user flow:
|
|
327
|
+
|
|
328
|
+
```javascript
|
|
329
|
+
// On homepage or landing page
|
|
330
|
+
window.addEventListener('lce:actions.client_ready', () => {
|
|
331
|
+
const currentAddress = window.elements.actions.address.getDetails();
|
|
332
|
+
|
|
333
|
+
if (!currentAddress) {
|
|
334
|
+
// Show address prompt
|
|
335
|
+
showAddressPrompt();
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Provide Context
|
|
341
|
+
|
|
342
|
+
Explain why you need the address:
|
|
343
|
+
|
|
344
|
+
```html
|
|
345
|
+
<div class="address-explainer">
|
|
346
|
+
<h2>Where should we deliver?</h2>
|
|
347
|
+
<p>We need your location to show available products and accurate pricing.</p>
|
|
348
|
+
<div id="address"></div>
|
|
349
|
+
</div>
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### Validate Manually Entered Addresses
|
|
353
|
+
|
|
354
|
+
When using manual address entry, validate before setting:
|
|
355
|
+
|
|
356
|
+
```javascript
|
|
357
|
+
async function setAddress(address, coords) {
|
|
358
|
+
// Validate format
|
|
359
|
+
if (!address.one || !address.city || !address.state || !address.zip) {
|
|
360
|
+
throw new Error('Missing required address fields');
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Validate state code
|
|
364
|
+
if (address.state.length !== 2) {
|
|
365
|
+
throw new Error('State must be 2-letter code');
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// Validate ZIP
|
|
369
|
+
if (!/^\d{5}(-\d{4})?$/.test(address.zip)) {
|
|
370
|
+
throw new Error('Invalid ZIP code');
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// Validate coordinates
|
|
374
|
+
if (coords.latitude < -90 || coords.latitude > 90) {
|
|
375
|
+
throw new Error('Invalid latitude');
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if (coords.longitude < -180 || coords.longitude > 180) {
|
|
379
|
+
throw new Error('Invalid longitude');
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// Set address
|
|
383
|
+
await window.elements.actions.address.setAddressManually(address, coords);
|
|
384
|
+
}
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Handle Errors Gracefully
|
|
388
|
+
|
|
389
|
+
```javascript
|
|
390
|
+
try {
|
|
391
|
+
await window.elements.actions.address.setAddressByPlacesId(placesId);
|
|
392
|
+
} catch (error) {
|
|
393
|
+
console.error('Failed to set address:', error);
|
|
394
|
+
|
|
395
|
+
// Show user-friendly error
|
|
396
|
+
showError('Unable to set that address. Please try again or enter manually.');
|
|
397
|
+
|
|
398
|
+
// Fall back to manual entry
|
|
399
|
+
showManualAddressForm();
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
## Troubleshooting
|
|
403
|
+
|
|
404
|
+
### Address Not Persisting
|
|
405
|
+
|
|
406
|
+
1. Check localStorage is not disabled
|
|
407
|
+
2. Verify no errors in console
|
|
408
|
+
3. Ensure `clear()` is not being called unintentionally
|
|
409
|
+
4. Check that address was set successfully (no errors thrown)
|
|
410
|
+
|
|
411
|
+
### Products Not Updating After Address Change
|
|
412
|
+
|
|
413
|
+
1. Products should automatically rerender when address changes
|
|
414
|
+
2. Check console for errors
|
|
415
|
+
3. Verify address was actually set (not just input changed)
|
|
416
|
+
4. Try manually rerendering product components
|
|
417
|
+
|
|
418
|
+
### Invalid Address Errors
|
|
419
|
+
|
|
420
|
+
1. Ensure all required fields are provided
|
|
421
|
+
2. Verify coordinates are within valid ranges
|
|
422
|
+
3. Check state code is 2 letters
|
|
423
|
+
4. Validate ZIP code format
|
|
424
|
+
5. Use Places ID method for most accurate results
|
|
425
|
+
|
|
426
|
+
## See Also
|
|
427
|
+
|
|
428
|
+
- [Product Component](./product-component.md) - Uses address for availability
|
|
429
|
+
- [Cart Component](./cart-component.md) - Requires address for adding items
|
|
430
|
+
- [Actions API](../api/actions/address-actions.md) - Address actions reference
|
|
431
|
+
- [Events](./events.md) - All available events
|