@salla.sa/twilight-components 2.14.291 → 2.14.292

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 (148) hide show
  1. package/dist/cjs/{filepond-l0In8JzI.js → filepond-B9sLUCBe.js} +1 -1
  2. package/dist/cjs/{filepond-plugin-file-poster--TMslLdw.js → filepond-plugin-file-poster-DkzerIBW.js} +1 -1
  3. package/dist/cjs/{filepond-plugin-file-validate-size-asc4GviL.js → filepond-plugin-file-validate-size-DF8uFSha.js} +1 -1
  4. package/dist/cjs/{filepond-plugin-file-validate-type-MAcIW_lX.js → filepond-plugin-file-validate-type-Dva6K_7l.js} +1 -1
  5. package/dist/cjs/{filepond-plugin-image-edit-8yC2fM_b.js → filepond-plugin-image-edit-C-0ziNsz.js} +1 -1
  6. package/dist/cjs/{filepond-plugin-image-exif-orientation-D2TaYNJz.js → filepond-plugin-image-exif-orientation-DxXsE_ZP.js} +1 -1
  7. package/dist/cjs/{filepond-plugin-image-preview-ZhHJTUGt.js → filepond-plugin-image-preview-2v59y8Fv.js} +1 -1
  8. package/dist/cjs/{index-BCqSMje8.js → index-B7O1YF_p.js} +1 -1
  9. package/dist/cjs/{index-CD__TuQ1.js → index-CCofAgHa.js} +2 -2
  10. package/dist/cjs/loader.cjs.js +2 -2
  11. package/dist/cjs/salla-accordion_62.cjs.entry.js +168 -83
  12. package/dist/cjs/salla-advertisement.cjs.entry.js +1 -1
  13. package/dist/cjs/salla-app-install-alert.cjs.entry.js +1 -1
  14. package/dist/cjs/salla-apps-icons.cjs.entry.js +1 -1
  15. package/dist/cjs/salla-cart-item-offers.cjs.entry.js +1 -1
  16. package/dist/cjs/salla-conditional-offer.cjs.entry.js +1 -1
  17. package/dist/cjs/salla-contacts.cjs.entry.js +1 -1
  18. package/dist/cjs/salla-filters-widget.cjs.entry.js +1 -1
  19. package/dist/cjs/salla-filters.cjs.entry.js +1 -1
  20. package/dist/cjs/salla-installment.cjs.entry.js +1 -1
  21. package/dist/cjs/salla-loyalty-prize-item.cjs.entry.js +1 -1
  22. package/dist/cjs/salla-loyalty-program.cjs.entry.js +1 -1
  23. package/dist/cjs/salla-metadata.cjs.entry.js +1 -1
  24. package/dist/cjs/salla-notification-item.cjs.entry.js +1 -1
  25. package/dist/cjs/salla-notifications.cjs.entry.js +1 -1
  26. package/dist/cjs/salla-offer.cjs.entry.js +1 -1
  27. package/dist/cjs/salla-order-details-multiple-bundle-product.cjs.entry.js +1 -1
  28. package/dist/cjs/salla-order-details-options.cjs.entry.js +1 -1
  29. package/dist/cjs/salla-order-details.cjs.entry.js +1 -1
  30. package/dist/cjs/salla-order-summary.cjs.entry.js +1 -1
  31. package/dist/cjs/salla-order-totals-card.cjs.entry.js +1 -1
  32. package/dist/cjs/salla-orders.cjs.entry.js +1 -1
  33. package/dist/cjs/salla-payments.cjs.entry.js +1 -1
  34. package/dist/cjs/salla-price-range.cjs.entry.js +1 -1
  35. package/dist/cjs/salla-review-card.cjs.entry.js +1 -1
  36. package/dist/cjs/salla-reviews-page.cjs.entry.js +1 -1
  37. package/dist/cjs/salla-reviews.cjs.entry.js +1 -1
  38. package/dist/cjs/salla-social.cjs.entry.js +1 -1
  39. package/dist/cjs/salla-tiered-offer.cjs.entry.js +1 -1
  40. package/dist/cjs/salla-tooltip.cjs.entry.js +1 -1
  41. package/dist/cjs/salla-trust-badges.cjs.entry.js +1 -1
  42. package/dist/cjs/salla-verify.cjs.entry.js +1 -1
  43. package/dist/cjs/salla-wallet.cjs.entry.js +1 -1
  44. package/dist/cjs/twilight.cjs.js +2 -2
  45. package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-details.js +20 -5
  46. package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-options-modal.js +84 -67
  47. package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-slider.js +75 -5
  48. package/dist/components/index.js +2 -2
  49. package/dist/components/keyboard_arrow_right.js +3 -3
  50. package/dist/components/salla-breadcrumb.js +2 -2
  51. package/dist/components/salla-multiple-bundle-product-details2.js +20 -5
  52. package/dist/components/salla-multiple-bundle-product-options-modal2.js +82 -65
  53. package/dist/components/salla-multiple-bundle-product-slider2.js +62 -6
  54. package/dist/components/salla-slider2.js +3 -3
  55. package/dist/esm/{filepond-D-hh7StM.js → filepond-BYDXj1kv.js} +1 -1
  56. package/dist/esm/{filepond-plugin-file-poster-B9peApDJ.js → filepond-plugin-file-poster-CuFchfVe.js} +1 -1
  57. package/dist/esm/{filepond-plugin-file-validate-size-Clsj6zmt.js → filepond-plugin-file-validate-size-DdbaDfww.js} +1 -1
  58. package/dist/esm/{filepond-plugin-file-validate-type-NUNR5wrE.js → filepond-plugin-file-validate-type-BpacmUuQ.js} +1 -1
  59. package/dist/esm/{filepond-plugin-image-edit-D9mIu1qc.js → filepond-plugin-image-edit--2pWYR5x.js} +1 -1
  60. package/dist/esm/{filepond-plugin-image-exif-orientation-DjJUiKBi.js → filepond-plugin-image-exif-orientation-BHXDSKOW.js} +1 -1
  61. package/dist/esm/{filepond-plugin-image-preview-Dqa9Qh69.js → filepond-plugin-image-preview-DOiMBtjb.js} +1 -1
  62. package/dist/esm/{index-r_fPtAzd.js → index-6_auLzVW.js} +1 -1
  63. package/dist/esm/{index-BdPAI7KX.js → index-De5BFkJn.js} +2 -2
  64. package/dist/esm/loader.js +3 -3
  65. package/dist/esm/salla-accordion_62.entry.js +168 -83
  66. package/dist/esm/salla-advertisement.entry.js +1 -1
  67. package/dist/esm/salla-app-install-alert.entry.js +1 -1
  68. package/dist/esm/salla-apps-icons.entry.js +1 -1
  69. package/dist/esm/salla-cart-item-offers.entry.js +1 -1
  70. package/dist/esm/salla-conditional-offer.entry.js +1 -1
  71. package/dist/esm/salla-contacts.entry.js +1 -1
  72. package/dist/esm/salla-filters-widget.entry.js +1 -1
  73. package/dist/esm/salla-filters.entry.js +1 -1
  74. package/dist/esm/salla-installment.entry.js +1 -1
  75. package/dist/esm/salla-loyalty-prize-item.entry.js +1 -1
  76. package/dist/esm/salla-loyalty-program.entry.js +1 -1
  77. package/dist/esm/salla-metadata.entry.js +1 -1
  78. package/dist/esm/salla-notification-item.entry.js +1 -1
  79. package/dist/esm/salla-notifications.entry.js +1 -1
  80. package/dist/esm/salla-offer.entry.js +1 -1
  81. package/dist/esm/salla-order-details-multiple-bundle-product.entry.js +1 -1
  82. package/dist/esm/salla-order-details-options.entry.js +1 -1
  83. package/dist/esm/salla-order-details.entry.js +1 -1
  84. package/dist/esm/salla-order-summary.entry.js +1 -1
  85. package/dist/esm/salla-order-totals-card.entry.js +1 -1
  86. package/dist/esm/salla-orders.entry.js +1 -1
  87. package/dist/esm/salla-payments.entry.js +1 -1
  88. package/dist/esm/salla-price-range.entry.js +1 -1
  89. package/dist/esm/salla-review-card.entry.js +1 -1
  90. package/dist/esm/salla-reviews-page.entry.js +1 -1
  91. package/dist/esm/salla-reviews.entry.js +1 -1
  92. package/dist/esm/salla-social.entry.js +1 -1
  93. package/dist/esm/salla-tiered-offer.entry.js +1 -1
  94. package/dist/esm/salla-tooltip.entry.js +1 -1
  95. package/dist/esm/salla-trust-badges.entry.js +1 -1
  96. package/dist/esm/salla-verify.entry.js +1 -1
  97. package/dist/esm/salla-wallet.entry.js +1 -1
  98. package/dist/esm/twilight.js +3 -3
  99. package/dist/twilight/{p-efdf02d5.entry.js → p-1b88233c.entry.js} +1 -1
  100. package/dist/twilight/{p-3420836d.entry.js → p-1c8efb3a.entry.js} +1 -1
  101. package/dist/twilight/{p-84f7d6ff.entry.js → p-1f56038b.entry.js} +1 -1
  102. package/dist/twilight/{p-9706a388.entry.js → p-24b6e7b0.entry.js} +1 -1
  103. package/dist/twilight/{p-23541825.entry.js → p-26a1a393.entry.js} +1 -1
  104. package/dist/twilight/{p-025d49de.entry.js → p-2933d113.entry.js} +1 -1
  105. package/dist/twilight/{p-2d7377e6.entry.js → p-2c29cdf5.entry.js} +1 -1
  106. package/dist/twilight/{p-2684045e.entry.js → p-2e8f7b03.entry.js} +1 -1
  107. package/dist/twilight/{p-85d33ec2.entry.js → p-301f50d5.entry.js} +1 -1
  108. package/dist/twilight/{p-ef28a883.entry.js → p-3482aff4.entry.js} +1 -1
  109. package/dist/twilight/{p-b354fb32.entry.js → p-35c15064.entry.js} +1 -1
  110. package/dist/twilight/{p-5b2567af.entry.js → p-37b7805d.entry.js} +1 -1
  111. package/dist/twilight/{p-2ebf898f.entry.js → p-38375e84.entry.js} +1 -1
  112. package/dist/twilight/{p-2d563fd2.entry.js → p-4985e087.entry.js} +1 -1
  113. package/dist/twilight/{p-5bff3464.entry.js → p-4e3906ea.entry.js} +1 -1
  114. package/dist/twilight/p-5c3edfd3.entry.js +4 -0
  115. package/dist/twilight/{p-b609c0a3.entry.js → p-628cedb8.entry.js} +1 -1
  116. package/dist/twilight/{p-0a7758ed.entry.js → p-64d2b5bf.entry.js} +1 -1
  117. package/dist/twilight/{p-0230315b.entry.js → p-719684b5.entry.js} +1 -1
  118. package/dist/twilight/{p-362bbc51.entry.js → p-7200623e.entry.js} +1 -1
  119. package/dist/twilight/{p-8110e635.entry.js → p-776eaeaa.entry.js} +1 -1
  120. package/dist/twilight/{p-2a4d5b5a.entry.js → p-7b689856.entry.js} +1 -1
  121. package/dist/twilight/{p-c96ebac7.entry.js → p-804c10d1.entry.js} +1 -1
  122. package/dist/twilight/{p-9b001f92.entry.js → p-854d383d.entry.js} +1 -1
  123. package/dist/twilight/{p-b2378248.entry.js → p-88b55062.entry.js} +1 -1
  124. package/dist/twilight/{p-aa85a960.entry.js → p-8c29955b.entry.js} +1 -1
  125. package/dist/twilight/{p-54a6b727.entry.js → p-8f9c2b1a.entry.js} +1 -1
  126. package/dist/twilight/{p-4b2e8325.entry.js → p-97410a23.entry.js} +1 -1
  127. package/dist/twilight/{p-2e338f09.entry.js → p-9b68655d.entry.js} +1 -1
  128. package/dist/twilight/p-Bk0ag9wm.js +9 -0
  129. package/dist/twilight/{p-CJ4oSd-N.js → p-Bmnj4Lo0.js} +1 -1
  130. package/dist/twilight/{p-DVxWyl5d.js → p-CKvjL5Ck.js} +1 -1
  131. package/dist/twilight/{p-oMzSzsXO.js → p-CXmaZL5g.js} +1 -1
  132. package/dist/twilight/{p-DuzBFC4S.js → p-D0KVO4LV.js} +1 -1
  133. package/dist/twilight/{p-BUxBV1_U.js → p-DCz2wWih.js} +1 -1
  134. package/dist/twilight/{p-BdPAI7KX.js → p-De5BFkJn.js} +1 -1
  135. package/dist/twilight/{p-BOK_dArT.js → p-_xsLTh9m.js} +1 -1
  136. package/dist/twilight/{p-62f6d935.entry.js → p-bd8e92c2.entry.js} +1 -1
  137. package/dist/twilight/{p-0c5e2e36.entry.js → p-c0f9a43d.entry.js} +1 -1
  138. package/dist/twilight/p-da7856b7.entry.js +11 -0
  139. package/dist/twilight/{p-9e190a6a.entry.js → p-e185d4a4.entry.js} +1 -1
  140. package/dist/twilight/{p-TjgJW4j-.js → p-vN9q8rrM.js} +1 -1
  141. package/dist/twilight/twilight.esm.js +1 -1
  142. package/dist/types/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-options-modal.d.ts +9 -0
  143. package/dist/types/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-slider.d.ts +11 -1
  144. package/dist/types/components.d.ts +12 -2
  145. package/package.json +5 -5
  146. package/dist/twilight/p-70567b55.entry.js +0 -11
  147. package/dist/twilight/p-7ce146ac.entry.js +0 -4
  148. package/dist/twilight/p-Dkl8u_H6.js +0 -9
@@ -9,6 +9,7 @@ export class SallaMultipleBundleProductOptionsModal {
9
9
  this.sectionIndex = 0;
10
10
  this.productIndex = 0;
11
11
  this.selectedOptions = {};
12
+ this.optionsResetTokens = {};
12
13
  this.isLoading = false;
13
14
  this.hasUnsavedChanges = false;
14
15
  this.validationErrors = [];
@@ -65,17 +66,21 @@ export class SallaMultipleBundleProductOptionsModal {
65
66
  this.selectedOptions = { ...this.selectedOptions };
66
67
  }
67
68
  componentDidLoad() {
68
- salla.event.on('multiple-bundle-product-modal::open', (data) => {
69
+ this.modalOpenListener = (data) => {
69
70
  this.product = data.product;
70
71
  this.sectionId = data.sectionId || null;
71
72
  this.sectionIndex = data.sectionIndex || 0;
72
73
  this.productIndex = data.productIndex || 0;
73
74
  this.open();
74
- });
75
+ };
76
+ salla.event.on('multiple-bundle-product-modal::open', this.modalOpenListener);
75
77
  // Listen for clear-options event when a product is deselected
76
- salla.event.on('multiple-bundle-product-modal::clear-options', (data) => {
77
- this.clearProductOptions(data.productId);
78
- });
78
+ this.clearOptionsListener = (data) => {
79
+ if (!data || !data.productId)
80
+ return;
81
+ this.clearProductOptions(data.productId, data.sectionId, data.productIndex);
82
+ };
83
+ salla.event.on('multiple-bundle-product-modal::clear-options', this.clearOptionsListener);
79
84
  // Create and store the option change listener for proper cleanup
80
85
  this.optionChangeListener = (e) => {
81
86
  const { productId, option, detail } = e.detail;
@@ -100,60 +105,16 @@ export class SallaMultipleBundleProductOptionsModal {
100
105
  // Extract section info from the checkbox name: bundle[sectionId][productIndex][id]
101
106
  const nameMatch = target.name.match(/^bundle\[([^\]]+)\]\[([^\]]+)\]\[id\]$/);
102
107
  if (nameMatch && !target.checked) {
103
- // Product was deselected, clear its cached options
104
108
  const [, sectionId, productIndex] = nameMatch;
105
109
  const productId = target.value;
106
- // Prevent the immediate event to ensure cleanup happens first
107
- e.preventDefault();
108
- e.stopPropagation();
109
- // Ensure the checkbox is actually unchecked
110
- target.checked = false;
111
- // Generate the same cache key used by the modal
112
- const cacheKey = this.generateCacheKey(sectionId, parseInt(productIndex), productId);
113
- // Clear the cached options for this product
114
- const updatedSelectedOptions = { ...this.selectedOptions };
115
- delete updatedSelectedOptions[cacheKey];
116
- this.selectedOptions = updatedSelectedOptions;
117
- // Force re-render of the modal if it's currently open for this product
118
- if (this.product && this.product.id == productId) {
119
- this.selectedOptions = { ...this.selectedOptions };
120
- }
121
110
  const form = this.host.closest('form');
122
- if (form) {
123
- const productInputPattern = `bundle[${sectionId}][${productIndex}]`;
124
- // Get all form inputs and filter manually
125
- const allInputs = Array.from(form.querySelectorAll('input'));
126
- const matchingInputs = allInputs.filter(input => input.name && input.name.startsWith(productInputPattern));
127
- // Process matching inputs for removal
128
- matchingInputs.forEach(el => {
129
- // Don't remove the visible checkbox that was just unchecked
130
- if (el !== target && (el.type === 'hidden' || el.hasAttribute('data-product-id'))) {
131
- el.remove();
132
- }
133
- });
134
- // Method 2: Find inputs by data-product-id BUT only within the same section/productIndex
135
- const dataProductInputs = allInputs.filter(input => {
136
- // Must have data-product-id matching the productId
137
- if (input.getAttribute('data-product-id') !== String(productId)) {
138
- return false;
139
- }
140
- // Must also be within the same section/productIndex pattern
141
- return input.name && input.name.startsWith(productInputPattern);
142
- });
143
- // Process inputs with matching section/productIndex and productId for removal
144
- dataProductInputs.forEach(el => {
145
- if (el !== target) {
146
- el.remove();
147
- }
148
- });
149
- // Method 3: Removed broader search to prevent removing inputs from other products
150
- // The cleanup is now more precise and only removes inputs for the specific product
151
- // Trigger form change event after cleanup is complete
152
- setTimeout(() => {
153
- const changeEvent = new window.Event('change', { bubbles: true });
154
- form.dispatchEvent(changeEvent);
155
- }, 50); // Small delay to ensure cleanup is complete
156
- }
111
+ this.cleanupProductDeselection({
112
+ sectionId,
113
+ productIndex: parseInt(productIndex, 10),
114
+ productId,
115
+ form,
116
+ uncheckedInput: target,
117
+ });
157
118
  }
158
119
  }
159
120
  };
@@ -165,6 +126,37 @@ export class SallaMultipleBundleProductOptionsModal {
165
126
  if (this.checkboxChangeListener) {
166
127
  document.removeEventListener('change', this.checkboxChangeListener);
167
128
  }
129
+ if (this.optionChangeListener) {
130
+ salla.event.off('product-options::change', this.optionChangeListener);
131
+ }
132
+ if (this.modalOpenListener) {
133
+ salla.event.off('multiple-bundle-product-modal::open', this.modalOpenListener);
134
+ }
135
+ if (this.clearOptionsListener) {
136
+ salla.event.off('multiple-bundle-product-modal::clear-options', this.clearOptionsListener);
137
+ }
138
+ }
139
+ cleanupProductDeselection(params) {
140
+ const { sectionId, productIndex, productId, form, uncheckedInput } = params;
141
+ this.clearProductOptions(productId, sectionId, productIndex);
142
+ if (form) {
143
+ const productInputPattern = `bundle[${sectionId}][${productIndex}]`;
144
+ Array.from(form.querySelectorAll(`input[name^="${productInputPattern}"]`)).forEach(input => {
145
+ if (input === uncheckedInput) {
146
+ return;
147
+ }
148
+ const shouldRemoveHidden = input.type === 'hidden';
149
+ const shouldRemoveByDataset = input.getAttribute('data-product-id') === String(productId) &&
150
+ input.name?.startsWith(productInputPattern);
151
+ if (shouldRemoveHidden || shouldRemoveByDataset) {
152
+ input.remove();
153
+ }
154
+ });
155
+ requestAnimationFrame(() => {
156
+ const changeEvent = new window.Event('change', { bubbles: true });
157
+ form.dispatchEvent(changeEvent);
158
+ });
159
+ }
168
160
  }
169
161
  generateFormInputName(sectionId, productIndex, optionParentId) {
170
162
  return `bundle[${sectionId}][${productIndex}][options][${optionParentId}]`;
@@ -191,17 +183,37 @@ export class SallaMultipleBundleProductOptionsModal {
191
183
  }
192
184
  }
193
185
  // Clear options state for a specific product
194
- clearProductOptions(productId) {
195
- // Generate cache key for this specific product in current section context
196
- const cacheKey = this.generateCacheKey(this.sectionId, this.productIndex, productId);
197
- // Remove the product from selectedOptions using the cache key
186
+ clearProductOptions(productId, sectionId, productIndex) {
198
187
  const updatedSelectedOptions = { ...this.selectedOptions };
199
- delete updatedSelectedOptions[cacheKey];
188
+ if (sectionId != null && productIndex != null && !Number.isNaN(productIndex)) {
189
+ const cacheKey = this.generateCacheKey(sectionId, productIndex, productId);
190
+ delete updatedSelectedOptions[cacheKey];
191
+ this.bumpOptionsResetToken(cacheKey);
192
+ }
193
+ else {
194
+ const productSuffix = `-${String(productId)}`;
195
+ const affectedKeys = [];
196
+ Object.keys(updatedSelectedOptions).forEach(key => {
197
+ if (key.endsWith(productSuffix)) {
198
+ delete updatedSelectedOptions[key];
199
+ affectedKeys.push(key);
200
+ }
201
+ });
202
+ affectedKeys.forEach(key => this.bumpOptionsResetToken(key));
203
+ }
200
204
  this.selectedOptions = updatedSelectedOptions;
201
205
  // Reset validation errors and unsaved changes
202
206
  this.validationErrors = [];
203
207
  this.hasUnsavedChanges = false;
204
208
  }
209
+ bumpOptionsResetToken(cacheKey) {
210
+ if (!cacheKey)
211
+ return;
212
+ this.optionsResetTokens = {
213
+ ...this.optionsResetTokens,
214
+ [cacheKey]: (this.optionsResetTokens[cacheKey] || 0) + 1,
215
+ };
216
+ }
205
217
  async handleOptionChange(productId, option, detail) {
206
218
  const cacheKey = this.generateCacheKey(this.sectionId, this.productIndex, productId);
207
219
  // Get the current state from the component to ensure we have the latest selections
@@ -396,6 +408,8 @@ export class SallaMultipleBundleProductOptionsModal {
396
408
  this.optionsSaved.emit({
397
409
  productId: Number(productId),
398
410
  selectedOptions,
411
+ sectionId: this.sectionId,
412
+ productIndex: this.productIndex,
399
413
  });
400
414
  // Emit product selected event to check the card
401
415
  if (this.sectionId) {
@@ -442,7 +456,9 @@ export class SallaMultipleBundleProductOptionsModal {
442
456
  render() {
443
457
  const productId = this.product?.id;
444
458
  const optionsWithSelectedState = this.getOptionsWithSelectedState();
445
- return (h(Host, { key: 'f48867c1730d142b1e55ddb4442c7e7d789a35bb' }, h("salla-modal", { key: '62196cd41c3979ca5e71327d9aad450a819a45ec', isLoading: this.isLoading, ref: el => (this.modal = el), width: "md", centered: false, id: `s-multiple-bundle-product-options-modal-options-${productId}`, class: "s-multiple-bundle-product-options-modal-wrapper" }, h("div", { key: 'feee0e09d5f1dbb19f02b8c109f43e7dc5d1dad8', slot: "loading" }, h("salla-skeleton", { key: '149debcb4852d4096613721a202f4079439abf0a', height: "100%", width: "100%" })), this.product?.images && this.product?.images.length > 0 && (h("salla-slider", { key: '591045fe1d3c9e30bb53a927d3e4d62b54623503', id: `details-slider-${this.product?.id}`, type: "thumbs", loop: false, "auto-height": true, "listen-to-thumbnails-option": true, showThumbsControls: false, controlsOuter: false, showControls: false, class: "s-multiple-bundle-product-options-modal-slider", verticalThumbs: true, thumbsConfig: {
459
+ const cacheKey = this.generateCacheKey(this.sectionId, this.productIndex, productId);
460
+ const resetToken = this.optionsResetTokens[cacheKey] || 0;
461
+ return (h(Host, { key: 'ce4cec97975d0aef32b50a13237a2d64701d8e9f' }, h("salla-modal", { key: 'cda08db7768f0b987a9569ca1170b059a58a417e', isLoading: this.isLoading, ref: el => (this.modal = el), width: "md", centered: false, id: `s-multiple-bundle-product-options-modal-options-${productId}`, class: "s-multiple-bundle-product-options-modal-wrapper" }, h("div", { key: 'd093204f6d85e7a874e0a69a826869e179aeafa4', slot: "loading" }, h("salla-skeleton", { key: '140608027bb0237b62eeb24d1eb5e47c5279c7e3', height: "100%", width: "100%" })), this.product?.images && this.product?.images.length > 0 && (h("salla-slider", { key: '807f2428e8219d9ab6e46163a5d03ad0b2e1b9a3', id: `details-slider-${this.product?.id}`, type: "thumbs", loop: false, "auto-height": true, "listen-to-thumbnails-option": true, showThumbsControls: false, controlsOuter: false, showControls: false, class: "s-multiple-bundle-product-options-modal-slider", verticalThumbs: true, thumbsConfig: {
446
462
  centeredSlides: true,
447
463
  centeredSlidesBounds: true,
448
464
  slidesPerView: Math.min(5, Math.max(1, this.product?.images.length)),
@@ -451,13 +467,13 @@ export class SallaMultipleBundleProductOptionsModal {
451
467
  watchSlidesProgress: true,
452
468
  direction: 'vertical',
453
469
  spaceBetween: 10,
454
- } }, h("div", { key: '1c4163f6d60a89b12d681e3df2db87a523ab092b', slot: "items" }, this.product?.images &&
470
+ } }, h("div", { key: 'f287bea52aa1e3c68debd0b68d011025ea3f9157', slot: "items" }, this.product?.images &&
455
471
  this.product?.images.map((image, index) => (h("div", { key: index, class: "swiper-slide" }, h("img", { src: image.url, alt: image.alt || `${this.product?.name} - Image ${index + 1}`, loading: "lazy", onError: e => {
456
472
  e.target.style.display = 'none';
457
- } }))))), this.product?.images && this.product?.images.length > 1 && (h("div", { key: '911fe5aad35ab3e733871bb185e7a89bb74b6da3', slot: "thumbs" }, this.product?.images &&
473
+ } }))))), this.product?.images && this.product?.images.length > 1 && (h("div", { key: '5d8064ef63c91a660a3b3267afb29e498ac76f4c', slot: "thumbs" }, this.product?.images &&
458
474
  this.product?.images.map((image, index) => (h("div", { key: index, "data-caption": `${this.product?.name} - Image ${index + 1}` }, h("img", { src: image.url, loading: "eager", class: "s-multiple-bundle-product-options-modal-slider-thumb", title: `${this.product?.name} - ${index + 1}`, alt: image.alt || `${this.product?.name} - ${index + 1}`, onError: e => {
459
475
  e.target.style.display = 'none';
460
- } })))))))), h("salla-product-options", { options: JSON.stringify(optionsWithSelectedState), key: `${this.sectionId}-${this.sectionIndex}-${productId}-persistent`, "product-id": productId }), h("div", { key: 'd107ebd058a3f349a5f2f05f4e2b685942d485d6', slot: "footer" }, h("div", { key: '01c7d37a91bb95eb830fcc3290a7cfde9ef7324b', class: "s-multiple-bundle-product-options-modal-footer" }, h("salla-button", { key: '402b9d19c176ebaec8bd7396b9bafe74b81fa456', onClick: e => this.onSave(e), loading: this.isLoading, disabled: this.isLoading }, this.isLoading
476
+ } })))))))), h("salla-product-options", { options: JSON.stringify(optionsWithSelectedState), key: `${cacheKey}-reset-${resetToken}`, "product-id": productId, "unique-key": `${cacheKey}-reset-${resetToken}` }), h("div", { key: '2f6c7f133ccabd75bbb9e8649c056619ce754296', slot: "footer" }, h("div", { key: '1c04908511a480af63fc4e358393514c74967508', class: "s-multiple-bundle-product-options-modal-footer" }, h("salla-button", { key: '49fbad4b1e71004dc8fd6df5d0f1a61b1ef25b8d', onClick: e => this.onSave(e), loading: this.isLoading, disabled: this.isLoading }, this.isLoading
461
477
  ? salla.lang.get('common.elements.saving')
462
478
  : salla.lang.get('common.elements.save')))))));
463
479
  }
@@ -480,6 +496,7 @@ export class SallaMultipleBundleProductOptionsModal {
480
496
  "sectionIndex": {},
481
497
  "productIndex": {},
482
498
  "selectedOptions": {},
499
+ "optionsResetTokens": {},
483
500
  "isLoading": {},
484
501
  "hasUnsavedChanges": {},
485
502
  "validationErrors": {}
@@ -497,8 +514,8 @@ export class SallaMultipleBundleProductOptionsModal {
497
514
  "text": ""
498
515
  },
499
516
  "complexType": {
500
- "original": "{ productId: number; selectedOptions: SelectedOption[] }",
501
- "resolved": "{ productId: number; selectedOptions: SelectedOption[]; }",
517
+ "original": "{\n productId: number;\n selectedOptions: SelectedOption[];\n sectionId?: string | number | null;\n productIndex?: number | null;\n }",
518
+ "resolved": "{ productId: number; selectedOptions: SelectedOption[]; sectionId?: string | number; productIndex?: number; }",
502
519
  "references": {
503
520
  "SelectedOption": {
504
521
  "location": "import",
@@ -1,10 +1,13 @@
1
1
  /*!
2
2
  * Crafted with ❤ by Salla
3
3
  */
4
- import { Host, h } from "@stencil/core";
4
+ import { Host, h, } from "@stencil/core";
5
+ import KeyBoardArrowLeftIcon from "../../../assets/svg/keyboard_arrow_left.svg";
6
+ import KeyBoardArrowRightIcon from "../../../assets/svg/keyboard_arrow_right.svg";
5
7
  export class SallaMultipleBundleProductSlider {
6
8
  constructor() {
7
9
  this.selectedProducts = {};
10
+ this.savedOptionsByInstance = {};
8
11
  this.handleProductClick = (product, productIndex) => {
9
12
  // Find the checkbox input for this product
10
13
  const checkboxId = this.generateEventName(this.section.id, productIndex);
@@ -17,6 +20,10 @@ export class SallaMultipleBundleProductSlider {
17
20
  // Dispatch a change event to trigger form validation/submission
18
21
  const changeEvent = new window.Event('change', { bubbles: true });
19
22
  checkbox.dispatchEvent(changeEvent);
23
+ if (!checkbox.checked) {
24
+ this.clearSavedOptionsState(this.section.id, productIndex);
25
+ this.dispatchClearOptionsEvent(product, productIndex);
26
+ }
20
27
  }
21
28
  this.productSelected.emit({
22
29
  product,
@@ -30,17 +37,66 @@ export class SallaMultipleBundleProductSlider {
30
37
  });
31
38
  };
32
39
  }
40
+ getProductInstanceKey(sectionId, productIndex) {
41
+ return `${sectionId}::${productIndex}`;
42
+ }
43
+ dispatchClearOptionsEvent(product, productIndex) {
44
+ salla.event.dispatch('multiple-bundle-product-modal::clear-options', {
45
+ productId: product.id,
46
+ sectionId: this.section.id,
47
+ sectionIndex: this.sectionIndex,
48
+ productIndex,
49
+ });
50
+ }
51
+ handleOptionsSaved(event) {
52
+ const detail = event.detail;
53
+ if (!detail)
54
+ return;
55
+ const { sectionId, productIndex, selectedOptions } = detail;
56
+ if (sectionId == null || sectionId !== this.section?.id)
57
+ return;
58
+ if (productIndex == null || Number.isNaN(productIndex))
59
+ return;
60
+ const key = this.getProductInstanceKey(sectionId, productIndex);
61
+ const hasOptions = !!selectedOptions?.length;
62
+ if (hasOptions) {
63
+ this.savedOptionsByInstance = {
64
+ ...this.savedOptionsByInstance,
65
+ [key]: true,
66
+ };
67
+ }
68
+ else if (this.savedOptionsByInstance[key]) {
69
+ const updatedState = { ...this.savedOptionsByInstance };
70
+ delete updatedState[key];
71
+ this.savedOptionsByInstance = updatedState;
72
+ }
73
+ }
74
+ clearSavedOptionsState(sectionId, productIndex) {
75
+ const key = this.getProductInstanceKey(sectionId, productIndex);
76
+ if (!this.savedOptionsByInstance[key])
77
+ return;
78
+ const updatedState = { ...this.savedOptionsByInstance };
79
+ delete updatedState[key];
80
+ this.savedOptionsByInstance = updatedState;
81
+ }
33
82
  generateEventName(sectionId, productIndex) {
34
83
  return `bundle[${sectionId}][${productIndex}][id]`;
35
84
  }
36
85
  render() {
37
- return (h(Host, { key: 'ec6fb04196690c5299da565d852ec77bbee6b1e3' }, h("salla-slider", { key: 'a7e79c2f27a53135e55e2708b5aa60d05f9ad21b', type: "carousel", controlsOuter: false, showControls: false, id: "accordion-multiple-bundle-product", pagination: true, class: "s-multiple-bundle-product-wrapper-slider", sliderConfig: {
86
+ return (h(Host, { key: '234e93258c3d7ca5d7dc08efb68743d042646706' }, h("salla-slider", { key: '451184823378e4ad0c9034d3af1b87373bcb7d20', type: "carousel", controlsOuter: false, showControls: false, id: "accordion-multiple-bundle-product", pagination: true, class: "s-multiple-bundle-product-wrapper-slider", sliderConfig: {
38
87
  spaceBetween: 0,
39
- } }, h("div", { key: 'c07aa5a0ee4fe106764b47dfa6d9f6509fb659cf', slot: "items" }, this?.section?.products?.map((product, productIndex) => {
88
+ } }, h("div", { key: '28c1acfd37a77059d4c177b787dca9deea47d123', slot: "items" }, this?.section?.products?.map((product, productIndex) => {
40
89
  const isChecked = this.selectedProducts[this.section.id]?.has(product.id) || false;
41
- return (h("div", { class: `swiper-slide s-multiple-bundle-product-slide-one-third ${product.quantity == 0
90
+ const hasSavedOptions = this.savedOptionsByInstance[this.getProductInstanceKey(this.section.id, productIndex)];
91
+ const optionsButtonLabel = hasSavedOptions
92
+ ? salla.lang.getWithDefault('pages.products.edit_selected_options', 'تعديل الخيارات')
93
+ : salla.lang.get('pages.products.choose_from_options');
94
+ let optionsArrowIcon = salla.config.get('theme.is_rtl', true)
95
+ ? KeyBoardArrowLeftIcon
96
+ : KeyBoardArrowRightIcon;
97
+ return (h("div", { class: `s-multiple-bundle-product-slide-one-third ${product.quantity == 0
42
98
  ? 's-multiple-bundle-product-slide-one-third-disabled'
43
- : ''}`, key: product.id }, h("div", { class: "s-multiple-bundle-product-card" }, h("div", { class: "s-multiple-bundle-product-image-wrapper", onClick: () => this.handleProductClick(product, productIndex) }, h("input", { id: this.generateEventName(this.section.id, productIndex), type: "checkbox", class: "s-multiple-bundle-product-checkbox", checked: isChecked, name: this.generateEventName(this.section.id, productIndex), value: product.id }), h("img", { src: product.image.url || salla.url.cdn('images/s-empty.png'), loading: "lazy", alt: product.image.alt || product.name, class: "s-multiple-bundle-product-image" })), h("div", { class: "s-multiple-bundle-product-content-wrapper" }, h("div", { class: "s-multiple-bundle-product-content" }, h("div", { class: "s-multiple-bundle-product-details" }, h("div", { class: "s-multiple-bundle-product-title-wrapper" }, h("h2", { class: "s-multiple-bundle-product-title" }, product.name)), h("div", { class: "s-multiple-bundle-product-price-wrapper" }, h("span", { class: "s-multiple-bundle-product-price" }, h("span", { innerHTML: salla.money(product.price) })), product.sale_price > 0 && (h("span", { class: "s-multiple-bundle-product-price-discount" }, h("span", { innerHTML: salla.money(product.sale_price) }))))), product.quantity_in_group > 0 && product.quantity !== 0 && (h("span", { class: "s-multiple-bundle-product-badge" }, salla.lang.get('pages.products.pieces'), h("span", null, product.quantity_in_group))), product.quantity === 0 && (h("span", { class: "s-multiple-bundle-product-badge" }, salla.lang.get('pages.products.quantity_in_group_finished')))), product.options?.length > 0 && (h("button", { class: "s-multiple-bundle-product-button", onClick: () => this.handleOptionsClick(product), type: "button" }, salla.lang.get('pages.products.choose_from_options'), h("i", { class: "sicon-keyboard_arrow_left s-multiple-bundle-product-button-icon" })))))));
99
+ : ''}`, key: product.id }, h("div", { class: "s-multiple-bundle-product-card" }, h("div", { class: "s-multiple-bundle-product-image-wrapper", onClick: () => this.handleProductClick(product, productIndex) }, h("input", { id: this.generateEventName(this.section.id, productIndex), type: "checkbox", class: "s-multiple-bundle-product-checkbox", checked: isChecked, name: this.generateEventName(this.section.id, productIndex), value: product.id }), h("img", { src: product.image.url || salla.url.cdn('images/s-empty.png'), loading: "lazy", alt: product.image.alt || product.name, class: "s-multiple-bundle-product-image" })), h("div", { class: "s-multiple-bundle-product-content-wrapper" }, h("div", { class: "s-multiple-bundle-product-content" }, h("div", { class: "s-multiple-bundle-product-details" }, h("div", { class: "s-multiple-bundle-product-title-wrapper" }, h("h2", { class: "s-multiple-bundle-product-title" }, product.name)), h("div", { class: "s-multiple-bundle-product-price-wrapper" }, h("span", { class: "s-multiple-bundle-product-price" }, h("span", { innerHTML: salla.money(product.price) })), product.sale_price > 0 && (h("span", { class: "s-multiple-bundle-product-price-discount" }, h("span", { innerHTML: salla.money(product.sale_price) }))))), product.quantity_in_group > 0 && product.quantity !== 0 && (h("span", { class: "s-multiple-bundle-product-badge" }, salla.lang.get('pages.products.pieces'), h("span", null, product.quantity_in_group))), product.quantity === 0 && (h("span", { class: "s-multiple-bundle-product-badge" }, salla.lang.get('pages.products.quantity_in_group_finished')))), product.options?.length > 0 && (h("button", { class: "s-multiple-bundle-product-button", onClick: () => this.handleOptionsClick(product), type: "button" }, optionsButtonLabel, h("span", { class: "s-multiple-bundle-product-button-icon", innerHTML: optionsArrowIcon })))))));
44
100
  })))));
45
101
  }
46
102
  static get is() { return "salla-multiple-bundle-product-slider"; }
@@ -125,6 +181,11 @@ export class SallaMultipleBundleProductSlider {
125
181
  }
126
182
  };
127
183
  }
184
+ static get states() {
185
+ return {
186
+ "savedOptionsByInstance": {}
187
+ };
188
+ }
128
189
  static get events() {
129
190
  return [{
130
191
  "method": "productSelected",
@@ -171,4 +232,13 @@ export class SallaMultipleBundleProductSlider {
171
232
  }];
172
233
  }
173
234
  static get elementRef() { return "host"; }
235
+ static get listeners() {
236
+ return [{
237
+ "name": "optionsSaved",
238
+ "method": "handleOptionsSaved",
239
+ "target": "document",
240
+ "capture": false,
241
+ "passive": false
242
+ }];
243
+ }
174
244
  }