@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.
Files changed (81) hide show
  1. package/README.md +83 -2750
  2. package/dist/index.checkout.esm.js +6898 -6837
  3. package/dist/index.esm.js +11463 -10993
  4. package/dist/types/auto-initialize/shared-utils.d.ts +5 -0
  5. package/dist/types/constants/core.constant.d.ts +0 -4
  6. package/dist/types/core/base-component.service.d.ts +2 -1
  7. package/dist/types/core/pubsub/interfaces/checkout.interface.d.ts +1 -0
  8. package/dist/types/enums/core.enum.d.ts +11 -0
  9. package/dist/types/interfaces/configs/product-list.interface.d.ts +2 -2
  10. package/dist/types/interfaces/core.interface.d.ts +5 -4
  11. package/dist/types/modules/address/address-input.component.d.ts +11 -0
  12. package/dist/types/modules/checkout/components/checkout-stripe-form.component.d.ts +2 -1
  13. package/dist/types/modules/product-list/components/card-components/index.d.ts +3 -0
  14. package/dist/types/modules/product-list/components/card-components/product-badge.d.ts +8 -0
  15. package/dist/types/modules/product-list/components/card-components/product-fulfillments.d.ts +2 -0
  16. package/dist/types/modules/product-list/components/card-components/product-price-and-personalization.d.ts +13 -0
  17. package/dist/types/modules/product-list/components/card-components/product-title.d.ts +6 -0
  18. package/dist/types/modules/product-list/components/index.d.ts +1 -0
  19. package/dist/types/modules/product-list/components/product-list-engraving.component.d.ts +5 -1
  20. package/dist/types/modules/product-list/components/product-list-product-pre-cart.component.d.ts +28 -0
  21. package/dist/types/modules/product-list/components/product-list-retailers.component.d.ts +10 -2
  22. package/dist/types/modules/product-list/product-list-card.component.d.ts +0 -5
  23. package/dist/types/modules/product-list/product-list.commands.d.ts +11 -2
  24. package/dist/types/modules/product-list/product-list.interface.d.ts +1 -0
  25. package/dist/types/modules/ui-components/engraving/engraving-form.component.d.ts +11 -2
  26. package/dist/types/modules/ui-components/lce-element/lce-element.component.d.ts +2 -1
  27. package/dist/types/utils/dom-compat.d.ts +2 -0
  28. package/docs/gitbook/actions.md +964 -0
  29. package/docs/gitbook/address.md +48 -0
  30. package/docs/gitbook/cart.md +65 -0
  31. package/docs/gitbook/checkout.md +131 -0
  32. package/docs/gitbook/events.md +1765 -0
  33. package/docs/gitbook/overview.md +166 -0
  34. package/docs/gitbook/product.md +64 -0
  35. package/docs/gitbook/quick-start-guide.md +393 -0
  36. package/docs/v1/README.md +210 -0
  37. package/docs/v1/api/actions/address-actions.md +281 -0
  38. package/docs/v1/api/actions/cart-actions.md +337 -0
  39. package/docs/v1/api/actions/checkout-actions.md +387 -0
  40. package/docs/v1/api/actions/product-actions.md +115 -0
  41. package/docs/v1/api/client.md +482 -0
  42. package/docs/v1/api/configuration.md +1 -0
  43. package/docs/v1/api/injection-methods.md +247 -0
  44. package/docs/v1/api/typescript-types.md +1 -0
  45. package/docs/v1/api/ui-helpers.md +200 -0
  46. package/docs/v1/examples/advanced-patterns.md +96 -0
  47. package/docs/v1/examples/checkout-flow.md +91 -0
  48. package/docs/v1/examples/custom-theming.md +63 -0
  49. package/docs/v1/examples/multi-product-page.md +90 -0
  50. package/docs/v1/examples/simple-product-page.md +89 -0
  51. package/docs/v1/getting-started/concepts.md +507 -0
  52. package/docs/v1/getting-started/installation.md +328 -0
  53. package/docs/v1/getting-started/quick-start.md +405 -0
  54. package/docs/v1/guides/address-component.md +431 -0
  55. package/docs/v1/guides/best-practices.md +324 -0
  56. package/docs/v1/guides/cart-component.md +737 -0
  57. package/docs/v1/guides/checkout-component.md +672 -0
  58. package/docs/v1/guides/events.md +926 -0
  59. package/docs/v1/guides/product-component.md +686 -0
  60. package/docs/v1/guides/product-list-component.md +598 -0
  61. package/docs/v1/guides/theming.md +216 -0
  62. package/docs/v1/integration/angular.md +39 -0
  63. package/docs/v1/integration/laravel.md +41 -0
  64. package/docs/v1/integration/nextjs.md +60 -0
  65. package/docs/v1/integration/proxy-setup.md +89 -0
  66. package/docs/v1/integration/react.md +64 -0
  67. package/docs/v1/integration/vanilla-js.md +84 -0
  68. package/docs/v1/integration/vue.md +34 -0
  69. package/docs/v1/reference/browser-support.md +44 -0
  70. package/docs/v1/reference/error-handling.md +70 -0
  71. package/docs/v1/reference/performance.md +54 -0
  72. package/docs/v1/reference/troubleshooting.md +64 -0
  73. package/package.json +1 -1
  74. package/docs/ACTIONS.md +0 -1301
  75. package/docs/BROWSER_SUPPORT.md +0 -279
  76. package/docs/CONFIGURATION.md +0 -997
  77. package/docs/DOCUMENTATION_INDEX.md +0 -319
  78. package/docs/EVENTS.md +0 -798
  79. package/docs/PROXY.md +0 -228
  80. package/docs/THEMING.md +0 -681
  81. package/docs/TROUBLESHOOTING.md +0 -793
@@ -0,0 +1,1765 @@
1
+ # Events
2
+
3
+ The SDK emits browser events for user actions and state changes. Listen on `window` using `lce:actions.*` and `lce:forms.*`.
4
+
5
+ ## Event shape
6
+
7
+ All SDK events are native `CustomEvent` objects. The payload lives in `event.detail`:
8
+
9
+ ```ts
10
+ export interface IEventMetadata {
11
+ eventId: string;
12
+ namespace: 'actions' | 'forms';
13
+ event: string;
14
+ originalEvent: string;
15
+ actionNamespace?: 'address' | 'product' | 'cart' | 'checkout' | 'other';
16
+ timestamp: number;
17
+ }
18
+
19
+ export interface IEnhancedEventData<T> {
20
+ data: T;
21
+ metadata: IEventMetadata;
22
+ }
23
+ ```
24
+
25
+ ```js
26
+ window.addEventListener('lce:actions.event_name', (event) => {
27
+ const { data, metadata } = event.detail;
28
+ });
29
+ ```
30
+
31
+ **TypeScript interfaces:** The interface names used below match the SDK type definitions. You can inspect them in your install at `node_modules/@liquidcommerce/elements-sdk/dist/types/core/pubsub/interfaces/*`.
32
+
33
+ ## Namespaces
34
+
35
+ - `lce:actions.*` - User actions and state changes
36
+ - `lce:forms.*` - Form field interactions (checkout)
37
+ - `lce:actions` - All action events (namespace listener)
38
+ - `lce:forms` - All form events (namespace listener)
39
+
40
+ Example: listen to every action event:
41
+
42
+ ```js
43
+ window.addEventListener('lce:actions', (event) => {
44
+ const { metadata } = event.detail;
45
+ console.log('Action event:', metadata.event);
46
+ });
47
+ ```
48
+
49
+ ## Client lifecycle
50
+
51
+ ### `lce:actions.client_ready`
52
+
53
+ Fired once when the SDK is initialized and safe to use.
54
+
55
+ **Data shape (TypeScript)**
56
+
57
+ ```ts
58
+ export interface IElementsClientIsReadyEventData {
59
+ isReady: boolean;
60
+ message: string;
61
+ timestamp: number;
62
+ version?: string;
63
+ }
64
+ ```
65
+
66
+ **Example**
67
+
68
+ ```js
69
+ window.addEventListener('lce:actions.client_ready', (event) => {
70
+ const { data } = event.detail;
71
+ if (data.isReady) {
72
+ console.log('Elements SDK ready', data.version);
73
+ }
74
+ });
75
+ ```
76
+
77
+ ## Product events
78
+
79
+ ### `lce:actions.product_loaded`
80
+
81
+ Product data finished loading into a product component.
82
+
83
+ **Data shape (TypeScript)**
84
+
85
+ ```ts
86
+ export type FulfillmentType = 'onDemand' | 'shipping';
87
+
88
+ export interface IProductLoadedEventData {
89
+ identifier: string;
90
+ selectedSizeId: string | null;
91
+ selectedFulfillmentType: FulfillmentType;
92
+ selectedFulfillmentId: string | null;
93
+ productHasAvailability: boolean;
94
+ fulfillmentHasAvailability: boolean;
95
+ sizes: Record<string, IProductSizeEventData>;
96
+
97
+ id: string;
98
+ name: string;
99
+ description: string;
100
+ htmlDescription: string;
101
+ images: string[];
102
+ brand: string;
103
+ region: string;
104
+ country: string;
105
+ material: string;
106
+ abv: string;
107
+ proof: string;
108
+ age: string;
109
+ color: string;
110
+ flavor: string;
111
+ variety: string;
112
+ appellation: string;
113
+ vintage: string;
114
+ tastingNotes: string;
115
+ catPath: string;
116
+ category: string;
117
+ classification: string;
118
+ type: string;
119
+ subType: string;
120
+ salsifyGrouping: string;
121
+ noAvailabilityPrice: number;
122
+ }
123
+
124
+ export interface IProductSizeEventData {
125
+ id: string;
126
+ upc: string;
127
+ size: string;
128
+ pack: boolean;
129
+ packDesc: string;
130
+ container: string;
131
+ containerType: string;
132
+ image: string;
133
+ uom: string;
134
+ volume: string;
135
+ maxQuantityPerOrder: number;
136
+ attributes: IProductSizeAttributes;
137
+ onDemandFulfillments: Record<string, IProductFulfillmentEventData>;
138
+ shippingFulfillments: Record<string, IProductFulfillmentEventData>;
139
+ }
140
+
141
+ export interface IProductSizeAttributes {
142
+ presale: IProductPresale;
143
+ engraving: IProductSizeEngraving;
144
+ }
145
+
146
+ export interface IProductSizeEngraving {
147
+ maxLines: number;
148
+ maxCharsPerLine: number;
149
+ fee: number;
150
+ location: string;
151
+ }
152
+
153
+ export interface IProductPresale {
154
+ canPurchaseOn: string | null;
155
+ estimatedShipBy: string | null;
156
+ isActive: boolean;
157
+ language: string;
158
+ }
159
+
160
+ export interface IProductFulfillmentEventData {
161
+ id: string;
162
+ type: FulfillmentType;
163
+ doesAllowGiftCards: boolean;
164
+ doesAllowPromos: boolean;
165
+ expectation: string;
166
+ engravingExpectation: string;
167
+ fee: number;
168
+ timezone: string;
169
+ hourStatus: IProductFulfillmentHourStatus;
170
+ retailerName: string;
171
+ retailerAddress: IRetailerAddress;
172
+ retailerAddressFormatted: string;
173
+ variant: IProductVariant;
174
+ }
175
+
176
+ export interface IProductFulfillmentHourStatus {
177
+ isOpen: boolean;
178
+ openTime: string;
179
+ isClosed: boolean;
180
+ closeTime: string;
181
+ }
182
+
183
+ export interface IProductVariant {
184
+ retailerId: string;
185
+ shippingFulfillmentId: string;
186
+ onDemandFulfillmentId: string;
187
+ isEngravable: boolean;
188
+ partNumber: string;
189
+ price: number;
190
+ stock: number;
191
+ }
192
+
193
+ export type IRetailerAddress = IAddressAddress & IAddressCoordinates;
194
+
195
+ export interface IAddressAddress {
196
+ one: string;
197
+ two: string;
198
+ city: string;
199
+ state: string;
200
+ zip: string;
201
+ country: string;
202
+ }
203
+
204
+ export interface IAddressCoordinates {
205
+ latitude: number;
206
+ longitude: number;
207
+ }
208
+ ```
209
+
210
+ **Example**
211
+
212
+ ```js
213
+ window.addEventListener('lce:actions.product_loaded', (event) => {
214
+ const { data } = event.detail;
215
+ console.log(`Loaded ${data.name} (${data.identifier})`);
216
+ });
217
+ ```
218
+
219
+ ### `lce:actions.product_add_to_cart`
220
+
221
+ User triggered add-to-cart from a product component. Use cart events to confirm success or failure.
222
+
223
+ **Data shape (TypeScript)**
224
+
225
+ ```ts
226
+ export interface IProductAddToCartEventData {
227
+ identifier: string;
228
+ fulfillmentId: string;
229
+ partNumber: string;
230
+ quantity: number;
231
+ engravingLines?: string[];
232
+ }
233
+ ```
234
+
235
+ **Example**
236
+
237
+ ```js
238
+ window.addEventListener('lce:actions.product_add_to_cart', (event) => {
239
+ const { data } = event.detail;
240
+ gtag('event', 'add_to_cart_click', { item_id: data.identifier, quantity: data.quantity });
241
+ });
242
+ ```
243
+
244
+ ### `lce:actions.product_size_changed`
245
+
246
+ User changed the selected size.
247
+
248
+ **Data shape (TypeScript)**
249
+
250
+ ```ts
251
+ export interface IProductSizeChangedEventData {
252
+ identifier: string;
253
+ selectedSizeId: string;
254
+ selectedSize: string;
255
+ previousSizeId: string;
256
+ previousSize: string;
257
+ }
258
+ ```
259
+
260
+ **Example**
261
+
262
+ ```js
263
+ window.addEventListener('lce:actions.product_size_changed', (event) => {
264
+ const { data } = event.detail;
265
+ console.log('Size changed to', data.selectedSize);
266
+ });
267
+ ```
268
+
269
+ ### `lce:actions.product_fulfillment_type_changed`
270
+
271
+ User switched fulfillment type (for example shipping vs onDemand).
272
+
273
+ **Data shape (TypeScript)**
274
+
275
+ ```ts
276
+ export type FulfillmentType = 'onDemand' | 'shipping';
277
+
278
+ export interface IProductFulfillmentTypeChangedEventData {
279
+ identifier: string;
280
+ selectedFulfillmentType: FulfillmentType;
281
+ selectedFulfillmentId: string | null;
282
+ previousFulfillmentType: FulfillmentType;
283
+ previousFulfillmentId: string | null;
284
+ fulfillmentHasAvailability: boolean;
285
+ }
286
+ ```
287
+
288
+ **Example**
289
+
290
+ ```js
291
+ window.addEventListener('lce:actions.product_fulfillment_type_changed', (event) => {
292
+ const { data } = event.detail;
293
+ console.log('Fulfillment type:', data.selectedFulfillmentType);
294
+ });
295
+ ```
296
+
297
+ ### `lce:actions.product_fulfillment_changed`
298
+
299
+ User selected a different fulfillment option or retailer.
300
+
301
+ **Data shape (TypeScript)**
302
+
303
+ ```ts
304
+ export type FulfillmentType = 'onDemand' | 'shipping';
305
+
306
+ export interface IProductFulfillmentChangedEventData {
307
+ identifier: string;
308
+ selectedFulfillmentId: string;
309
+ selectedFulfillmentType: FulfillmentType;
310
+ previousFulfillmentId: string;
311
+ previousFulfillmentType: FulfillmentType;
312
+ }
313
+ ```
314
+
315
+ **Example**
316
+
317
+ ```js
318
+ window.addEventListener('lce:actions.product_fulfillment_changed', (event) => {
319
+ const { data } = event.detail;
320
+ console.log('Fulfillment changed:', data.selectedFulfillmentId);
321
+ });
322
+ ```
323
+
324
+ ### `lce:actions.product_quantity_increase`
325
+
326
+ Product quantity increased.
327
+
328
+ **Data shape (TypeScript)**
329
+
330
+ ```ts
331
+ export interface IProductQuantityChangedEventData {
332
+ identifier: string;
333
+ quantity: number;
334
+ previousQuantity: number;
335
+ }
336
+ ```
337
+
338
+ **Example**
339
+
340
+ ```js
341
+ window.addEventListener('lce:actions.product_quantity_increase', (event) => {
342
+ const { data } = event.detail;
343
+ console.log('Quantity increased to', data.quantity);
344
+ });
345
+ ```
346
+
347
+ ### `lce:actions.product_quantity_decrease`
348
+
349
+ Product quantity decreased.
350
+
351
+ **Data shape (TypeScript)**
352
+
353
+ ```ts
354
+ export interface IProductQuantityChangedEventData {
355
+ identifier: string;
356
+ quantity: number;
357
+ previousQuantity: number;
358
+ }
359
+ ```
360
+
361
+ **Example**
362
+
363
+ ```js
364
+ window.addEventListener('lce:actions.product_quantity_decrease', (event) => {
365
+ const { data } = event.detail;
366
+ console.log('Quantity decreased to', data.quantity);
367
+ });
368
+ ```
369
+
370
+ ## Address events
371
+
372
+ ### `lce:actions.address_updated`
373
+
374
+ Address successfully set or changed.
375
+
376
+ **Data shape (TypeScript)**
377
+
378
+ ```ts
379
+ export interface IAddressActionEventData {
380
+ googlePlacesId: string;
381
+ formattedAddress: string;
382
+ address: IAddressAddress;
383
+ coordinates: IAddressCoordinates;
384
+ }
385
+
386
+ export interface IAddressAddress {
387
+ one: string;
388
+ two: string;
389
+ city: string;
390
+ state: string;
391
+ zip: string;
392
+ country: string;
393
+ }
394
+
395
+ export interface IAddressCoordinates {
396
+ latitude: number;
397
+ longitude: number;
398
+ }
399
+ ```
400
+
401
+ **Example**
402
+
403
+ ```js
404
+ window.addEventListener('lce:actions.address_updated', (event) => {
405
+ const { data } = event.detail;
406
+ console.log('Address set:', data.formattedAddress);
407
+ });
408
+ ```
409
+
410
+ ### `lce:actions.address_cleared`
411
+
412
+ Address removed.
413
+
414
+ **Data shape (TypeScript)**
415
+
416
+ ```ts
417
+ export type AddressClearedEventData = boolean;
418
+ ```
419
+
420
+ **Example**
421
+
422
+ ```js
423
+ window.addEventListener('lce:actions.address_cleared', () => {
424
+ console.log('Address cleared');
425
+ });
426
+ ```
427
+
428
+ ### `lce:actions.address_failed`
429
+
430
+ Address set failed (validation, geocode, etc.).
431
+
432
+ **Data shape (TypeScript)**
433
+
434
+ ```ts
435
+ export interface IAddressFailedEventData {
436
+ googlePlacesId: string;
437
+ formattedAddress: string;
438
+ address: IAddressAddress;
439
+ coordinates: IAddressCoordinates;
440
+ error: string;
441
+ }
442
+
443
+ export interface IAddressAddress {
444
+ one: string;
445
+ two: string;
446
+ city: string;
447
+ state: string;
448
+ zip: string;
449
+ country: string;
450
+ }
451
+
452
+ export interface IAddressCoordinates {
453
+ latitude: number;
454
+ longitude: number;
455
+ }
456
+ ```
457
+
458
+ **Example**
459
+
460
+ ```js
461
+ window.addEventListener('lce:actions.address_failed', (event) => {
462
+ const { data } = event.detail;
463
+ console.error('Address error:', data.error);
464
+ });
465
+ ```
466
+
467
+ ## Cart events
468
+
469
+ ### `lce:actions.cart_loaded`
470
+
471
+ Cart state loaded or synced.
472
+
473
+ **Data shape (TypeScript)**
474
+
475
+ ```ts
476
+ export type FulfillmentType = 'onDemand' | 'shipping';
477
+
478
+ export interface IBaseCartEventData {
479
+ cartId: string;
480
+ promoCodeDiscount: number | null;
481
+ subtotal: number;
482
+ itemCount: number;
483
+ items: Record<string, ICartItem>;
484
+ retailers: Record<string, ICartRetailer>;
485
+ location: {
486
+ placesId: string;
487
+ formattedAddress: string;
488
+ address: IAddressAddress;
489
+ coordinates: IAddressCoordinates;
490
+ } | null;
491
+ }
492
+
493
+ export interface ICartItem {
494
+ id: string;
495
+ variantId: string;
496
+ liquidId: string;
497
+ retailerId: string;
498
+ partNumber: string;
499
+ fulfillmentId: string;
500
+ upc: string;
501
+ sku: string;
502
+ salsifyGrouping: string;
503
+ catPath: string;
504
+ volume: string;
505
+ uom: string;
506
+ pack: boolean;
507
+ packDesc: string;
508
+ container: string;
509
+ containerType: string;
510
+ name: string;
511
+ brand: string;
512
+ size: string;
513
+ price: number;
514
+ quantity: number;
515
+ maxQuantity: number;
516
+ unitPrice: number;
517
+ mainImage: string;
518
+ attributes: ICartItemAttributes;
519
+ }
520
+
521
+ export interface ICartItemAttributes {
522
+ engraving: ICartItemEngraving;
523
+ presale: IProductPresale;
524
+ }
525
+
526
+ export interface ICartItemEngraving {
527
+ isEngravable: boolean;
528
+ hasEngraving: boolean;
529
+ fee: number;
530
+ maxCharsPerLine: number;
531
+ maxLines: number;
532
+ location: string;
533
+ lines: string[];
534
+ }
535
+
536
+ export interface IProductPresale {
537
+ canPurchaseOn: string | null;
538
+ estimatedShipBy: string | null;
539
+ isActive: boolean;
540
+ language: string;
541
+ }
542
+
543
+ export interface ICartRetailer {
544
+ id: string;
545
+ name: string;
546
+ subtotal: number;
547
+ itemsQuantity: number;
548
+ fulfillments: Record<string, ICartFulfillment>;
549
+ }
550
+
551
+ export interface ICartFulfillment {
552
+ id: string;
553
+ canEngrave: boolean;
554
+ type: FulfillmentType;
555
+ expectation: string;
556
+ engravingExpectation: string;
557
+ itemIds: string[];
558
+ subtotal: number;
559
+ hasUnmetMinimumPurchaseAmount: boolean;
560
+ minimumPurchaseAmount: number;
561
+ }
562
+
563
+ export interface IAddressAddress {
564
+ one: string;
565
+ two: string;
566
+ city: string;
567
+ state: string;
568
+ zip: string;
569
+ country: string;
570
+ }
571
+
572
+ export interface IAddressCoordinates {
573
+ latitude: number;
574
+ longitude: number;
575
+ }
576
+ ```
577
+
578
+ **Example**
579
+
580
+ ```js
581
+ window.addEventListener('lce:actions.cart_loaded', (event) => {
582
+ const { data } = event.detail;
583
+ console.log(`Cart ${data.cartId} has ${data.itemCount} items`);
584
+ });
585
+ ```
586
+
587
+ ### `lce:actions.cart_opened`
588
+
589
+ Cart drawer opened.
590
+
591
+ **Data shape (TypeScript)**
592
+
593
+ ```ts
594
+ export type CartOpenedEventData = boolean;
595
+ ```
596
+
597
+ **Example**
598
+
599
+ ```js
600
+ window.addEventListener('lce:actions.cart_opened', () => {
601
+ document.body.classList.add('cart-open');
602
+ });
603
+ ```
604
+
605
+ ### `lce:actions.cart_closed`
606
+
607
+ Cart drawer closed.
608
+
609
+ **Data shape (TypeScript)**
610
+
611
+ ```ts
612
+ export type CartClosedEventData = boolean;
613
+ ```
614
+
615
+ **Example**
616
+
617
+ ```js
618
+ window.addEventListener('lce:actions.cart_closed', () => {
619
+ document.body.classList.remove('cart-open');
620
+ });
621
+ ```
622
+
623
+ ### `lce:actions.cart_updated`
624
+
625
+ Cart totals/items changed.
626
+
627
+ **Data shape (TypeScript)**
628
+
629
+ ```ts
630
+ export interface ICartUpdatedEventData {
631
+ previous: IBaseCartEventData;
632
+ current: IBaseCartEventData;
633
+ }
634
+
635
+ export type FulfillmentType = 'onDemand' | 'shipping';
636
+
637
+ export interface IBaseCartEventData {
638
+ cartId: string;
639
+ promoCodeDiscount: number | null;
640
+ subtotal: number;
641
+ itemCount: number;
642
+ items: Record<string, ICartItem>;
643
+ retailers: Record<string, ICartRetailer>;
644
+ location: {
645
+ placesId: string;
646
+ formattedAddress: string;
647
+ address: IAddressAddress;
648
+ coordinates: IAddressCoordinates;
649
+ } | null;
650
+ }
651
+
652
+ export interface ICartItem {
653
+ id: string;
654
+ variantId: string;
655
+ liquidId: string;
656
+ retailerId: string;
657
+ partNumber: string;
658
+ fulfillmentId: string;
659
+ upc: string;
660
+ sku: string;
661
+ salsifyGrouping: string;
662
+ catPath: string;
663
+ volume: string;
664
+ uom: string;
665
+ pack: boolean;
666
+ packDesc: string;
667
+ container: string;
668
+ containerType: string;
669
+ name: string;
670
+ brand: string;
671
+ size: string;
672
+ price: number;
673
+ quantity: number;
674
+ maxQuantity: number;
675
+ unitPrice: number;
676
+ mainImage: string;
677
+ attributes: ICartItemAttributes;
678
+ }
679
+
680
+ export interface ICartItemAttributes {
681
+ engraving: ICartItemEngraving;
682
+ presale: IProductPresale;
683
+ }
684
+
685
+ export interface ICartItemEngraving {
686
+ isEngravable: boolean;
687
+ hasEngraving: boolean;
688
+ fee: number;
689
+ maxCharsPerLine: number;
690
+ maxLines: number;
691
+ location: string;
692
+ lines: string[];
693
+ }
694
+
695
+ export interface IProductPresale {
696
+ canPurchaseOn: string | null;
697
+ estimatedShipBy: string | null;
698
+ isActive: boolean;
699
+ language: string;
700
+ }
701
+
702
+ export interface ICartRetailer {
703
+ id: string;
704
+ name: string;
705
+ subtotal: number;
706
+ itemsQuantity: number;
707
+ fulfillments: Record<string, ICartFulfillment>;
708
+ }
709
+
710
+ export interface ICartFulfillment {
711
+ id: string;
712
+ canEngrave: boolean;
713
+ type: FulfillmentType;
714
+ expectation: string;
715
+ engravingExpectation: string;
716
+ itemIds: string[];
717
+ subtotal: number;
718
+ hasUnmetMinimumPurchaseAmount: boolean;
719
+ minimumPurchaseAmount: number;
720
+ }
721
+
722
+ export interface IAddressAddress {
723
+ one: string;
724
+ two: string;
725
+ city: string;
726
+ state: string;
727
+ zip: string;
728
+ country: string;
729
+ }
730
+
731
+ export interface IAddressCoordinates {
732
+ latitude: number;
733
+ longitude: number;
734
+ }
735
+ ```
736
+
737
+ **Example**
738
+
739
+ ```js
740
+ window.addEventListener('lce:actions.cart_updated', (event) => {
741
+ const { data } = event.detail;
742
+ const delta = data.current.itemCount - data.previous.itemCount;
743
+ if (delta !== 0) console.log('Item count changed by', delta);
744
+ });
745
+ ```
746
+
747
+ ### `lce:actions.cart_reset`
748
+
749
+ Cart cleared.
750
+
751
+ **Data shape (TypeScript)**
752
+
753
+ ```ts
754
+ export type CartResetEventData = boolean;
755
+ ```
756
+
757
+ **Example**
758
+
759
+ ```js
760
+ window.addEventListener('lce:actions.cart_reset', () => {
761
+ console.log('Cart reset');
762
+ });
763
+ ```
764
+
765
+ ### `lce:actions.cart_failed`
766
+
767
+ Cart operation failed.
768
+
769
+ **Data shape (TypeScript)**
770
+
771
+ ```ts
772
+ export interface ICartFailedEventData {
773
+ cartId: string;
774
+ message: string;
775
+ }
776
+ ```
777
+
778
+ **Example**
779
+
780
+ ```js
781
+ window.addEventListener('lce:actions.cart_failed', (event) => {
782
+ const { data } = event.detail;
783
+ console.error('Cart error:', data.message);
784
+ });
785
+ ```
786
+
787
+ ### `lce:actions.cart_item_added`
788
+
789
+ Item added to cart.
790
+
791
+ **Data shape (TypeScript)**
792
+
793
+ ```ts
794
+ export interface ICartItemAddedEventData {
795
+ cartId: string;
796
+ itemId: string;
797
+ fulfillmentId: string;
798
+ partNumber: string;
799
+ quantity: number;
800
+ engravingLines?: string[];
801
+ }
802
+ ```
803
+
804
+ **Example**
805
+
806
+ ```js
807
+ window.addEventListener('lce:actions.cart_item_added', (event) => {
808
+ const { data } = event.detail;
809
+ console.log(`Added item ${data.itemId} (qty ${data.quantity})`);
810
+ });
811
+ ```
812
+
813
+ ### `lce:actions.cart_item_removed`
814
+
815
+ Item removed from cart.
816
+
817
+ **Data shape (TypeScript)**
818
+
819
+ ```ts
820
+ export interface ICartItemRemovedEventData {
821
+ cartId: string;
822
+ itemId: string;
823
+ }
824
+ ```
825
+
826
+ **Example**
827
+
828
+ ```js
829
+ window.addEventListener('lce:actions.cart_item_removed', (event) => {
830
+ const { data } = event.detail;
831
+ console.log('Removed item', data.itemId);
832
+ });
833
+ ```
834
+
835
+ ### `lce:actions.cart_item_quantity_increase`
836
+
837
+ Cart item quantity increased.
838
+
839
+ **Data shape (TypeScript)**
840
+
841
+ ```ts
842
+ export interface ICartItemQuantityChangedEventData {
843
+ cartId: string;
844
+ itemId: string;
845
+ quantity: number;
846
+ previousQuantity: number;
847
+ }
848
+ ```
849
+
850
+ **Example**
851
+
852
+ ```js
853
+ window.addEventListener('lce:actions.cart_item_quantity_increase', (event) => {
854
+ const { data } = event.detail;
855
+ console.log('Quantity increased to', data.quantity);
856
+ });
857
+ ```
858
+
859
+ ### `lce:actions.cart_item_quantity_decrease`
860
+
861
+ Cart item quantity decreased.
862
+
863
+ **Data shape (TypeScript)**
864
+
865
+ ```ts
866
+ export interface ICartItemQuantityChangedEventData {
867
+ cartId: string;
868
+ itemId: string;
869
+ quantity: number;
870
+ previousQuantity: number;
871
+ }
872
+ ```
873
+
874
+ **Example**
875
+
876
+ ```js
877
+ window.addEventListener('lce:actions.cart_item_quantity_decrease', (event) => {
878
+ const { data } = event.detail;
879
+ console.log('Quantity decreased to', data.quantity);
880
+ });
881
+ ```
882
+
883
+ ### `lce:actions.cart_item_engraving_updated`
884
+
885
+ Engraving text updated for a cart item.
886
+
887
+ **Data shape (TypeScript)**
888
+
889
+ ```ts
890
+ export interface ICartItemEngravingUpdatedEventData {
891
+ cartId: string;
892
+ itemId: string;
893
+ engravingLines: string[];
894
+ previousEngravingLines: string[];
895
+ }
896
+ ```
897
+
898
+ **Example**
899
+
900
+ ```js
901
+ window.addEventListener('lce:actions.cart_item_engraving_updated', (event) => {
902
+ const { data } = event.detail;
903
+ console.log('Updated engraving for', data.itemId);
904
+ });
905
+ ```
906
+
907
+ ### `lce:actions.cart_promo_code_applied`
908
+
909
+ Promo code applied to cart.
910
+
911
+ **Data shape (TypeScript)**
912
+
913
+ ```ts
914
+ export interface ICartPromoCodeEventData {
915
+ cartId: string;
916
+ discount?: number;
917
+ newSubtotal?: number;
918
+ }
919
+ ```
920
+
921
+ **Example**
922
+
923
+ ```js
924
+ window.addEventListener('lce:actions.cart_promo_code_applied', (event) => {
925
+ const { data } = event.detail;
926
+ console.log('Promo applied, discount:', data.discount);
927
+ });
928
+ ```
929
+
930
+ ### `lce:actions.cart_promo_code_removed`
931
+
932
+ Promo code removed from cart.
933
+
934
+ **Data shape (TypeScript)**
935
+
936
+ ```ts
937
+ export interface ICartPromoCodeEventData {
938
+ cartId: string;
939
+ discount?: number;
940
+ newSubtotal?: number;
941
+ }
942
+ ```
943
+
944
+ **Example**
945
+
946
+ ```js
947
+ window.addEventListener('lce:actions.cart_promo_code_removed', (event) => {
948
+ const { data } = event.detail;
949
+ console.log('Promo removed');
950
+ });
951
+ ```
952
+
953
+ ### `lce:actions.cart_promo_code_failed`
954
+
955
+ Promo code failed validation.
956
+
957
+ **Data shape (TypeScript)**
958
+
959
+ ```ts
960
+ export interface ICartPromoCodeFailedEventData {
961
+ cartId: string;
962
+ error: string;
963
+ }
964
+ ```
965
+
966
+ **Example**
967
+
968
+ ```js
969
+ window.addEventListener('lce:actions.cart_promo_code_failed', (event) => {
970
+ const { data } = event.detail;
971
+ console.error('Promo failed:', data.error);
972
+ });
973
+ ```
974
+
975
+ ### `lce:actions.cart_product_add_success`
976
+
977
+ Programmatic add-to-cart succeeded.
978
+
979
+ **Data shape (TypeScript)**
980
+
981
+ ```ts
982
+ export interface ICartProductAddEventData {
983
+ cartId: string;
984
+ itemsAdded: number;
985
+ identifiers: string[];
986
+ }
987
+ ```
988
+
989
+ **Example**
990
+
991
+ ```js
992
+ window.addEventListener('lce:actions.cart_product_add_success', (event) => {
993
+ const { data } = event.detail;
994
+ console.log(`Added ${data.itemsAdded} products`);
995
+ });
996
+ ```
997
+
998
+ ### `lce:actions.cart_product_add_failed`
999
+
1000
+ Programmatic add-to-cart failed.
1001
+
1002
+ **Data shape (TypeScript)**
1003
+
1004
+ ```ts
1005
+ export interface ICartProductAddFailedEventData {
1006
+ cartId: string;
1007
+ identifiers: string[];
1008
+ error: string;
1009
+ }
1010
+ ```
1011
+
1012
+ **Example**
1013
+
1014
+ ```js
1015
+ window.addEventListener('lce:actions.cart_product_add_failed', (event) => {
1016
+ const { data } = event.detail;
1017
+ console.error('Product add failed:', data.error);
1018
+ });
1019
+ ```
1020
+
1021
+ ## Checkout events
1022
+
1023
+ ### `lce:actions.checkout_loaded`
1024
+
1025
+ Checkout state loaded.
1026
+
1027
+ **Data shape (TypeScript)**
1028
+
1029
+ ```ts
1030
+ export interface IBaseCheckoutEventData {
1031
+ token: string;
1032
+ cartId: string;
1033
+ isGift: boolean;
1034
+ billingSameAsShipping: boolean;
1035
+ marketingPreferences: ICheckoutMarketingPreferences;
1036
+ hasPromoCode: boolean;
1037
+ hasGiftCards: boolean;
1038
+ amounts: ICheckoutAmounts;
1039
+ itemCount: number;
1040
+ items: Record<string, ICheckoutItem>;
1041
+ }
1042
+
1043
+ export interface ICheckoutMarketingPreferences {
1044
+ canEmail: boolean;
1045
+ canSms: boolean;
1046
+ }
1047
+
1048
+ export interface ICheckoutAmounts {
1049
+ subtotal: number;
1050
+ engraving: number;
1051
+ service: number;
1052
+ shipping: number;
1053
+ delivery: number;
1054
+ platform: number;
1055
+ discounts: number;
1056
+ giftCards: number;
1057
+ tax: number;
1058
+ tip: number;
1059
+ total: number;
1060
+ }
1061
+
1062
+ export interface ICheckoutItem {
1063
+ variantId: string;
1064
+ cartItemId: string;
1065
+ liquidId: string;
1066
+ retailerId: string;
1067
+ fulfillmentId: string;
1068
+ salsifyPid?: string;
1069
+ salsifyGrouping?: string;
1070
+ name: string;
1071
+ catPath: string;
1072
+ volume: string;
1073
+ uom: string;
1074
+ proof: string;
1075
+ abv: string;
1076
+ containerType: string;
1077
+ container: string;
1078
+ size: string;
1079
+ pack: boolean;
1080
+ packDesc: string;
1081
+ mainImage: string;
1082
+ brand: string;
1083
+ partNumber: string;
1084
+ upc: string;
1085
+ sku: string;
1086
+ price: number;
1087
+ unitPrice: number;
1088
+ quantity: number;
1089
+ tax: number;
1090
+ unitTax: number;
1091
+ bottleDeposits: number;
1092
+ attributes: ICheckoutItemAttributes;
1093
+ }
1094
+
1095
+ export interface ICheckoutItemAttributes {
1096
+ engraving: ICheckoutItemEngraving;
1097
+ presale: IProductPresale;
1098
+ }
1099
+
1100
+ export interface ICheckoutItemEngraving {
1101
+ isEngravable: boolean;
1102
+ hasEngraving: boolean;
1103
+ fee: number;
1104
+ maxCharsPerLine: number;
1105
+ maxLines: number;
1106
+ location: string;
1107
+ lines: string[];
1108
+ }
1109
+
1110
+ export interface IProductPresale {
1111
+ canPurchaseOn: string | null;
1112
+ estimatedShipBy: string | null;
1113
+ isActive: boolean;
1114
+ language: string;
1115
+ }
1116
+ ```
1117
+
1118
+ **Example**
1119
+
1120
+ ```js
1121
+ window.addEventListener('lce:actions.checkout_loaded', (event) => {
1122
+ const { data } = event.detail;
1123
+ console.log('Checkout loaded for cart', data.cartId);
1124
+ });
1125
+ ```
1126
+
1127
+ ### `lce:actions.checkout_opened`
1128
+
1129
+ Checkout drawer opened.
1130
+
1131
+ **Data shape (TypeScript)**
1132
+
1133
+ ```ts
1134
+ export type CheckoutOpenedEventData = boolean;
1135
+ ```
1136
+
1137
+ **Example**
1138
+
1139
+ ```js
1140
+ window.addEventListener('lce:actions.checkout_opened', () => {
1141
+ console.log('Checkout opened');
1142
+ });
1143
+ ```
1144
+
1145
+ ### `lce:actions.checkout_closed`
1146
+
1147
+ Checkout drawer closed.
1148
+
1149
+ **Data shape (TypeScript)**
1150
+
1151
+ ```ts
1152
+ export type CheckoutClosedEventData = boolean;
1153
+ ```
1154
+
1155
+ **Example**
1156
+
1157
+ ```js
1158
+ window.addEventListener('lce:actions.checkout_closed', () => {
1159
+ console.log('Checkout closed');
1160
+ });
1161
+ ```
1162
+
1163
+ ### `lce:actions.checkout_failed`
1164
+
1165
+ Checkout failed to load or operate.
1166
+
1167
+ **Data shape (TypeScript)**
1168
+
1169
+ ```ts
1170
+ export interface ICheckoutFailedEventData {
1171
+ message: string;
1172
+ }
1173
+ ```
1174
+
1175
+ **Example**
1176
+
1177
+ ```js
1178
+ window.addEventListener('lce:actions.checkout_failed', (event) => {
1179
+ const { data } = event.detail;
1180
+ console.error('Checkout error:', data.message);
1181
+ });
1182
+ ```
1183
+
1184
+ ### `lce:actions.checkout_customer_information_updated`
1185
+
1186
+ Customer info updated.
1187
+
1188
+ **Data shape (TypeScript)**
1189
+
1190
+ ```ts
1191
+ export interface ICheckoutCustomerInformationUpdatedEventData {
1192
+ cartId: string;
1193
+ }
1194
+ ```
1195
+
1196
+ **Example**
1197
+
1198
+ ```js
1199
+ window.addEventListener('lce:actions.checkout_customer_information_updated', (event) => {
1200
+ const { data } = event.detail;
1201
+ console.log('Customer info updated for cart', data.cartId);
1202
+ });
1203
+ ```
1204
+
1205
+ ### `lce:actions.checkout_billing_information_updated`
1206
+
1207
+ Billing info updated.
1208
+
1209
+ **Data shape (TypeScript)**
1210
+
1211
+ ```ts
1212
+ export interface ICheckoutBillingInformationUpdatedEventData {
1213
+ cartId: string;
1214
+ }
1215
+ ```
1216
+
1217
+ **Example**
1218
+
1219
+ ```js
1220
+ window.addEventListener('lce:actions.checkout_billing_information_updated', (event) => {
1221
+ const { data } = event.detail;
1222
+ console.log('Billing info updated for cart', data.cartId);
1223
+ });
1224
+ ```
1225
+
1226
+ ### `lce:actions.checkout_gift_information_updated`
1227
+
1228
+ Gift recipient info updated.
1229
+
1230
+ **Data shape (TypeScript)**
1231
+
1232
+ ```ts
1233
+ export interface ICheckoutGiftInformationUpdatedEventData {
1234
+ cartId: string;
1235
+ }
1236
+ ```
1237
+
1238
+ **Example**
1239
+
1240
+ ```js
1241
+ window.addEventListener('lce:actions.checkout_gift_information_updated', (event) => {
1242
+ const { data } = event.detail;
1243
+ console.log('Gift info updated for cart', data.cartId);
1244
+ });
1245
+ ```
1246
+
1247
+ ### `lce:actions.checkout_is_gift_toggled`
1248
+
1249
+ Gift mode toggled.
1250
+
1251
+ **Data shape (TypeScript)**
1252
+
1253
+ ```ts
1254
+ export interface ICheckoutToggleEventData {
1255
+ cartId: string;
1256
+ isActive: boolean;
1257
+ previousIsActive: boolean;
1258
+ }
1259
+ ```
1260
+
1261
+ **Example**
1262
+
1263
+ ```js
1264
+ window.addEventListener('lce:actions.checkout_is_gift_toggled', (event) => {
1265
+ const { data } = event.detail;
1266
+ console.log('Gift mode:', data.isActive);
1267
+ });
1268
+ ```
1269
+
1270
+ ### `lce:actions.checkout_billing_same_as_shipping_toggled`
1271
+
1272
+ Billing same-as-shipping toggled.
1273
+
1274
+ **Data shape (TypeScript)**
1275
+
1276
+ ```ts
1277
+ export interface ICheckoutToggleEventData {
1278
+ cartId: string;
1279
+ isActive: boolean;
1280
+ previousIsActive: boolean;
1281
+ }
1282
+ ```
1283
+
1284
+ **Example**
1285
+
1286
+ ```js
1287
+ window.addEventListener('lce:actions.checkout_billing_same_as_shipping_toggled', (event) => {
1288
+ const { data } = event.detail;
1289
+ console.log('Billing same as shipping:', data.isActive);
1290
+ });
1291
+ ```
1292
+
1293
+ ### `lce:actions.checkout_marketing_preferences_toggled`
1294
+
1295
+ Marketing preference toggled.
1296
+
1297
+ **Data shape (TypeScript)**
1298
+
1299
+ ```ts
1300
+ export interface ICheckoutMarketingPreferencesToggleEventData {
1301
+ cartId: string;
1302
+ fieldName: 'canEmail' | 'canSms';
1303
+ isActive: boolean;
1304
+ previousIsActive: boolean;
1305
+ }
1306
+ ```
1307
+
1308
+ **Example**
1309
+
1310
+ ```js
1311
+ window.addEventListener('lce:actions.checkout_marketing_preferences_toggled', (event) => {
1312
+ const { data } = event.detail;
1313
+ console.log(`Marketing ${data.fieldName}:`, data.isActive);
1314
+ });
1315
+ ```
1316
+
1317
+ ### `lce:actions.checkout_item_removed`
1318
+
1319
+ Item removed during checkout.
1320
+
1321
+ **Data shape (TypeScript)**
1322
+
1323
+ ```ts
1324
+ export interface ICheckoutItemRemovedEventData {
1325
+ cartId: string;
1326
+ cartItemId: string;
1327
+ }
1328
+ ```
1329
+
1330
+ **Example**
1331
+
1332
+ ```js
1333
+ window.addEventListener('lce:actions.checkout_item_removed', (event) => {
1334
+ const { data } = event.detail;
1335
+ console.log('Checkout item removed', data.cartItemId);
1336
+ });
1337
+ ```
1338
+
1339
+ ### `lce:actions.checkout_item_quantity_increase`
1340
+
1341
+ Checkout item quantity increased.
1342
+
1343
+ **Data shape (TypeScript)**
1344
+
1345
+ ```ts
1346
+ export interface ICheckoutItemQuantityChangedEventData {
1347
+ cartId: string;
1348
+ cartItemId: string;
1349
+ quantity: number;
1350
+ previousQuantity: number;
1351
+ }
1352
+ ```
1353
+
1354
+ **Example**
1355
+
1356
+ ```js
1357
+ window.addEventListener('lce:actions.checkout_item_quantity_increase', (event) => {
1358
+ const { data } = event.detail;
1359
+ console.log('Checkout quantity increased to', data.quantity);
1360
+ });
1361
+ ```
1362
+
1363
+ ### `lce:actions.checkout_item_quantity_decrease`
1364
+
1365
+ Checkout item quantity decreased.
1366
+
1367
+ **Data shape (TypeScript)**
1368
+
1369
+ ```ts
1370
+ export interface ICheckoutItemQuantityChangedEventData {
1371
+ cartId: string;
1372
+ cartItemId: string;
1373
+ quantity: number;
1374
+ previousQuantity: number;
1375
+ }
1376
+ ```
1377
+
1378
+ **Example**
1379
+
1380
+ ```js
1381
+ window.addEventListener('lce:actions.checkout_item_quantity_decrease', (event) => {
1382
+ const { data } = event.detail;
1383
+ console.log('Checkout quantity decreased to', data.quantity);
1384
+ });
1385
+ ```
1386
+
1387
+ ### `lce:actions.checkout_item_engraving_updated`
1388
+
1389
+ Engraving text updated for a checkout item.
1390
+
1391
+ **Data shape (TypeScript)**
1392
+
1393
+ ```ts
1394
+ export interface ICheckoutItemEngravingUpdatedEventData {
1395
+ cartId: string;
1396
+ cartItemId: string;
1397
+ engravingLines: string[];
1398
+ previousEngravingLines: string[];
1399
+ }
1400
+ ```
1401
+
1402
+ **Example**
1403
+
1404
+ ```js
1405
+ window.addEventListener('lce:actions.checkout_item_engraving_updated', (event) => {
1406
+ const { data } = event.detail;
1407
+ console.log('Checkout engraving updated for', data.cartItemId);
1408
+ });
1409
+ ```
1410
+
1411
+ ### `lce:actions.checkout_tip_updated`
1412
+
1413
+ Delivery tips updated.
1414
+
1415
+ **Data shape (TypeScript)**
1416
+
1417
+ ```ts
1418
+ export interface ICheckoutTipUpdatedEventData {
1419
+ cartId: string;
1420
+ deliveryTips: Array<{
1421
+ fulfillmentId: string;
1422
+ tip: number;
1423
+ }>;
1424
+ previousDeliveryTips: Array<{
1425
+ fulfillmentId: string;
1426
+ tip: number;
1427
+ }>;
1428
+ }
1429
+ ```
1430
+
1431
+ **Example**
1432
+
1433
+ ```js
1434
+ window.addEventListener('lce:actions.checkout_tip_updated', (event) => {
1435
+ const { data } = event.detail;
1436
+ console.log('Tips updated for cart', data.cartId);
1437
+ });
1438
+ ```
1439
+
1440
+ ### `lce:actions.checkout_submit_started`
1441
+
1442
+ Checkout submit started.
1443
+
1444
+ **Data shape (TypeScript)**
1445
+
1446
+ ```ts
1447
+ export interface ICheckoutSubmitStartedEventData {
1448
+ started: boolean;
1449
+ }
1450
+ ```
1451
+
1452
+ **Example**
1453
+
1454
+ ```js
1455
+ window.addEventListener('lce:actions.checkout_submit_started', (event) => {
1456
+ const { data } = event.detail;
1457
+ if (data.started) console.log('Checkout submit started');
1458
+ });
1459
+ ```
1460
+
1461
+ ### `lce:actions.checkout_submit_completed`
1462
+
1463
+ Checkout completed successfully.
1464
+
1465
+ **Data shape (TypeScript)**
1466
+
1467
+ ```ts
1468
+ export interface ICheckoutSubmitCompletedEventData {
1469
+ orderNumber: string;
1470
+ orderTotal: number;
1471
+ }
1472
+ ```
1473
+
1474
+ **Example**
1475
+
1476
+ ```js
1477
+ window.addEventListener('lce:actions.checkout_submit_completed', (event) => {
1478
+ const { data } = event.detail;
1479
+ console.log('Order completed:', data.orderNumber);
1480
+ });
1481
+ ```
1482
+
1483
+ ### `lce:actions.checkout_submit_failed`
1484
+
1485
+ Checkout submission failed.
1486
+
1487
+ **Data shape (TypeScript)**
1488
+
1489
+ ```ts
1490
+ export interface ICheckoutSubmitFailedEventData {
1491
+ message: string;
1492
+ }
1493
+ ```
1494
+
1495
+ **Example**
1496
+
1497
+ ```js
1498
+ window.addEventListener('lce:actions.checkout_submit_failed', (event) => {
1499
+ const { data } = event.detail;
1500
+ console.error('Checkout submit failed:', data.message);
1501
+ });
1502
+ ```
1503
+
1504
+ ### `lce:actions.checkout_promo_code_applied`
1505
+
1506
+ Promo code applied in checkout.
1507
+
1508
+ **Data shape (TypeScript)**
1509
+
1510
+ ```ts
1511
+ export interface ICheckoutPromoCodeEventData {
1512
+ cartId: string;
1513
+ discount?: number;
1514
+ newTotal?: number;
1515
+ }
1516
+ ```
1517
+
1518
+ **Example**
1519
+
1520
+ ```js
1521
+ window.addEventListener('lce:actions.checkout_promo_code_applied', (event) => {
1522
+ const { data } = event.detail;
1523
+ console.log('Checkout promo applied:', data.discount);
1524
+ });
1525
+ ```
1526
+
1527
+ ### `lce:actions.checkout_promo_code_removed`
1528
+
1529
+ Promo code removed in checkout.
1530
+
1531
+ **Data shape (TypeScript)**
1532
+
1533
+ ```ts
1534
+ export interface ICheckoutPromoCodeEventData {
1535
+ cartId: string;
1536
+ discount?: number;
1537
+ newTotal?: number;
1538
+ }
1539
+ ```
1540
+
1541
+ **Example**
1542
+
1543
+ ```js
1544
+ window.addEventListener('lce:actions.checkout_promo_code_removed', (event) => {
1545
+ const { data } = event.detail;
1546
+ console.log('Checkout promo removed');
1547
+ });
1548
+ ```
1549
+
1550
+ ### `lce:actions.checkout_promo_code_failed`
1551
+
1552
+ Promo code failed in checkout.
1553
+
1554
+ **Data shape (TypeScript)**
1555
+
1556
+ ```ts
1557
+ export interface ICheckoutPromoCodeFailedEventData {
1558
+ cartId: string;
1559
+ error: string;
1560
+ }
1561
+ ```
1562
+
1563
+ **Example**
1564
+
1565
+ ```js
1566
+ window.addEventListener('lce:actions.checkout_promo_code_failed', (event) => {
1567
+ const { data } = event.detail;
1568
+ console.error('Checkout promo failed:', data.error);
1569
+ });
1570
+ ```
1571
+
1572
+ ### `lce:actions.checkout_gift_card_applied`
1573
+
1574
+ Gift card applied in checkout.
1575
+
1576
+ **Data shape (TypeScript)**
1577
+
1578
+ ```ts
1579
+ export interface ICheckoutGiftCardEventData {
1580
+ cartId: string;
1581
+ newTotal?: number;
1582
+ }
1583
+ ```
1584
+
1585
+ **Example**
1586
+
1587
+ ```js
1588
+ window.addEventListener('lce:actions.checkout_gift_card_applied', (event) => {
1589
+ const { data } = event.detail;
1590
+ console.log('Gift card applied, new total:', data.newTotal);
1591
+ });
1592
+ ```
1593
+
1594
+ ### `lce:actions.checkout_gift_card_removed`
1595
+
1596
+ Gift card removed in checkout.
1597
+
1598
+ **Data shape (TypeScript)**
1599
+
1600
+ ```ts
1601
+ export interface ICheckoutGiftCardEventData {
1602
+ cartId: string;
1603
+ newTotal?: number;
1604
+ }
1605
+ ```
1606
+
1607
+ **Example**
1608
+
1609
+ ```js
1610
+ window.addEventListener('lce:actions.checkout_gift_card_removed', (event) => {
1611
+ const { data } = event.detail;
1612
+ console.log('Gift card removed');
1613
+ });
1614
+ ```
1615
+
1616
+ ### `lce:actions.checkout_gift_card_failed`
1617
+
1618
+ Gift card failed in checkout.
1619
+
1620
+ **Data shape (TypeScript)**
1621
+
1622
+ ```ts
1623
+ export interface ICheckoutGiftCardFailedEventData {
1624
+ cartId: string;
1625
+ error: string;
1626
+ }
1627
+ ```
1628
+
1629
+ **Example**
1630
+
1631
+ ```js
1632
+ window.addEventListener('lce:actions.checkout_gift_card_failed', (event) => {
1633
+ const { data } = event.detail;
1634
+ console.error('Gift card failed:', data.error);
1635
+ });
1636
+ ```
1637
+
1638
+ ### `lce:actions.checkout_product_add_success`
1639
+
1640
+ Programmatic add-to-checkout succeeded.
1641
+
1642
+ **Data shape (TypeScript)**
1643
+
1644
+ ```ts
1645
+ export interface ICheckoutProductAddEventData {
1646
+ cartId: string;
1647
+ itemsAdded: number;
1648
+ identifiers: string[];
1649
+ isPresale?: boolean;
1650
+ }
1651
+ ```
1652
+
1653
+ **Example**
1654
+
1655
+ ```js
1656
+ window.addEventListener('lce:actions.checkout_product_add_success', (event) => {
1657
+ const { data } = event.detail;
1658
+ console.log(`Checkout added ${data.itemsAdded} products`);
1659
+ });
1660
+ ```
1661
+
1662
+ ### `lce:actions.checkout_product_add_failed`
1663
+
1664
+ Programmatic add-to-checkout failed.
1665
+
1666
+ **Data shape (TypeScript)**
1667
+
1668
+ ```ts
1669
+ export interface ICheckoutProductAddFailedEventData {
1670
+ cartId: string;
1671
+ identifiers: string[];
1672
+ error: string;
1673
+ isPresale?: boolean;
1674
+ }
1675
+ ```
1676
+
1677
+ **Example**
1678
+
1679
+ ```js
1680
+ window.addEventListener('lce:actions.checkout_product_add_failed', (event) => {
1681
+ const { data } = event.detail;
1682
+ console.error('Checkout product add failed:', data.error);
1683
+ });
1684
+ ```
1685
+
1686
+ ## Form events
1687
+
1688
+ ### `lce:forms.customer`
1689
+
1690
+ Fires when a customer form field changes in checkout.
1691
+
1692
+ **Data shape (TypeScript)**
1693
+
1694
+ ```ts
1695
+ export interface IFormEventData {
1696
+ fieldName: string;
1697
+ fieldValue?: string;
1698
+ }
1699
+ ```
1700
+
1701
+ **Example**
1702
+
1703
+ ```js
1704
+ window.addEventListener('lce:forms.customer', (event) => {
1705
+ const { data } = event.detail;
1706
+ console.log('Customer field changed:', data.fieldName);
1707
+ });
1708
+ ```
1709
+
1710
+ ### `lce:forms.billing`
1711
+
1712
+ Fires when a billing form field changes in checkout.
1713
+
1714
+ **Data shape (TypeScript)**
1715
+
1716
+ ```ts
1717
+ export interface IFormEventData {
1718
+ fieldName: string;
1719
+ fieldValue?: string;
1720
+ }
1721
+ ```
1722
+
1723
+ **Example**
1724
+
1725
+ ```js
1726
+ window.addEventListener('lce:forms.billing', (event) => {
1727
+ const { data } = event.detail;
1728
+ console.log('Billing field changed:', data.fieldName);
1729
+ });
1730
+ ```
1731
+
1732
+ ### `lce:forms.gift`
1733
+
1734
+ Fires when a gift form field changes in checkout.
1735
+
1736
+ **Data shape (TypeScript)**
1737
+
1738
+ ```ts
1739
+ export interface IFormEventData {
1740
+ fieldName: string;
1741
+ fieldValue?: string;
1742
+ }
1743
+ ```
1744
+
1745
+ **Example**
1746
+
1747
+ ```js
1748
+ window.addEventListener('lce:forms.gift', (event) => {
1749
+ const { data } = event.detail;
1750
+ console.log('Gift field changed:', data.fieldName);
1751
+ });
1752
+ ```
1753
+
1754
+ ## Analytics example
1755
+
1756
+ ```js
1757
+ window.addEventListener('lce:actions.checkout_submit_completed', (event) => {
1758
+ const { data } = event.detail;
1759
+ gtag('event', 'purchase', {
1760
+ transaction_id: data.orderNumber,
1761
+ value: data.orderTotal / 100,
1762
+ currency: 'USD'
1763
+ });
1764
+ });
1765
+ ```