@magic-spells/cart-panel 0.1.0 → 0.1.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.
@@ -1,15 +1,18 @@
1
1
  cart-item {
2
2
  --cart-item-processing-duration: 250ms;
3
3
  --cart-item-destroying-duration: 600ms;
4
+ --cart-item-appearing-duration: 400ms;
4
5
  --cart-item-shadow-color: rgba(0, 0, 0, 0.15);
5
6
  --cart-item-shadow-color-strong: rgba(0, 0, 0, 0.5);
6
- --cart-item-processing-bg: rgba(100, 100, 100, 0.2);
7
7
  --cart-item-destroying-bg: rgba(0, 0, 0, 0.1);
8
8
  --cart-item-processing-scale: 0.98;
9
9
  --cart-item-destroying-scale: 0.85;
10
+ --cart-item-appearing-scale: 0.9;
10
11
  --cart-item-processing-blur: 1px;
11
12
  --cart-item-destroying-blur: 10px;
13
+ --cart-item-appearing-blur: 2px;
12
14
  --cart-item-destroying-opacity: 0.2;
15
+ --cart-item-appearing-opacity: 0.5;
13
16
  --cart-item-destroying-brightness: 0.6;
14
17
  --cart-item-destroying-saturate: 0.3;
15
18
  display: block;
@@ -31,57 +34,76 @@ cart-item::after {
31
34
  left: 0px;
32
35
  transition: background-color var(--cart-item-processing-duration) ease;
33
36
  }
34
- cart-item[data-state=ready] cart-item-content {
37
+ cart-item[state=ready] {
38
+ transition: filter var(--cart-item-processing-duration) ease-out, background-color var(--cart-item-processing-duration) ease-out, box-shadow var(--cart-item-processing-duration) ease-out, height var(--cart-item-appearing-duration) ease-out;
39
+ }
40
+ cart-item[state=ready] cart-item-content {
35
41
  transform: scale(1);
36
42
  filter: blur(0px);
37
43
  opacity: 1;
44
+ transition: transform var(--cart-item-appearing-duration) ease-out, filter var(--cart-item-appearing-duration) ease-out, opacity var(--cart-item-appearing-duration) ease-out;
38
45
  }
39
- cart-item[data-state=ready] cart-item-processing {
46
+ cart-item[state=ready] cart-item-processing {
40
47
  opacity: 0;
41
48
  visibility: hidden;
42
49
  }
43
- cart-item[data-state=processing] {
50
+ cart-item[state=processing] {
44
51
  box-shadow: inset 0px 2px 10px var(--cart-item-shadow-color);
45
52
  }
46
- cart-item[data-state=processing]::after {
53
+ cart-item[state=processing]::after {
47
54
  background: rgba(0, 0, 0, 0.15);
48
55
  }
49
- cart-item[data-state=processing] cart-item-content {
56
+ cart-item[state=processing] cart-item-content {
50
57
  transform: scale(var(--cart-item-processing-scale));
51
58
  filter: blur(var(--cart-item-processing-blur));
52
59
  opacity: 0.9;
53
60
  pointer-events: none;
61
+ transition: transform var(--cart-item-processing-duration) ease-out, filter var(--cart-item-processing-duration) ease-out, opacity var(--cart-item-processing-duration) ease-out;
54
62
  }
55
- cart-item[data-state=processing] cart-item-processing {
63
+ cart-item[state=processing] cart-item-processing {
56
64
  opacity: 1;
57
65
  visibility: visible;
58
66
  }
59
- cart-item[data-state=destroying] {
67
+ cart-item[state=destroying] {
60
68
  background-color: var(--cart-item-destroying-bg);
61
- box-shadow: inset 0px 4px 20px var(--cart-item-shadow-color-strong);
69
+ box-shadow: inset 0px 2px 20px var(--cart-item-shadow-color-strong);
62
70
  margin-top: 0px;
63
71
  margin-bottom: 0px;
64
72
  transition: filter var(--cart-item-destroying-duration) ease, background-color var(--cart-item-destroying-duration) ease, box-shadow var(--cart-item-destroying-duration) ease, margin var(--cart-item-destroying-duration) ease;
65
73
  }
66
- cart-item[data-state=destroying]::after {
74
+ cart-item[state=destroying]::after {
67
75
  background: rgba(0, 0, 0, 0.9);
68
76
  transition: background-color var(--cart-item-destroying-duration) ease;
69
77
  }
70
- cart-item[data-state=destroying] cart-item-content {
78
+ cart-item[state=destroying] cart-item-content {
71
79
  transition: transform var(--cart-item-destroying-duration) ease, filter var(--cart-item-destroying-duration) ease, opacity var(--cart-item-destroying-duration) ease;
72
80
  transform: scale(var(--cart-item-destroying-scale));
73
81
  filter: blur(var(--cart-item-destroying-blur)) saturate(var(--cart-item-destroying-saturate));
74
82
  opacity: var(--cart-item-destroying-opacity);
75
83
  pointer-events: none;
76
84
  }
77
- cart-item[data-state=destroying] cart-item-processing {
85
+ cart-item[state=destroying] cart-item-processing {
78
86
  opacity: 0;
79
87
  transition: opacity var(--cart-item-processing-duration) ease;
80
88
  }
89
+ cart-item[state=appearing] {
90
+ height: 0px;
91
+ overflow: hidden;
92
+ transition: height var(--cart-item-appearing-duration) ease-out, filter var(--cart-item-appearing-duration) ease-out, opacity var(--cart-item-appearing-duration) ease-out;
93
+ }
94
+ cart-item[state=appearing] cart-item-content {
95
+ transform: scale(var(--cart-item-appearing-scale));
96
+ filter: blur(var(--cart-item-appearing-blur));
97
+ opacity: var(--cart-item-appearing-opacity);
98
+ transition: transform var(--cart-item-appearing-duration) ease-out, filter var(--cart-item-appearing-duration) ease-out, opacity var(--cart-item-appearing-duration) ease-out;
99
+ }
100
+ cart-item[state=appearing] cart-item-processing {
101
+ opacity: 0;
102
+ visibility: hidden;
103
+ }
81
104
 
82
105
  cart-item-content {
83
106
  display: block;
84
- transition: transform var(--cart-item-processing-duration) ease-out, filter var(--cart-item-processing-duration) ease-out, opacity var(--cart-item-processing-duration) ease-out;
85
107
  }
86
108
 
87
109
  cart-item-processing {
@@ -99,7 +121,29 @@ cart-item-processing {
99
121
  transition: opacity var(--cart-item-processing-duration) ease-out, visibility var(--cart-item-processing-duration) ease-out;
100
122
  z-index: 10;
101
123
  }
124
+ cart-item-processing .cart-item-loader {
125
+ width: 60px;
126
+ aspect-ratio: 2;
127
+ --_g: no-repeat radial-gradient(circle closest-side, #000 90%, #0000);
128
+ background: var(--_g) 0% 50%, var(--_g) 50% 50%, var(--_g) 100% 50%;
129
+ background-size: 33.3333333333% 50%;
130
+ animation: cart-item-loader 1s infinite linear;
131
+ }
102
132
 
133
+ @keyframes cart-item-loader {
134
+ 20% {
135
+ background-position: 0% 0%, 50% 50%, 100% 50%;
136
+ }
137
+ 40% {
138
+ background-position: 0% 100%, 50% 0%, 100% 50%;
139
+ }
140
+ 60% {
141
+ background-position: 0% 50%, 50% 100%, 100% 0%;
142
+ }
143
+ 80% {
144
+ background-position: 0% 50%, 50% 50%, 100% 100%;
145
+ }
146
+ }
103
147
  :root {
104
148
  --cart-dialog-z-index: 1000;
105
149
  --cart-overlay-z-index: 1000;
@@ -1,4 +1,5 @@
1
- import '@magic-spells/cart-item';
1
+ import { CartItem } from '@magic-spells/cart-item';
2
+ export { CartItem } from '@magic-spells/cart-item';
2
3
  import '@magic-spells/focus-trap';
3
4
  import EventEmitter from '@magic-spells/event-emitter';
4
5
 
@@ -11,6 +12,7 @@ class CartDialog extends HTMLElement {
11
12
  #scrollPosition = 0;
12
13
  #currentCart = null;
13
14
  #eventEmitter;
15
+ #isInitialRender = true;
14
16
 
15
17
  /**
16
18
  * Clean up event listeners when component is removed from DOM
@@ -108,13 +110,18 @@ class CartDialog extends HTMLElement {
108
110
  }
109
111
  }
110
112
 
113
+ // Insert focus trap before the cart-panel
111
114
  _.contentPanel.parentNode.insertBefore(_.focusTrap, _.contentPanel);
115
+ // Move cart-panel inside the focus trap
112
116
  _.focusTrap.appendChild(_.contentPanel);
113
117
 
118
+ // Setup the trap - this will add focus-trap-start/end elements around the content
114
119
  _.focusTrap.setupTrap();
115
120
 
116
- // Add modal overlay
117
- _.prepend(document.createElement('cart-overlay'));
121
+ // Add modal overlay if it doesn't already exist
122
+ if (!_.querySelector('cart-overlay')) {
123
+ _.prepend(document.createElement('cart-overlay'));
124
+ }
118
125
  _.#attachListeners();
119
126
  _.#bindKeyboard();
120
127
  }
@@ -172,7 +179,7 @@ class CartDialog extends HTMLElement {
172
179
 
173
180
  // Handle close buttons
174
181
  _.addEventListener('click', (e) => {
175
- if (!e.target.closest('[data-action="hide-cart"]')) return;
182
+ if (!e.target.closest('[data-action-hide-cart]')) return;
176
183
  _.hide();
177
184
  });
178
185
 
@@ -227,9 +234,9 @@ class CartDialog extends HTMLElement {
227
234
  this.updateCartItem(cartKey, 0)
228
235
  .then((updatedCart) => {
229
236
  if (updatedCart && !updatedCart.error) {
230
- // Success - remove with animation
231
- element.destroyYourself();
237
+ // Success - let smart comparison handle the removal animation
232
238
  this.#currentCart = updatedCart;
239
+ this.#renderCartItems(updatedCart);
233
240
  this.#updateCartItems(updatedCart);
234
241
 
235
242
  // Emit cart updated and data changed events
@@ -262,8 +269,9 @@ class CartDialog extends HTMLElement {
262
269
  this.updateCartItem(cartKey, quantity)
263
270
  .then((updatedCart) => {
264
271
  if (updatedCart && !updatedCart.error) {
265
- // Success - update cart data
272
+ // Success - update cart data and refresh items
266
273
  this.#currentCart = updatedCart;
274
+ this.#renderCartItems(updatedCart);
267
275
  this.#updateCartItems(updatedCart);
268
276
  element.setState('ready');
269
277
 
@@ -284,13 +292,33 @@ class CartDialog extends HTMLElement {
284
292
  }
285
293
 
286
294
  /**
287
- * Update cart items
295
+ * Update cart items display based on cart data
288
296
  * @private
289
297
  */
290
298
  #updateCartItems(cart = null) {
291
- // Placeholder for cart item updates
292
- // Could be used to sync cart items with server data
293
- cart || this.#currentCart;
299
+ const cartData = cart || this.#currentCart;
300
+ if (!cartData) return;
301
+
302
+ // Get cart sections
303
+ const hasItemsSection = this.querySelector('[data-cart-has-items]');
304
+ const emptySection = this.querySelector('[data-cart-is-empty]');
305
+ const itemsContainer = this.querySelector('[data-content-cart-items]');
306
+
307
+ if (!hasItemsSection || !emptySection || !itemsContainer) {
308
+ console.warn(
309
+ 'Cart sections not found. Expected [data-cart-has-items], [data-cart-is-empty], and [data-content-cart-items]'
310
+ );
311
+ return;
312
+ }
313
+
314
+ // Show/hide sections based on item count
315
+ if (cartData.item_count > 0) {
316
+ hasItemsSection.style.display = 'block';
317
+ emptySection.style.display = 'none';
318
+ } else {
319
+ hasItemsSection.style.display = 'none';
320
+ emptySection.style.display = 'block';
321
+ }
294
322
  }
295
323
 
296
324
  /**
@@ -345,19 +373,157 @@ class CartDialog extends HTMLElement {
345
373
  * @returns {Promise<Object>} Cart data object
346
374
  */
347
375
  refreshCart() {
376
+ console.log('Refreshing cart...');
348
377
  return this.getCart().then((cartData) => {
378
+ console.log('Cart data received:', cartData);
349
379
  if (cartData && !cartData.error) {
350
380
  this.#currentCart = cartData;
381
+ this.#renderCartItems(cartData);
351
382
  this.#updateCartItems(cartData);
352
383
 
353
384
  // Emit cart refreshed and data changed events
354
385
  this.#emit('cart-dialog:refreshed', { cart: cartData });
355
386
  this.#emit('cart-dialog:data-changed', cartData);
387
+ } else {
388
+ console.warn('Cart data has error or is null:', cartData);
356
389
  }
357
390
  return cartData;
358
391
  });
359
392
  }
360
393
 
394
+ /**
395
+ * Remove items from DOM that are no longer in cart data
396
+ * @private
397
+ */
398
+ #removeItemsFromDOM(itemsContainer, newKeysSet) {
399
+ const currentItems = Array.from(itemsContainer.querySelectorAll('cart-item'));
400
+ const itemsToRemove = currentItems.filter((item) => !newKeysSet.has(item.getAttribute('key')));
401
+
402
+ console.log(
403
+ `Removing ${itemsToRemove.length} items:`,
404
+ itemsToRemove.map((item) => item.getAttribute('key'))
405
+ );
406
+
407
+ itemsToRemove.forEach((item) => {
408
+ item.destroyYourself();
409
+ });
410
+ }
411
+
412
+ /**
413
+ * Add new items to DOM with animation delay
414
+ * @private
415
+ */
416
+ #addItemsToDOM(itemsContainer, itemsToAdd, newKeys) {
417
+ console.log(
418
+ `Adding ${itemsToAdd.length} items:`,
419
+ itemsToAdd.map((item) => item.key || item.id)
420
+ );
421
+
422
+ // Delay adding new items by 300ms to let cart slide open first
423
+ setTimeout(() => {
424
+ itemsToAdd.forEach((itemData) => {
425
+ const cartItem = CartItem.createAnimated(itemData);
426
+ const targetIndex = newKeys.indexOf(itemData.key || itemData.id);
427
+
428
+ // Find the correct position to insert the new item
429
+ if (targetIndex === 0) {
430
+ // Insert at the beginning
431
+ itemsContainer.insertBefore(cartItem, itemsContainer.firstChild);
432
+ } else {
433
+ // Find the item that should come before this one
434
+ let insertAfter = null;
435
+ for (let i = targetIndex - 1; i >= 0; i--) {
436
+ const prevKey = newKeys[i];
437
+ const prevItem = itemsContainer.querySelector(`cart-item[key="${prevKey}"]`);
438
+ if (prevItem) {
439
+ insertAfter = prevItem;
440
+ break;
441
+ }
442
+ }
443
+
444
+ if (insertAfter) {
445
+ insertAfter.insertAdjacentElement('afterend', cartItem);
446
+ } else {
447
+ itemsContainer.appendChild(cartItem);
448
+ }
449
+ }
450
+ });
451
+ }, 100);
452
+ }
453
+
454
+ /**
455
+ * Render cart items from Shopify cart data with smart comparison
456
+ * @private
457
+ */
458
+ #renderCartItems(cartData) {
459
+ const itemsContainer = this.querySelector('[data-content-cart-items]');
460
+
461
+ if (!itemsContainer || !cartData || !cartData.items) {
462
+ console.warn('Cannot render cart items:', {
463
+ itemsContainer: !!itemsContainer,
464
+ cartData: !!cartData,
465
+ items: cartData?.items?.length,
466
+ });
467
+ return;
468
+ }
469
+
470
+ // Handle initial render - load all items without animation
471
+ if (this.#isInitialRender) {
472
+ console.log('Initial cart render:', cartData.items.length, 'items');
473
+
474
+ // Clear existing items
475
+ itemsContainer.innerHTML = '';
476
+
477
+ // Create cart-item elements without animation
478
+ cartData.items.forEach((itemData) => {
479
+ const cartItem = new CartItem(itemData); // No animation
480
+ itemsContainer.appendChild(cartItem);
481
+ });
482
+
483
+ this.#isInitialRender = false;
484
+ console.log('Initial render complete, container children:', itemsContainer.children.length);
485
+ return;
486
+ }
487
+
488
+ console.log('Smart rendering cart items:', cartData.items.length, 'items');
489
+
490
+ // Get current DOM items and their keys
491
+ const currentItems = Array.from(itemsContainer.querySelectorAll('cart-item'));
492
+ const currentKeys = new Set(currentItems.map((item) => item.getAttribute('key')));
493
+
494
+ // Get new cart data keys in order
495
+ const newKeys = cartData.items.map((item) => item.key || item.id);
496
+ const newKeysSet = new Set(newKeys);
497
+
498
+ // Step 1: Remove items that are no longer in cart data
499
+ this.#removeItemsFromDOM(itemsContainer, newKeysSet);
500
+
501
+ // Step 2: Add new items that weren't in DOM (with animation delay)
502
+ const itemsToAdd = cartData.items.filter(
503
+ (itemData) => !currentKeys.has(itemData.key || itemData.id)
504
+ );
505
+
506
+ this.#addItemsToDOM(itemsContainer, itemsToAdd, newKeys);
507
+
508
+ console.log('Smart rendering complete, container children:', itemsContainer.children.length);
509
+ }
510
+
511
+ /**
512
+ * Set the template function for cart items
513
+ * @param {Function} templateFn - Function that takes item data and returns HTML string
514
+ */
515
+ setCartItemTemplate(templateFn) {
516
+ CartItem.setTemplate(templateFn);
517
+ }
518
+
519
+ /**
520
+ * Set the processing template function for cart items
521
+ * @param {Function} templateFn - Function that returns HTML string for processing state
522
+ */
523
+ setCartItemProcessingTemplate(templateFn) {
524
+ CartItem.setProcessingTemplate(templateFn);
525
+ }
526
+
361
527
  /**
362
528
  * Shows the cart dialog and traps focus within it
363
529
  * @param {HTMLElement} [triggerEl=null] - The element that triggered the cart dialog
@@ -458,9 +624,20 @@ class CartPanel extends HTMLElement {
458
624
  }
459
625
  }
460
626
 
461
- customElements.define('cart-dialog', CartDialog);
462
- customElements.define('cart-overlay', CartOverlay);
463
- customElements.define('cart-panel', CartPanel);
627
+ if (!customElements.get('cart-dialog')) {
628
+ customElements.define('cart-dialog', CartDialog);
629
+ }
630
+ if (!customElements.get('cart-overlay')) {
631
+ customElements.define('cart-overlay', CartOverlay);
632
+ }
633
+ if (!customElements.get('cart-panel')) {
634
+ customElements.define('cart-panel', CartPanel);
635
+ }
636
+
637
+ // Make CartItem available globally for Shopify themes
638
+ if (typeof window !== 'undefined') {
639
+ window.CartItem = CartItem;
640
+ }
464
641
 
465
642
  export { CartDialog, CartOverlay, CartPanel, CartDialog as default };
466
643
  //# sourceMappingURL=cart-panel.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cart-panel.esm.js","sources":["../src/cart-panel.js"],"sourcesContent":["import './cart-panel.scss';\nimport '@magic-spells/cart-item';\nimport '@magic-spells/focus-trap';\nimport EventEmitter from '@magic-spells/event-emitter';\n\n/**\n * Custom element that creates an accessible modal cart dialog with focus management\n * @extends HTMLElement\n */\nclass CartDialog extends HTMLElement {\n\t#handleTransitionEnd;\n\t#scrollPosition = 0;\n\t#currentCart = null;\n\t#eventEmitter;\n\n\t/**\n\t * Clean up event listeners when component is removed from DOM\n\t */\n\tdisconnectedCallback() {\n\t\tconst _ = this;\n\t\tif (_.contentPanel) {\n\t\t\t_.contentPanel.removeEventListener('transitionend', _.#handleTransitionEnd);\n\t\t}\n\n\t\t// Ensure body scroll is restored if component is removed while open\n\t\tdocument.body.classList.remove('overflow-hidden');\n\t\tthis.#restoreScroll();\n\n\t\t// Detach event listeners\n\t\tthis.#detachListeners();\n\t}\n\n\t/**\n\t * Saves current scroll position and locks body scrolling\n\t * @private\n\t */\n\t#lockScroll() {\n\t\tconst _ = this;\n\t\t// Save current scroll position\n\t\t_.#scrollPosition = window.pageYOffset;\n\n\t\t// Apply fixed position to body\n\t\tdocument.body.classList.add('overflow-hidden');\n\t\tdocument.body.style.top = `-${_.#scrollPosition}px`;\n\t}\n\n\t/**\n\t * Restores scroll position when cart dialog is closed\n\t * @private\n\t */\n\t#restoreScroll() {\n\t\tconst _ = this;\n\t\t// Remove fixed positioning\n\t\tdocument.body.classList.remove('overflow-hidden');\n\t\tdocument.body.style.removeProperty('top');\n\n\t\t// Restore scroll position\n\t\twindow.scrollTo(0, _.#scrollPosition);\n\t}\n\n\t/**\n\t * Initializes the cart dialog, sets up focus trap and overlay\n\t */\n\tconstructor() {\n\t\tsuper();\n\t\tconst _ = this;\n\t\t_.id = _.getAttribute('id');\n\t\t_.setAttribute('role', 'dialog');\n\t\t_.setAttribute('aria-modal', 'true');\n\t\t_.setAttribute('aria-hidden', 'true');\n\n\t\t_.triggerEl = null;\n\n\t\t// Initialize event emitter\n\t\t_.#eventEmitter = new EventEmitter();\n\n\t\t// Create a handler for transition end events\n\t\t_.#handleTransitionEnd = (e) => {\n\t\t\tif (e.propertyName === 'opacity' && _.getAttribute('aria-hidden') === 'true') {\n\t\t\t\t_.contentPanel.classList.add('hidden');\n\n\t\t\t\t// Emit afterHide event - cart dialog has completed its transition\n\t\t\t\t_.#emit('cart-dialog:afterHide', { triggerElement: _.triggerEl });\n\t\t\t}\n\t\t};\n\t}\n\n\tconnectedCallback() {\n\t\tconst _ = this;\n\n\t\t// Now that we're in the DOM, find the content panel and set up focus trap\n\t\t_.contentPanel = _.querySelector('cart-panel');\n\n\t\tif (!_.contentPanel) {\n\t\t\tconsole.error('cart-panel element not found inside cart-dialog');\n\t\t\treturn;\n\t\t}\n\n\t\t_.focusTrap = document.createElement('focus-trap');\n\n\t\t// Ensure we have labelledby and describedby references\n\t\tif (!_.getAttribute('aria-labelledby')) {\n\t\t\tconst heading = _.querySelector('h1, h2, h3');\n\t\t\tif (heading && !heading.id) {\n\t\t\t\theading.id = `${_.id}-title`;\n\t\t\t}\n\t\t\tif (heading?.id) {\n\t\t\t\t_.setAttribute('aria-labelledby', heading.id);\n\t\t\t}\n\t\t}\n\n\t\t_.contentPanel.parentNode.insertBefore(_.focusTrap, _.contentPanel);\n\t\t_.focusTrap.appendChild(_.contentPanel);\n\n\t\t_.focusTrap.setupTrap();\n\n\t\t// Add modal overlay\n\t\t_.prepend(document.createElement('cart-overlay'));\n\t\t_.#attachListeners();\n\t\t_.#bindKeyboard();\n\t}\n\n\t/**\n\t * Event emitter method - Add an event listener with a cleaner API\n\t * @param {string} eventName - Name of the event to listen for\n\t * @param {Function} callback - Callback function to execute when event is fired\n\t * @returns {CartDialog} Returns this for method chaining\n\t */\n\ton(eventName, callback) {\n\t\tthis.#eventEmitter.on(eventName, callback);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Event emitter method - Remove an event listener\n\t * @param {string} eventName - Name of the event to stop listening for\n\t * @param {Function} callback - Callback function to remove\n\t * @returns {CartDialog} Returns this for method chaining\n\t */\n\toff(eventName, callback) {\n\t\tthis.#eventEmitter.off(eventName, callback);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Internal method to emit events via the event emitter\n\t * @param {string} eventName - Name of the event to emit\n\t * @param {*} [data] - Optional data to include with the event\n\t * @private\n\t */\n\t#emit(eventName, data = null) {\n\t\tthis.#eventEmitter.emit(eventName, data);\n\t}\n\n\t/**\n\t * Attach event listeners for cart dialog functionality\n\t * @private\n\t */\n\t#attachListeners() {\n\t\tconst _ = this;\n\n\t\t// Handle trigger buttons\n\t\tdocument.addEventListener('click', (e) => {\n\t\t\tconst trigger = e.target.closest(`[aria-controls=\"${_.id}\"]`);\n\t\t\tif (!trigger) return;\n\n\t\t\tif (trigger.getAttribute('data-prevent-default') === 'true') {\n\t\t\t\te.preventDefault();\n\t\t\t}\n\n\t\t\t_.show(trigger);\n\t\t});\n\n\t\t// Handle close buttons\n\t\t_.addEventListener('click', (e) => {\n\t\t\tif (!e.target.closest('[data-action=\"hide-cart\"]')) return;\n\t\t\t_.hide();\n\t\t});\n\n\t\t// Handle cart item remove events\n\t\t_.addEventListener('cart-item:remove', (e) => {\n\t\t\t_.#handleCartItemRemove(e);\n\t\t});\n\n\t\t// Handle cart item quantity change events\n\t\t_.addEventListener('cart-item:quantity-change', (e) => {\n\t\t\t_.#handleCartItemQuantityChange(e);\n\t\t});\n\n\t\t// Add transition end listener\n\t\t_.contentPanel.addEventListener('transitionend', _.#handleTransitionEnd);\n\t}\n\n\t/**\n\t * Detach event listeners\n\t * @private\n\t */\n\t#detachListeners() {\n\t\tconst _ = this;\n\t\tif (_.contentPanel) {\n\t\t\t_.contentPanel.removeEventListener('transitionend', _.#handleTransitionEnd);\n\t\t}\n\t}\n\n\t/**\n\t * Binds keyboard events for accessibility\n\t * @private\n\t */\n\t#bindKeyboard() {\n\t\tthis.addEventListener('keydown', (e) => {\n\t\t\tif (e.key === 'Escape') {\n\t\t\t\tthis.hide();\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Handle cart item removal\n\t * @private\n\t */\n\t#handleCartItemRemove(e) {\n\t\tconst { cartKey, element } = e.detail;\n\n\t\t// Set item to processing state\n\t\telement.setState('processing');\n\n\t\t// Remove item by setting quantity to 0\n\t\tthis.updateCartItem(cartKey, 0)\n\t\t\t.then((updatedCart) => {\n\t\t\t\tif (updatedCart && !updatedCart.error) {\n\t\t\t\t\t// Success - remove with animation\n\t\t\t\t\telement.destroyYourself();\n\t\t\t\t\tthis.#currentCart = updatedCart;\n\t\t\t\t\tthis.#updateCartItems(updatedCart);\n\n\t\t\t\t\t// Emit cart updated and data changed events\n\t\t\t\t\tthis.#emit('cart-dialog:updated', { cart: updatedCart });\n\t\t\t\t\tthis.#emit('cart-dialog:data-changed', updatedCart);\n\t\t\t\t} else {\n\t\t\t\t\t// Error - reset to ready state\n\t\t\t\t\telement.setState('ready');\n\t\t\t\t\tconsole.error('Failed to remove cart item:', cartKey);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\t// Error - reset to ready state\n\t\t\t\telement.setState('ready');\n\t\t\t\tconsole.error('Error removing cart item:', error);\n\t\t\t});\n\t}\n\n\t/**\n\t * Handle cart item quantity change\n\t * @private\n\t */\n\t#handleCartItemQuantityChange(e) {\n\t\tconst { cartKey, quantity, element } = e.detail;\n\n\t\t// Set item to processing state\n\t\telement.setState('processing');\n\n\t\t// Update item quantity\n\t\tthis.updateCartItem(cartKey, quantity)\n\t\t\t.then((updatedCart) => {\n\t\t\t\tif (updatedCart && !updatedCart.error) {\n\t\t\t\t\t// Success - update cart data\n\t\t\t\t\tthis.#currentCart = updatedCart;\n\t\t\t\t\tthis.#updateCartItems(updatedCart);\n\t\t\t\t\telement.setState('ready');\n\n\t\t\t\t\t// Emit cart updated and data changed events\n\t\t\t\t\tthis.#emit('cart-dialog:updated', { cart: updatedCart });\n\t\t\t\t\tthis.#emit('cart-dialog:data-changed', updatedCart);\n\t\t\t\t} else {\n\t\t\t\t\t// Error - reset to ready state\n\t\t\t\t\telement.setState('ready');\n\t\t\t\t\tconsole.error('Failed to update cart item quantity:', cartKey, quantity);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\t// Error - reset to ready state\n\t\t\t\telement.setState('ready');\n\t\t\t\tconsole.error('Error updating cart item quantity:', error);\n\t\t\t});\n\t}\n\n\t/**\n\t * Update cart items\n\t * @private\n\t */\n\t#updateCartItems(cart = null) {\n\t\t// Placeholder for cart item updates\n\t\t// Could be used to sync cart items with server data\n\t\tconst cartData = cart || this.#currentCart;\n\t\tif (cartData) {\n\t\t\t// Future implementation: update cart item components\n\t\t}\n\t}\n\n\t/**\n\t * Fetch current cart data from server\n\t * @returns {Promise<Object>} Cart data object\n\t */\n\tgetCart() {\n\t\treturn fetch('/cart.json', {\n\t\t\tcrossDomain: true,\n\t\t\tcredentials: 'same-origin',\n\t\t})\n\t\t\t.then((response) => {\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tthrow Error(response.statusText);\n\t\t\t\t}\n\t\t\t\treturn response.json();\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tconsole.error('Error fetching cart:', error);\n\t\t\t\treturn { error: true, message: error.message };\n\t\t\t});\n\t}\n\n\t/**\n\t * Update cart item quantity on server\n\t * @param {string|number} key - Cart item key/ID\n\t * @param {number} quantity - New quantity (0 to remove)\n\t * @returns {Promise<Object>} Updated cart data object\n\t */\n\tupdateCartItem(key, quantity) {\n\t\treturn fetch('/cart/change.json', {\n\t\t\tcrossDomain: true,\n\t\t\tmethod: 'POST',\n\t\t\tcredentials: 'same-origin',\n\t\t\tbody: JSON.stringify({ id: key, quantity: quantity }),\n\t\t\theaders: { 'Content-Type': 'application/json' },\n\t\t})\n\t\t\t.then((response) => {\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tthrow Error(response.statusText);\n\t\t\t\t}\n\t\t\t\treturn response.json();\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tconsole.error('Error updating cart item:', error);\n\t\t\t\treturn { error: true, message: error.message };\n\t\t\t});\n\t}\n\n\t/**\n\t * Refresh cart data from server and update components\n\t * @returns {Promise<Object>} Cart data object\n\t */\n\trefreshCart() {\n\t\treturn this.getCart().then((cartData) => {\n\t\t\tif (cartData && !cartData.error) {\n\t\t\t\tthis.#currentCart = cartData;\n\t\t\t\tthis.#updateCartItems(cartData);\n\n\t\t\t\t// Emit cart refreshed and data changed events\n\t\t\t\tthis.#emit('cart-dialog:refreshed', { cart: cartData });\n\t\t\t\tthis.#emit('cart-dialog:data-changed', cartData);\n\t\t\t}\n\t\t\treturn cartData;\n\t\t});\n\t}\n\n\t/**\n\t * Shows the cart dialog and traps focus within it\n\t * @param {HTMLElement} [triggerEl=null] - The element that triggered the cart dialog\n\t * @fires CartDialog#show - Fired when the cart dialog has been shown\n\t */\n\tshow(triggerEl = null) {\n\t\tconst _ = this;\n\t\t_.triggerEl = triggerEl || false;\n\n\t\t// Remove the hidden class first to ensure content is rendered\n\t\t_.contentPanel.classList.remove('hidden');\n\n\t\t// Give the browser a moment to process before starting animation\n\t\trequestAnimationFrame(() => {\n\t\t\t// Update ARIA states\n\t\t\t_.setAttribute('aria-hidden', 'false');\n\t\t\tif (_.triggerEl) {\n\t\t\t\t_.triggerEl.setAttribute('aria-expanded', 'true');\n\t\t\t}\n\n\t\t\t// Lock body scrolling and save scroll position\n\t\t\t_.#lockScroll();\n\n\t\t\t// Focus management\n\t\t\tconst firstFocusable = _.querySelector(\n\t\t\t\t'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n\t\t\t);\n\t\t\tif (firstFocusable) {\n\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\tfirstFocusable.focus();\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Refresh cart data when showing\n\t\t\t_.refreshCart();\n\n\t\t\t// Emit show event - cart dialog is now visible\n\t\t\t_.#emit('cart-dialog:show', { triggerElement: _.triggerEl });\n\t\t});\n\t}\n\n\t/**\n\t * Hides the cart dialog and restores focus\n\t * @fires CartDialog#hide - Fired when the cart dialog has started hiding (transition begins)\n\t * @fires CartDialog#afterHide - Fired when the cart dialog has completed its hide transition\n\t */\n\thide() {\n\t\tconst _ = this;\n\n\t\t// Restore body scroll and scroll position\n\t\t_.#restoreScroll();\n\n\t\t// Update ARIA states\n\t\tif (_.triggerEl) {\n\t\t\t// remove focus from modal panel first\n\t\t\t_.triggerEl.focus();\n\t\t\t// mark trigger as no longer expanded\n\t\t\t_.triggerEl.setAttribute('aria-expanded', 'false');\n\t\t}\n\n\t\t// Set aria-hidden to start transition\n\t\t// The transitionend event handler will add display:none when complete\n\t\t_.setAttribute('aria-hidden', 'true');\n\n\t\t// Emit hide event - cart dialog is now starting to hide\n\t\t_.#emit('cart-dialog:hide', { triggerElement: _.triggerEl });\n\t}\n}\n\n/**\n * Custom element that creates a clickable overlay for the cart dialog\n * @extends HTMLElement\n */\nclass CartOverlay extends HTMLElement {\n\tconstructor() {\n\t\tsuper();\n\t\tthis.setAttribute('tabindex', '-1');\n\t\tthis.setAttribute('aria-hidden', 'true');\n\t\tthis.cartDialog = this.closest('cart-dialog');\n\t\tthis.#attachListeners();\n\t}\n\n\t#attachListeners() {\n\t\tthis.addEventListener('click', () => {\n\t\t\tthis.cartDialog.hide();\n\t\t});\n\t}\n}\n\n/**\n * Custom element that wraps the content of the cart dialog\n * @extends HTMLElement\n */\nclass CartPanel extends HTMLElement {\n\tconstructor() {\n\t\tsuper();\n\t\tthis.setAttribute('role', 'document');\n\t}\n}\n\ncustomElements.define('cart-dialog', CartDialog);\ncustomElements.define('cart-overlay', CartOverlay);\ncustomElements.define('cart-panel', CartPanel);\n\nexport { CartDialog, CartOverlay, CartPanel };\nexport default CartDialog;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cart-panel.esm.js","sources":["../src/cart-panel.js"],"sourcesContent":["import './cart-panel.scss';\nimport '@magic-spells/cart-item';\nimport { CartItem } from '@magic-spells/cart-item';\nimport '@magic-spells/focus-trap';\nimport EventEmitter from '@magic-spells/event-emitter';\n\n/**\n * Custom element that creates an accessible modal cart dialog with focus management\n * @extends HTMLElement\n */\nclass CartDialog extends HTMLElement {\n\t#handleTransitionEnd;\n\t#scrollPosition = 0;\n\t#currentCart = null;\n\t#eventEmitter;\n\t#isInitialRender = true;\n\n\t/**\n\t * Clean up event listeners when component is removed from DOM\n\t */\n\tdisconnectedCallback() {\n\t\tconst _ = this;\n\t\tif (_.contentPanel) {\n\t\t\t_.contentPanel.removeEventListener('transitionend', _.#handleTransitionEnd);\n\t\t}\n\n\t\t// Ensure body scroll is restored if component is removed while open\n\t\tdocument.body.classList.remove('overflow-hidden');\n\t\tthis.#restoreScroll();\n\n\t\t// Detach event listeners\n\t\tthis.#detachListeners();\n\t}\n\n\t/**\n\t * Saves current scroll position and locks body scrolling\n\t * @private\n\t */\n\t#lockScroll() {\n\t\tconst _ = this;\n\t\t// Save current scroll position\n\t\t_.#scrollPosition = window.pageYOffset;\n\n\t\t// Apply fixed position to body\n\t\tdocument.body.classList.add('overflow-hidden');\n\t\tdocument.body.style.top = `-${_.#scrollPosition}px`;\n\t}\n\n\t/**\n\t * Restores scroll position when cart dialog is closed\n\t * @private\n\t */\n\t#restoreScroll() {\n\t\tconst _ = this;\n\t\t// Remove fixed positioning\n\t\tdocument.body.classList.remove('overflow-hidden');\n\t\tdocument.body.style.removeProperty('top');\n\n\t\t// Restore scroll position\n\t\twindow.scrollTo(0, _.#scrollPosition);\n\t}\n\n\t/**\n\t * Initializes the cart dialog, sets up focus trap and overlay\n\t */\n\tconstructor() {\n\t\tsuper();\n\t\tconst _ = this;\n\t\t_.id = _.getAttribute('id');\n\t\t_.setAttribute('role', 'dialog');\n\t\t_.setAttribute('aria-modal', 'true');\n\t\t_.setAttribute('aria-hidden', 'true');\n\n\t\t_.triggerEl = null;\n\n\t\t// Initialize event emitter\n\t\t_.#eventEmitter = new EventEmitter();\n\n\t\t// Create a handler for transition end events\n\t\t_.#handleTransitionEnd = (e) => {\n\t\t\tif (e.propertyName === 'opacity' && _.getAttribute('aria-hidden') === 'true') {\n\t\t\t\t_.contentPanel.classList.add('hidden');\n\n\t\t\t\t// Emit afterHide event - cart dialog has completed its transition\n\t\t\t\t_.#emit('cart-dialog:afterHide', { triggerElement: _.triggerEl });\n\t\t\t}\n\t\t};\n\t}\n\n\tconnectedCallback() {\n\t\tconst _ = this;\n\n\t\t// Now that we're in the DOM, find the content panel and set up focus trap\n\t\t_.contentPanel = _.querySelector('cart-panel');\n\n\t\tif (!_.contentPanel) {\n\t\t\tconsole.error('cart-panel element not found inside cart-dialog');\n\t\t\treturn;\n\t\t}\n\n\t\t_.focusTrap = document.createElement('focus-trap');\n\n\t\t// Ensure we have labelledby and describedby references\n\t\tif (!_.getAttribute('aria-labelledby')) {\n\t\t\tconst heading = _.querySelector('h1, h2, h3');\n\t\t\tif (heading && !heading.id) {\n\t\t\t\theading.id = `${_.id}-title`;\n\t\t\t}\n\t\t\tif (heading?.id) {\n\t\t\t\t_.setAttribute('aria-labelledby', heading.id);\n\t\t\t}\n\t\t}\n\n\t\t// Insert focus trap before the cart-panel\n\t\t_.contentPanel.parentNode.insertBefore(_.focusTrap, _.contentPanel);\n\t\t// Move cart-panel inside the focus trap\n\t\t_.focusTrap.appendChild(_.contentPanel);\n\n\t\t// Setup the trap - this will add focus-trap-start/end elements around the content\n\t\t_.focusTrap.setupTrap();\n\n\t\t// Add modal overlay if it doesn't already exist\n\t\tif (!_.querySelector('cart-overlay')) {\n\t\t\t_.prepend(document.createElement('cart-overlay'));\n\t\t}\n\t\t_.#attachListeners();\n\t\t_.#bindKeyboard();\n\t}\n\n\t/**\n\t * Event emitter method - Add an event listener with a cleaner API\n\t * @param {string} eventName - Name of the event to listen for\n\t * @param {Function} callback - Callback function to execute when event is fired\n\t * @returns {CartDialog} Returns this for method chaining\n\t */\n\ton(eventName, callback) {\n\t\tthis.#eventEmitter.on(eventName, callback);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Event emitter method - Remove an event listener\n\t * @param {string} eventName - Name of the event to stop listening for\n\t * @param {Function} callback - Callback function to remove\n\t * @returns {CartDialog} Returns this for method chaining\n\t */\n\toff(eventName, callback) {\n\t\tthis.#eventEmitter.off(eventName, callback);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Internal method to emit events via the event emitter\n\t * @param {string} eventName - Name of the event to emit\n\t * @param {*} [data] - Optional data to include with the event\n\t * @private\n\t */\n\t#emit(eventName, data = null) {\n\t\tthis.#eventEmitter.emit(eventName, data);\n\t}\n\n\t/**\n\t * Attach event listeners for cart dialog functionality\n\t * @private\n\t */\n\t#attachListeners() {\n\t\tconst _ = this;\n\n\t\t// Handle trigger buttons\n\t\tdocument.addEventListener('click', (e) => {\n\t\t\tconst trigger = e.target.closest(`[aria-controls=\"${_.id}\"]`);\n\t\t\tif (!trigger) return;\n\n\t\t\tif (trigger.getAttribute('data-prevent-default') === 'true') {\n\t\t\t\te.preventDefault();\n\t\t\t}\n\n\t\t\t_.show(trigger);\n\t\t});\n\n\t\t// Handle close buttons\n\t\t_.addEventListener('click', (e) => {\n\t\t\tif (!e.target.closest('[data-action-hide-cart]')) return;\n\t\t\t_.hide();\n\t\t});\n\n\t\t// Handle cart item remove events\n\t\t_.addEventListener('cart-item:remove', (e) => {\n\t\t\t_.#handleCartItemRemove(e);\n\t\t});\n\n\t\t// Handle cart item quantity change events\n\t\t_.addEventListener('cart-item:quantity-change', (e) => {\n\t\t\t_.#handleCartItemQuantityChange(e);\n\t\t});\n\n\t\t// Add transition end listener\n\t\t_.contentPanel.addEventListener('transitionend', _.#handleTransitionEnd);\n\t}\n\n\t/**\n\t * Detach event listeners\n\t * @private\n\t */\n\t#detachListeners() {\n\t\tconst _ = this;\n\t\tif (_.contentPanel) {\n\t\t\t_.contentPanel.removeEventListener('transitionend', _.#handleTransitionEnd);\n\t\t}\n\t}\n\n\t/**\n\t * Binds keyboard events for accessibility\n\t * @private\n\t */\n\t#bindKeyboard() {\n\t\tthis.addEventListener('keydown', (e) => {\n\t\t\tif (e.key === 'Escape') {\n\t\t\t\tthis.hide();\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Handle cart item removal\n\t * @private\n\t */\n\t#handleCartItemRemove(e) {\n\t\tconst { cartKey, element } = e.detail;\n\n\t\t// Set item to processing state\n\t\telement.setState('processing');\n\n\t\t// Remove item by setting quantity to 0\n\t\tthis.updateCartItem(cartKey, 0)\n\t\t\t.then((updatedCart) => {\n\t\t\t\tif (updatedCart && !updatedCart.error) {\n\t\t\t\t\t// Success - let smart comparison handle the removal animation\n\t\t\t\t\tthis.#currentCart = updatedCart;\n\t\t\t\t\tthis.#renderCartItems(updatedCart);\n\t\t\t\t\tthis.#updateCartItems(updatedCart);\n\n\t\t\t\t\t// Emit cart updated and data changed events\n\t\t\t\t\tthis.#emit('cart-dialog:updated', { cart: updatedCart });\n\t\t\t\t\tthis.#emit('cart-dialog:data-changed', updatedCart);\n\t\t\t\t} else {\n\t\t\t\t\t// Error - reset to ready state\n\t\t\t\t\telement.setState('ready');\n\t\t\t\t\tconsole.error('Failed to remove cart item:', cartKey);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\t// Error - reset to ready state\n\t\t\t\telement.setState('ready');\n\t\t\t\tconsole.error('Error removing cart item:', error);\n\t\t\t});\n\t}\n\n\t/**\n\t * Handle cart item quantity change\n\t * @private\n\t */\n\t#handleCartItemQuantityChange(e) {\n\t\tconst { cartKey, quantity, element } = e.detail;\n\n\t\t// Set item to processing state\n\t\telement.setState('processing');\n\n\t\t// Update item quantity\n\t\tthis.updateCartItem(cartKey, quantity)\n\t\t\t.then((updatedCart) => {\n\t\t\t\tif (updatedCart && !updatedCart.error) {\n\t\t\t\t\t// Success - update cart data and refresh items\n\t\t\t\t\tthis.#currentCart = updatedCart;\n\t\t\t\t\tthis.#renderCartItems(updatedCart);\n\t\t\t\t\tthis.#updateCartItems(updatedCart);\n\t\t\t\t\telement.setState('ready');\n\n\t\t\t\t\t// Emit cart updated and data changed events\n\t\t\t\t\tthis.#emit('cart-dialog:updated', { cart: updatedCart });\n\t\t\t\t\tthis.#emit('cart-dialog:data-changed', updatedCart);\n\t\t\t\t} else {\n\t\t\t\t\t// Error - reset to ready state\n\t\t\t\t\telement.setState('ready');\n\t\t\t\t\tconsole.error('Failed to update cart item quantity:', cartKey, quantity);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\t// Error - reset to ready state\n\t\t\t\telement.setState('ready');\n\t\t\t\tconsole.error('Error updating cart item quantity:', error);\n\t\t\t});\n\t}\n\n\t/**\n\t * Update cart items display based on cart data\n\t * @private\n\t */\n\t#updateCartItems(cart = null) {\n\t\tconst cartData = cart || this.#currentCart;\n\t\tif (!cartData) return;\n\n\t\t// Get cart sections\n\t\tconst hasItemsSection = this.querySelector('[data-cart-has-items]');\n\t\tconst emptySection = this.querySelector('[data-cart-is-empty]');\n\t\tconst itemsContainer = this.querySelector('[data-content-cart-items]');\n\n\t\tif (!hasItemsSection || !emptySection || !itemsContainer) {\n\t\t\tconsole.warn(\n\t\t\t\t'Cart sections not found. Expected [data-cart-has-items], [data-cart-is-empty], and [data-content-cart-items]'\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\t// Show/hide sections based on item count\n\t\tif (cartData.item_count > 0) {\n\t\t\thasItemsSection.style.display = 'block';\n\t\t\temptySection.style.display = 'none';\n\t\t} else {\n\t\t\thasItemsSection.style.display = 'none';\n\t\t\temptySection.style.display = 'block';\n\t\t}\n\t}\n\n\t/**\n\t * Fetch current cart data from server\n\t * @returns {Promise<Object>} Cart data object\n\t */\n\tgetCart() {\n\t\treturn fetch('/cart.json', {\n\t\t\tcrossDomain: true,\n\t\t\tcredentials: 'same-origin',\n\t\t})\n\t\t\t.then((response) => {\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tthrow Error(response.statusText);\n\t\t\t\t}\n\t\t\t\treturn response.json();\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tconsole.error('Error fetching cart:', error);\n\t\t\t\treturn { error: true, message: error.message };\n\t\t\t});\n\t}\n\n\t/**\n\t * Update cart item quantity on server\n\t * @param {string|number} key - Cart item key/ID\n\t * @param {number} quantity - New quantity (0 to remove)\n\t * @returns {Promise<Object>} Updated cart data object\n\t */\n\tupdateCartItem(key, quantity) {\n\t\treturn fetch('/cart/change.json', {\n\t\t\tcrossDomain: true,\n\t\t\tmethod: 'POST',\n\t\t\tcredentials: 'same-origin',\n\t\t\tbody: JSON.stringify({ id: key, quantity: quantity }),\n\t\t\theaders: { 'Content-Type': 'application/json' },\n\t\t})\n\t\t\t.then((response) => {\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tthrow Error(response.statusText);\n\t\t\t\t}\n\t\t\t\treturn response.json();\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tconsole.error('Error updating cart item:', error);\n\t\t\t\treturn { error: true, message: error.message };\n\t\t\t});\n\t}\n\n\t/**\n\t * Refresh cart data from server and update components\n\t * @returns {Promise<Object>} Cart data object\n\t */\n\trefreshCart() {\n\t\tconsole.log('Refreshing cart...');\n\t\treturn this.getCart().then((cartData) => {\n\t\t\tconsole.log('Cart data received:', cartData);\n\t\t\tif (cartData && !cartData.error) {\n\t\t\t\tthis.#currentCart = cartData;\n\t\t\t\tthis.#renderCartItems(cartData);\n\t\t\t\tthis.#updateCartItems(cartData);\n\n\t\t\t\t// Emit cart refreshed and data changed events\n\t\t\t\tthis.#emit('cart-dialog:refreshed', { cart: cartData });\n\t\t\t\tthis.#emit('cart-dialog:data-changed', cartData);\n\t\t\t} else {\n\t\t\t\tconsole.warn('Cart data has error or is null:', cartData);\n\t\t\t}\n\t\t\treturn cartData;\n\t\t});\n\t}\n\n\t/**\n\t * Remove items from DOM that are no longer in cart data\n\t * @private\n\t */\n\t#removeItemsFromDOM(itemsContainer, newKeysSet) {\n\t\tconst currentItems = Array.from(itemsContainer.querySelectorAll('cart-item'));\n\t\tconst itemsToRemove = currentItems.filter((item) => !newKeysSet.has(item.getAttribute('key')));\n\n\t\tconsole.log(\n\t\t\t`Removing ${itemsToRemove.length} items:`,\n\t\t\titemsToRemove.map((item) => item.getAttribute('key'))\n\t\t);\n\n\t\titemsToRemove.forEach((item) => {\n\t\t\titem.destroyYourself();\n\t\t});\n\t}\n\n\t/**\n\t * Add new items to DOM with animation delay\n\t * @private\n\t */\n\t#addItemsToDOM(itemsContainer, itemsToAdd, newKeys) {\n\t\tconsole.log(\n\t\t\t`Adding ${itemsToAdd.length} items:`,\n\t\t\titemsToAdd.map((item) => item.key || item.id)\n\t\t);\n\n\t\t// Delay adding new items by 300ms to let cart slide open first\n\t\tsetTimeout(() => {\n\t\t\titemsToAdd.forEach((itemData) => {\n\t\t\t\tconst cartItem = CartItem.createAnimated(itemData);\n\t\t\t\tconst targetIndex = newKeys.indexOf(itemData.key || itemData.id);\n\n\t\t\t\t// Find the correct position to insert the new item\n\t\t\t\tif (targetIndex === 0) {\n\t\t\t\t\t// Insert at the beginning\n\t\t\t\t\titemsContainer.insertBefore(cartItem, itemsContainer.firstChild);\n\t\t\t\t} else {\n\t\t\t\t\t// Find the item that should come before this one\n\t\t\t\t\tlet insertAfter = null;\n\t\t\t\t\tfor (let i = targetIndex - 1; i >= 0; i--) {\n\t\t\t\t\t\tconst prevKey = newKeys[i];\n\t\t\t\t\t\tconst prevItem = itemsContainer.querySelector(`cart-item[key=\"${prevKey}\"]`);\n\t\t\t\t\t\tif (prevItem) {\n\t\t\t\t\t\t\tinsertAfter = prevItem;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (insertAfter) {\n\t\t\t\t\t\tinsertAfter.insertAdjacentElement('afterend', cartItem);\n\t\t\t\t\t} else {\n\t\t\t\t\t\titemsContainer.appendChild(cartItem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}, 100);\n\t}\n\n\t/**\n\t * Render cart items from Shopify cart data with smart comparison\n\t * @private\n\t */\n\t#renderCartItems(cartData) {\n\t\tconst itemsContainer = this.querySelector('[data-content-cart-items]');\n\n\t\tif (!itemsContainer || !cartData || !cartData.items) {\n\t\t\tconsole.warn('Cannot render cart items:', {\n\t\t\t\titemsContainer: !!itemsContainer,\n\t\t\t\tcartData: !!cartData,\n\t\t\t\titems: cartData?.items?.length,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\t// Handle initial render - load all items without animation\n\t\tif (this.#isInitialRender) {\n\t\t\tconsole.log('Initial cart render:', cartData.items.length, 'items');\n\n\t\t\t// Clear existing items\n\t\t\titemsContainer.innerHTML = '';\n\n\t\t\t// Create cart-item elements without animation\n\t\t\tcartData.items.forEach((itemData) => {\n\t\t\t\tconst cartItem = new CartItem(itemData); // No animation\n\t\t\t\titemsContainer.appendChild(cartItem);\n\t\t\t});\n\n\t\t\tthis.#isInitialRender = false;\n\t\t\tconsole.log('Initial render complete, container children:', itemsContainer.children.length);\n\t\t\treturn;\n\t\t}\n\n\t\tconsole.log('Smart rendering cart items:', cartData.items.length, 'items');\n\n\t\t// Get current DOM items and their keys\n\t\tconst currentItems = Array.from(itemsContainer.querySelectorAll('cart-item'));\n\t\tconst currentKeys = new Set(currentItems.map((item) => item.getAttribute('key')));\n\n\t\t// Get new cart data keys in order\n\t\tconst newKeys = cartData.items.map((item) => item.key || item.id);\n\t\tconst newKeysSet = new Set(newKeys);\n\n\t\t// Step 1: Remove items that are no longer in cart data\n\t\tthis.#removeItemsFromDOM(itemsContainer, newKeysSet);\n\n\t\t// Step 2: Add new items that weren't in DOM (with animation delay)\n\t\tconst itemsToAdd = cartData.items.filter(\n\t\t\t(itemData) => !currentKeys.has(itemData.key || itemData.id)\n\t\t);\n\n\t\tthis.#addItemsToDOM(itemsContainer, itemsToAdd, newKeys);\n\n\t\tconsole.log('Smart rendering complete, container children:', itemsContainer.children.length);\n\t}\n\n\t/**\n\t * Set the template function for cart items\n\t * @param {Function} templateFn - Function that takes item data and returns HTML string\n\t */\n\tsetCartItemTemplate(templateFn) {\n\t\tCartItem.setTemplate(templateFn);\n\t}\n\n\t/**\n\t * Set the processing template function for cart items\n\t * @param {Function} templateFn - Function that returns HTML string for processing state\n\t */\n\tsetCartItemProcessingTemplate(templateFn) {\n\t\tCartItem.setProcessingTemplate(templateFn);\n\t}\n\n\t/**\n\t * Shows the cart dialog and traps focus within it\n\t * @param {HTMLElement} [triggerEl=null] - The element that triggered the cart dialog\n\t * @fires CartDialog#show - Fired when the cart dialog has been shown\n\t */\n\tshow(triggerEl = null) {\n\t\tconst _ = this;\n\t\t_.triggerEl = triggerEl || false;\n\n\t\t// Remove the hidden class first to ensure content is rendered\n\t\t_.contentPanel.classList.remove('hidden');\n\n\t\t// Give the browser a moment to process before starting animation\n\t\trequestAnimationFrame(() => {\n\t\t\t// Update ARIA states\n\t\t\t_.setAttribute('aria-hidden', 'false');\n\t\t\tif (_.triggerEl) {\n\t\t\t\t_.triggerEl.setAttribute('aria-expanded', 'true');\n\t\t\t}\n\n\t\t\t// Lock body scrolling and save scroll position\n\t\t\t_.#lockScroll();\n\n\t\t\t// Focus management\n\t\t\tconst firstFocusable = _.querySelector(\n\t\t\t\t'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n\t\t\t);\n\t\t\tif (firstFocusable) {\n\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\tfirstFocusable.focus();\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Refresh cart data when showing\n\t\t\t_.refreshCart();\n\n\t\t\t// Emit show event - cart dialog is now visible\n\t\t\t_.#emit('cart-dialog:show', { triggerElement: _.triggerEl });\n\t\t});\n\t}\n\n\t/**\n\t * Hides the cart dialog and restores focus\n\t * @fires CartDialog#hide - Fired when the cart dialog has started hiding (transition begins)\n\t * @fires CartDialog#afterHide - Fired when the cart dialog has completed its hide transition\n\t */\n\thide() {\n\t\tconst _ = this;\n\n\t\t// Restore body scroll and scroll position\n\t\t_.#restoreScroll();\n\n\t\t// Update ARIA states\n\t\tif (_.triggerEl) {\n\t\t\t// remove focus from modal panel first\n\t\t\t_.triggerEl.focus();\n\t\t\t// mark trigger as no longer expanded\n\t\t\t_.triggerEl.setAttribute('aria-expanded', 'false');\n\t\t}\n\n\t\t// Set aria-hidden to start transition\n\t\t// The transitionend event handler will add display:none when complete\n\t\t_.setAttribute('aria-hidden', 'true');\n\n\t\t// Emit hide event - cart dialog is now starting to hide\n\t\t_.#emit('cart-dialog:hide', { triggerElement: _.triggerEl });\n\t}\n}\n\n/**\n * Custom element that creates a clickable overlay for the cart dialog\n * @extends HTMLElement\n */\nclass CartOverlay extends HTMLElement {\n\tconstructor() {\n\t\tsuper();\n\t\tthis.setAttribute('tabindex', '-1');\n\t\tthis.setAttribute('aria-hidden', 'true');\n\t\tthis.cartDialog = this.closest('cart-dialog');\n\t\tthis.#attachListeners();\n\t}\n\n\t#attachListeners() {\n\t\tthis.addEventListener('click', () => {\n\t\t\tthis.cartDialog.hide();\n\t\t});\n\t}\n}\n\n/**\n * Custom element that wraps the content of the cart dialog\n * @extends HTMLElement\n */\nclass CartPanel extends HTMLElement {\n\tconstructor() {\n\t\tsuper();\n\t\tthis.setAttribute('role', 'document');\n\t}\n}\n\nif (!customElements.get('cart-dialog')) {\n\tcustomElements.define('cart-dialog', CartDialog);\n}\nif (!customElements.get('cart-overlay')) {\n\tcustomElements.define('cart-overlay', CartOverlay);\n}\nif (!customElements.get('cart-panel')) {\n\tcustomElements.define('cart-panel', CartPanel);\n}\n\nexport { CartDialog, CartOverlay, CartPanel, CartItem };\nexport default CartDialog;\n\n// Make CartItem available globally for Shopify themes\nif (typeof window !== 'undefined') {\n\twindow.CartItem = CartItem;\n}\n"],"names":[],"mappings":"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"}