@salla.sa/twilight-components 2.14.272 → 2.14.274

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 (247) hide show
  1. package/dist/cjs/{filepond-EG2Mf8a1.js → filepond-L1nMkdqn.js} +1 -1
  2. package/dist/cjs/{filepond-plugin-file-poster-DjNsnxTw.js → filepond-plugin-file-poster-BYZl5BE2.js} +1 -1
  3. package/dist/cjs/{filepond-plugin-file-validate-size-BlM1btNO.js → filepond-plugin-file-validate-size-DSrSXg4-.js} +1 -1
  4. package/dist/cjs/{filepond-plugin-file-validate-type-DhymSoh9.js → filepond-plugin-file-validate-type-CgnsyE2V.js} +1 -1
  5. package/dist/cjs/{filepond-plugin-image-edit-BQfvfpQ1.js → filepond-plugin-image-edit-lODj8ghv.js} +1 -1
  6. package/dist/cjs/{filepond-plugin-image-exif-orientation-DOi06s13.js → filepond-plugin-image-exif-orientation-uQ5EYlsy.js} +1 -1
  7. package/dist/cjs/{filepond-plugin-image-preview-Rfix7Xbt.js → filepond-plugin-image-preview-Cm1OgAvZ.js} +1 -1
  8. package/dist/cjs/{index-DS7mXxWq.js → index-BEeccvkl.js} +136 -26
  9. package/dist/cjs/{index-vIV5iX-W.js → index-D0NII6ks.js} +1 -1
  10. package/dist/cjs/loader.cjs.js +3 -4
  11. package/dist/cjs/{salla-add-product-button_51.cjs.entry.js → salla-accordion_62.cjs.entry.js} +2104 -120
  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 +2 -2
  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-accordion_4.cjs.entry.js → salla-order-details-options.cjs.entry.js} +1 -100
  29. package/dist/cjs/salla-order-details.cjs.entry.js +2 -2
  30. package/dist/cjs/salla-order-summary.cjs.entry.js +2 -2
  31. package/dist/cjs/salla-orders.cjs.entry.js +1 -1
  32. package/dist/cjs/salla-payments.cjs.entry.js +3 -3
  33. package/dist/cjs/salla-price-range.cjs.entry.js +3 -3
  34. package/dist/cjs/salla-review-card.cjs.entry.js +2 -2
  35. package/dist/cjs/salla-reviews-page.cjs.entry.js +2 -2
  36. package/dist/cjs/salla-reviews.cjs.entry.js +2 -2
  37. package/dist/cjs/salla-social.cjs.entry.js +2 -2
  38. package/dist/cjs/salla-tiered-offer.cjs.entry.js +1 -1
  39. package/dist/cjs/salla-tooltip.cjs.entry.js +2 -2
  40. package/dist/cjs/salla-verify.cjs.entry.js +1 -1
  41. package/dist/cjs/salla-wallet.cjs.entry.js +1 -1
  42. package/dist/cjs/twilight.cjs.js +3 -4
  43. package/dist/collection/collection-manifest.json +5 -0
  44. package/dist/collection/components/salla-accordion/salla-accordion-head.js +8 -2
  45. package/dist/collection/components/salla-comments/salla-comments.js +20 -1
  46. package/dist/collection/components/salla-conditional-fields/salla-conditional-fields.js +33 -5
  47. package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-cart.css +0 -0
  48. package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-cart.js +89 -0
  49. package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-details.css +0 -0
  50. package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-details.js +195 -0
  51. package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-options-modal.css +3 -0
  52. package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-options-modal.js +595 -0
  53. package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-slider.css +0 -0
  54. package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-slider.js +174 -0
  55. package/dist/collection/components/salla-multiple-bundle-product/interfaces.js +1 -0
  56. package/dist/collection/components/salla-multiple-bundle-product/salla-multiple-bundle-product.css +3 -0
  57. package/dist/collection/components/salla-multiple-bundle-product/salla-multiple-bundle-product.js +132 -0
  58. package/dist/collection/components/salla-notifications/salla-notification-item.js +1 -1
  59. package/dist/collection/components/salla-offer-modal/salla-offer-modal.js +1 -1
  60. package/dist/collection/components/salla-order-details/salla-order-details.js +1 -1
  61. package/dist/collection/components/salla-order-summary/salla-order-summary.js +1 -1
  62. package/dist/collection/components/salla-payments/salla-payments.js +2 -2
  63. package/dist/collection/components/salla-placeholder/salla-placeholder.js +1 -1
  64. package/dist/collection/components/salla-price-range/salla-price-range.js +2 -2
  65. package/dist/collection/components/salla-product-availability/salla-product-availability.js +1 -1
  66. package/dist/collection/components/salla-product-card/salla-product-card.js +5 -5
  67. package/dist/collection/components/salla-product-options/salla-product-options.js +105 -22
  68. package/dist/collection/components/salla-product-size-guide/salla-product-size-guide.js +2 -2
  69. package/dist/collection/components/salla-quantity-input/salla-quantity-input.js +1 -1
  70. package/dist/collection/components/salla-quick-buy/salla-quick-buy.js +1 -1
  71. package/dist/collection/components/salla-review-card/salla-review-card.js +1 -1
  72. package/dist/collection/components/salla-reviews/salla-reviews.js +1 -1
  73. package/dist/collection/components/salla-reviews-page/salla-reviews-page.js +1 -1
  74. package/dist/collection/components/salla-scopes/salla-scopes.js +1 -1
  75. package/dist/collection/components/salla-search/salla-search.js +3 -3
  76. package/dist/collection/components/salla-skeleton/salla-skeleton.js +1 -1
  77. package/dist/collection/components/salla-slider/salla-slider.js +2 -2
  78. package/dist/collection/components/salla-social/salla-social.js +1 -1
  79. package/dist/collection/components/salla-social-share/salla-social-share.js +1 -1
  80. package/dist/collection/components/salla-tabs/salla-tab-content.js +1 -1
  81. package/dist/collection/components/salla-tabs/salla-tab-header.js +1 -1
  82. package/dist/collection/components/salla-tabs/salla-tabs.js +1 -1
  83. package/dist/collection/components/salla-tel-input/salla-tel-input.js +1 -1
  84. package/dist/collection/components/salla-tooltip/salla-tooltip.js +1 -1
  85. package/dist/collection/components/salla-user-settings/salla-user-settings.js +1 -1
  86. package/dist/components/index.js +2 -2
  87. package/dist/components/salla-accordion-head2.js +2 -2
  88. package/dist/components/salla-comments.js +20 -1
  89. package/dist/components/salla-conditional-fields2.js +28 -6
  90. package/dist/components/salla-multiple-bundle-product-cart.d.ts +11 -0
  91. package/dist/components/salla-multiple-bundle-product-cart.js +9 -0
  92. package/dist/components/salla-multiple-bundle-product-cart2.js +153 -0
  93. package/dist/components/salla-multiple-bundle-product-details.d.ts +11 -0
  94. package/dist/components/salla-multiple-bundle-product-details.js +9 -0
  95. package/dist/components/salla-multiple-bundle-product-details2.js +283 -0
  96. package/dist/components/salla-multiple-bundle-product-options-modal.d.ts +11 -0
  97. package/dist/components/salla-multiple-bundle-product-options-modal.js +9 -0
  98. package/dist/components/salla-multiple-bundle-product-options-modal2.js +585 -0
  99. package/dist/components/salla-multiple-bundle-product-slider.d.ts +11 -0
  100. package/dist/components/salla-multiple-bundle-product-slider.js +9 -0
  101. package/dist/components/salla-multiple-bundle-product-slider2.js +81 -0
  102. package/dist/components/salla-multiple-bundle-product.d.ts +11 -0
  103. package/dist/components/salla-multiple-bundle-product.js +210 -0
  104. package/dist/components/salla-notification-item2.js +1 -1
  105. package/dist/components/salla-offer-modal.js +1 -1
  106. package/dist/components/salla-order-details.js +1 -1
  107. package/dist/components/salla-order-summary.js +1 -1
  108. package/dist/components/salla-payments.js +2 -2
  109. package/dist/components/salla-placeholder2.js +1 -1
  110. package/dist/components/salla-price-range2.js +2 -2
  111. package/dist/components/salla-product-availability2.js +1 -1
  112. package/dist/components/salla-product-card2.js +5 -5
  113. package/dist/components/salla-product-options.js +1 -810
  114. package/dist/{esm/salla-product-options.entry.js → components/salla-product-options2.js} +197 -30
  115. package/dist/components/salla-product-size-guide.js +2 -2
  116. package/dist/components/salla-quantity-input.js +1 -1
  117. package/dist/components/salla-quick-buy2.js +1 -1
  118. package/dist/components/salla-review-card2.js +1 -1
  119. package/dist/components/salla-reviews-page.js +1 -1
  120. package/dist/components/salla-reviews.js +1 -1
  121. package/dist/components/salla-scopes.js +1 -1
  122. package/dist/components/salla-search.js +3 -3
  123. package/dist/components/salla-skeleton2.js +1 -1
  124. package/dist/components/salla-slider2.js +2 -2
  125. package/dist/components/salla-social-share.js +1 -1
  126. package/dist/components/salla-social.js +1 -1
  127. package/dist/components/salla-tab-content2.js +1 -1
  128. package/dist/components/salla-tab-header2.js +1 -1
  129. package/dist/components/salla-tabs2.js +1 -1
  130. package/dist/components/salla-tel-input2.js +1 -1
  131. package/dist/components/salla-tooltip2.js +1 -1
  132. package/dist/components/salla-user-settings.js +1 -1
  133. package/dist/esm/{filepond-DbR8YXoW.js → filepond-JStnJXdo.js} +1 -1
  134. package/dist/esm/{filepond-plugin-file-poster-DEj3O3wZ.js → filepond-plugin-file-poster-13kSl6pa.js} +1 -1
  135. package/dist/esm/{filepond-plugin-file-validate-size-DYnIp5yF.js → filepond-plugin-file-validate-size-DGYz9wX6.js} +1 -1
  136. package/dist/esm/{filepond-plugin-file-validate-type-Cx_PD8SU.js → filepond-plugin-file-validate-type-7M_EeTPs.js} +1 -1
  137. package/dist/esm/{filepond-plugin-image-edit-BwmXRkmP.js → filepond-plugin-image-edit-C5N0Q0IF.js} +1 -1
  138. package/dist/esm/{filepond-plugin-image-exif-orientation-BtsMS4U-.js → filepond-plugin-image-exif-orientation-BvYJ1LVk.js} +1 -1
  139. package/dist/esm/{filepond-plugin-image-preview-DQ0c3hIt.js → filepond-plugin-image-preview-P4HnGsSt.js} +1 -1
  140. package/dist/esm/{index-D5PGwR59.js → index-Bdj1TBK9.js} +136 -26
  141. package/dist/esm/{index-xiIpq8fU.js → index-CqLymITv.js} +1 -1
  142. package/dist/esm/loader.js +3 -4
  143. package/dist/esm/{salla-add-product-button_51.entry.js → salla-accordion_62.entry.js} +2084 -111
  144. package/dist/esm/salla-advertisement.entry.js +1 -1
  145. package/dist/esm/salla-app-install-alert.entry.js +1 -1
  146. package/dist/esm/salla-apps-icons.entry.js +1 -1
  147. package/dist/esm/salla-cart-item-offers.entry.js +1 -1
  148. package/dist/esm/salla-conditional-offer.entry.js +1 -1
  149. package/dist/esm/salla-contacts.entry.js +1 -1
  150. package/dist/esm/salla-filters-widget.entry.js +1 -1
  151. package/dist/esm/salla-filters.entry.js +1 -1
  152. package/dist/esm/salla-installment.entry.js +1 -1
  153. package/dist/esm/salla-loyalty-prize-item.entry.js +1 -1
  154. package/dist/esm/salla-loyalty-program.entry.js +1 -1
  155. package/dist/esm/salla-metadata.entry.js +1 -1
  156. package/dist/esm/salla-notification-item.entry.js +2 -2
  157. package/dist/esm/salla-notifications.entry.js +1 -1
  158. package/dist/esm/salla-offer.entry.js +1 -1
  159. package/dist/esm/salla-order-details-multiple-bundle-product.entry.js +1 -1
  160. package/dist/esm/{salla-accordion_4.entry.js → salla-order-details-options.entry.js} +2 -98
  161. package/dist/esm/salla-order-details.entry.js +2 -2
  162. package/dist/esm/salla-order-summary.entry.js +2 -2
  163. package/dist/esm/salla-orders.entry.js +1 -1
  164. package/dist/esm/salla-payments.entry.js +3 -3
  165. package/dist/esm/salla-price-range.entry.js +3 -3
  166. package/dist/esm/salla-review-card.entry.js +2 -2
  167. package/dist/esm/salla-reviews-page.entry.js +2 -2
  168. package/dist/esm/salla-reviews.entry.js +2 -2
  169. package/dist/esm/salla-social.entry.js +2 -2
  170. package/dist/esm/salla-tiered-offer.entry.js +1 -1
  171. package/dist/esm/salla-tooltip.entry.js +2 -2
  172. package/dist/esm/salla-verify.entry.js +1 -1
  173. package/dist/esm/salla-wallet.entry.js +1 -1
  174. package/dist/esm/twilight.js +3 -4
  175. package/dist/twilight/{p-56fa3b9c.entry.js → p-0f8534fd.entry.js} +1 -1
  176. package/dist/twilight/{p-3f412ab2.entry.js → p-1be88437.entry.js} +1 -1
  177. package/dist/twilight/{p-10856491.entry.js → p-1d81f143.entry.js} +1 -1
  178. package/dist/twilight/{p-4611a11b.entry.js → p-282f4f69.entry.js} +1 -1
  179. package/dist/twilight/{p-9e3f55be.entry.js → p-34e10e96.entry.js} +1 -1
  180. package/dist/twilight/{p-c15928d5.entry.js → p-3a4137eb.entry.js} +1 -1
  181. package/dist/twilight/{p-0ffafdea.entry.js → p-456d49c3.entry.js} +1 -1
  182. package/dist/twilight/{p-a61e2b8e.entry.js → p-4d05539c.entry.js} +1 -1
  183. package/dist/twilight/{p-e3b0a71f.entry.js → p-550d2b59.entry.js} +1 -1
  184. package/dist/twilight/{p-de200512.entry.js → p-57629f65.entry.js} +1 -1
  185. package/dist/twilight/p-5971eca7.entry.js +4 -0
  186. package/dist/twilight/p-723d7b1b.entry.js +4 -0
  187. package/dist/twilight/{p-92848d53.entry.js → p-78e6e403.entry.js} +1 -1
  188. package/dist/twilight/{p-2613f6dc.entry.js → p-895bd462.entry.js} +1 -1
  189. package/dist/twilight/p-9760fa21.entry.js +4 -0
  190. package/dist/twilight/{p-C4wd-bXb.js → p-AhRhML1e.js} +1 -1
  191. package/dist/twilight/{p-Bvez5luh.js → p-BP3jjHyr.js} +1 -1
  192. package/dist/twilight/{p-D5PGwR59.js → p-Bdj1TBK9.js} +2 -2
  193. package/dist/twilight/{p-BsHa_73h.js → p-Btn8p1Mk.js} +1 -1
  194. package/dist/twilight/{p-D0ZZ4jO5.js → p-CDM6fsL2.js} +2 -2
  195. package/dist/twilight/{p-CH8-uKSN.js → p-Ccp_rmSW.js} +1 -1
  196. package/dist/twilight/{p-DV_VEuIe.js → p-D6-aDTP4.js} +1 -1
  197. package/dist/twilight/{p-D5p2t_CX.js → p-DD6CdbcU.js} +1 -1
  198. package/dist/twilight/{p-DEUne75O.js → p-DYhkBiMu.js} +1 -1
  199. package/dist/twilight/p-a1e9d695.entry.js +4 -0
  200. package/dist/twilight/{p-eaad31d1.entry.js → p-a5681537.entry.js} +1 -1
  201. package/dist/twilight/{p-e95284d7.entry.js → p-a8d01888.entry.js} +1 -1
  202. package/dist/twilight/p-b254a752.entry.js +4 -0
  203. package/dist/twilight/{p-eae51196.entry.js → p-bd7a0c4f.entry.js} +1 -1
  204. package/dist/twilight/{p-7df916fc.entry.js → p-bf90a8c8.entry.js} +1 -1
  205. package/dist/twilight/p-c293f9c1.entry.js +11 -0
  206. package/dist/twilight/{p-b94ebbd9.entry.js → p-c9ad0ad1.entry.js} +1 -1
  207. package/dist/twilight/p-cc93a79e.entry.js +4 -0
  208. package/dist/twilight/{p-2bf21126.entry.js → p-e825aae4.entry.js} +1 -1
  209. package/dist/twilight/{p-8ba8efe1.entry.js → p-e99645f0.entry.js} +1 -1
  210. package/dist/twilight/{p-f3c29342.entry.js → p-f232e683.entry.js} +1 -1
  211. package/dist/twilight/{p-65b1fcea.entry.js → p-f7784dda.entry.js} +1 -1
  212. package/dist/twilight/{p-280c1f64.entry.js → p-f85916d5.entry.js} +1 -1
  213. package/dist/twilight/{p-bcab2639.entry.js → p-f96be282.entry.js} +1 -1
  214. package/dist/twilight/{p-b40d5871.entry.js → p-faee9d58.entry.js} +1 -1
  215. package/dist/twilight/twilight.esm.js +1 -1
  216. package/dist/types/components/salla-accordion/salla-accordion-head.d.ts +6 -0
  217. package/dist/types/components/salla-conditional-fields/salla-conditional-fields.d.ts +2 -0
  218. package/dist/types/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-cart.d.ts +10 -0
  219. package/dist/types/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-details.d.ts +20 -0
  220. package/dist/types/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-options-modal.d.ts +46 -0
  221. package/dist/types/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-slider.d.ts +22 -0
  222. package/dist/types/components/salla-multiple-bundle-product/interfaces.d.ts +101 -0
  223. package/dist/types/components/salla-multiple-bundle-product/salla-multiple-bundle-product.d.ts +42 -0
  224. package/dist/types/components/salla-product-options/salla-product-options.d.ts +21 -1
  225. package/dist/types/components.d.ts +298 -2
  226. package/package.json +5 -5
  227. package/dist/cjs/app-globals-OVEmNa5W.js +0 -38
  228. package/dist/cjs/camera-DytepEoK.js +0 -13
  229. package/dist/cjs/minus-CCryh1qf.js +0 -21
  230. package/dist/cjs/salla-booking-field_2.cjs.entry.js +0 -280
  231. package/dist/cjs/salla-product-options.cjs.entry.js +0 -715
  232. package/dist/esm/app-globals-BKgAyoNJ.js +0 -36
  233. package/dist/esm/camera-C6jIkM-X.js +0 -11
  234. package/dist/esm/minus-DfeagqF1.js +0 -18
  235. package/dist/esm/salla-booking-field_2.entry.js +0 -277
  236. package/dist/twilight/p-19c38b4a.entry.js +0 -11
  237. package/dist/twilight/p-8272b58f.entry.js +0 -4
  238. package/dist/twilight/p-989fcbb4.entry.js +0 -4
  239. package/dist/twilight/p-9f47b72b.entry.js +0 -4
  240. package/dist/twilight/p-C6jIkM-X.js +0 -4
  241. package/dist/twilight/p-DfeagqF1.js +0 -4
  242. package/dist/twilight/p-KHt1Smzh.js +0 -4
  243. package/dist/twilight/p-b8d41065.entry.js +0 -4
  244. package/dist/twilight/p-dd9695d6.entry.js +0 -4
  245. package/dist/twilight/p-e2ebb686.entry.js +0 -4
  246. package/dist/twilight/p-e30f7c20.entry.js +0 -4
  247. package/dist/twilight/p-fcb3e719.entry.js +0 -4
@@ -0,0 +1,595 @@
1
+ /*!
2
+ * Crafted with ❤ by Salla
3
+ */
4
+ import { Host, h } from "@stencil/core";
5
+ export class SallaMultipleBundleProductOptionsModal {
6
+ constructor() {
7
+ this.product = null;
8
+ this.sectionId = null;
9
+ this.sectionIndex = 0;
10
+ this.productIndex = 0;
11
+ this.selectedOptions = {};
12
+ this.isLoading = false;
13
+ this.hasUnsavedChanges = false;
14
+ this.validationErrors = [];
15
+ }
16
+ /**
17
+ * Generate a unique cache key for selected options using section ID, product index, and product ID
18
+ */
19
+ generateCacheKey(sectionId, productIndex, productId) {
20
+ return `${sectionId || 'unknown'}-${productIndex || 0}-${productId || 'unknown'}`;
21
+ }
22
+ handleProductChange(newValue) {
23
+ // Use setTimeout to ensure modal is ready
24
+ setTimeout(() => {
25
+ if (this.modal && newValue) {
26
+ const title = newValue.name || '';
27
+ this.modal.setTitle(title);
28
+ }
29
+ }, 100);
30
+ // Reset validation errors when product changes
31
+ this.validationErrors = [];
32
+ this.hasUnsavedChanges = false;
33
+ }
34
+ async open() {
35
+ if (!this.modal) {
36
+ requestAnimationFrame(() => this.open());
37
+ return;
38
+ }
39
+ this.isLoading = true;
40
+ // Set the title before opening
41
+ if (this.product?.name) {
42
+ this.modal.setTitle(this.product.name);
43
+ }
44
+ this.modal.open();
45
+ // Initialize selectedOptions with current selections from the component
46
+ setTimeout(async () => {
47
+ if (this.product?.id) {
48
+ await this.initializeSelectedOptions();
49
+ }
50
+ // Set title again after modal is fully loaded
51
+ if (this.product?.name) {
52
+ this.modal.setTitle(this.product.name);
53
+ }
54
+ this.modal.stopLoading();
55
+ this.isLoading = false;
56
+ }, 300);
57
+ }
58
+ async close() {
59
+ if (this.modal) {
60
+ this.modal.close();
61
+ }
62
+ }
63
+ async refreshOptionsState() {
64
+ // Force re-render by updating the component state
65
+ this.selectedOptions = { ...this.selectedOptions };
66
+ }
67
+ componentDidLoad() {
68
+ salla.event.on('multiple-bundle-product-modal::open', (data) => {
69
+ this.product = data.product;
70
+ this.sectionId = data.sectionId || null;
71
+ this.sectionIndex = data.sectionIndex || 0;
72
+ this.productIndex = data.productIndex || 0;
73
+ this.open();
74
+ });
75
+ // 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
+ });
79
+ // Create and store the option change listener for proper cleanup
80
+ this.optionChangeListener = (e) => {
81
+ const { productId, option, detail } = e.detail;
82
+ // Convert productId to the same type as our product ID
83
+ const normalizedProductId = this.product?.id ? String(this.product.id) : null;
84
+ const normalizedEventProductId = productId ? String(productId) : null;
85
+ // Only handle events for the current product
86
+ if (normalizedProductId &&
87
+ normalizedEventProductId &&
88
+ normalizedProductId === normalizedEventProductId &&
89
+ option &&
90
+ detail) {
91
+ this.handleOptionChange(Number(normalizedProductId), option, detail);
92
+ }
93
+ };
94
+ salla.event.on('product-options::change', this.optionChangeListener);
95
+ // Create and store the checkbox change listener for proper cleanup
96
+ this.checkboxChangeListener = (e) => {
97
+ const target = e.target;
98
+ // Check if this is a product selection checkbox
99
+ if (target && target.type === 'checkbox' && target.name && target.name.includes('bundle[') && target.name.includes('][id]')) {
100
+ // Extract section info from the checkbox name: bundle[sectionId][productIndex][id]
101
+ const nameMatch = target.name.match(/^bundle\[([^\]]+)\]\[([^\]]+)\]\[id\]$/);
102
+ if (nameMatch && !target.checked) {
103
+ // Product was deselected, clear its cached options
104
+ const [, sectionId, productIndex] = nameMatch;
105
+ 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
+ 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
+ }
157
+ }
158
+ }
159
+ };
160
+ // Listen for product checkbox changes to reset options when product is deselected
161
+ document.addEventListener('change', this.checkboxChangeListener);
162
+ }
163
+ disconnectedCallback() {
164
+ // Clean up event listeners to prevent memory leaks
165
+ if (this.checkboxChangeListener) {
166
+ document.removeEventListener('change', this.checkboxChangeListener);
167
+ }
168
+ }
169
+ generateFormInputName(sectionId, productIndex, optionParentId) {
170
+ return `bundle[${sectionId}][${productIndex}][options][${optionParentId}]`;
171
+ }
172
+ async initializeSelectedOptions() {
173
+ if (!this.product?.id)
174
+ return;
175
+ const productId = this.product.id;
176
+ const cacheKey = this.generateCacheKey(this.sectionId, this.productIndex, productId);
177
+ const optionsEl = document.querySelector(`salla-product-options[product-id="${productId}"]`);
178
+ if (optionsEl) {
179
+ try {
180
+ const selectedOptions = await optionsEl.getSelectedOptions();
181
+ if (selectedOptions && selectedOptions.length > 0) {
182
+ this.selectedOptions = {
183
+ ...this.selectedOptions,
184
+ [cacheKey]: selectedOptions,
185
+ };
186
+ }
187
+ }
188
+ catch (e) {
189
+ console.warn('Could not initialize selected options:', e);
190
+ }
191
+ }
192
+ }
193
+ // 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
198
+ const updatedSelectedOptions = { ...this.selectedOptions };
199
+ delete updatedSelectedOptions[cacheKey];
200
+ this.selectedOptions = updatedSelectedOptions;
201
+ // Reset validation errors and unsaved changes
202
+ this.validationErrors = [];
203
+ this.hasUnsavedChanges = false;
204
+ }
205
+ async handleOptionChange(productId, option, detail) {
206
+ const cacheKey = this.generateCacheKey(this.sectionId, this.productIndex, productId);
207
+ // Get the current state from the component to ensure we have the latest selections
208
+ const optionsEl = document.querySelector(`salla-product-options[product-id="${productId}"]`);
209
+ let currentComponentSelections = [];
210
+ if (optionsEl) {
211
+ try {
212
+ currentComponentSelections = (await optionsEl.getSelectedOptions()) || [];
213
+ }
214
+ catch (e) {
215
+ console.warn('Could not get current selections from component:', e);
216
+ }
217
+ }
218
+ // If component returns data, use it; otherwise, fall back to manual tracking
219
+ if (currentComponentSelections.length > 0) {
220
+ // Component returned data, use it
221
+ this.selectedOptions = {
222
+ ...this.selectedOptions,
223
+ [cacheKey]: currentComponentSelections,
224
+ };
225
+ }
226
+ else {
227
+ // If we have existing selections in internal state and component returns empty,
228
+ // it might be a deselection, so we should use manual tracking
229
+ if (this.selectedOptions[cacheKey] && this.selectedOptions[cacheKey].length > 0) {
230
+ // Component didn't return data, use manual tracking
231
+ const currentSelected = this.selectedOptions[cacheKey] || [];
232
+ const updatedSelected = [...currentSelected];
233
+ // Find existing selection for this specific option (by option_id)
234
+ const existingIndex = updatedSelected.findIndex(opt => opt.option_id === option.id);
235
+ if (existingIndex > -1) {
236
+ // Check if this is a deselection (detail might be null or undefined)
237
+ if (!detail || detail.id === null || detail.id === undefined) {
238
+ // Remove the option (deselection)
239
+ updatedSelected.splice(existingIndex, 1);
240
+ }
241
+ else {
242
+ // Replace existing selection for this option
243
+ updatedSelected[existingIndex] = { ...detail, option_id: option.id };
244
+ }
245
+ }
246
+ else {
247
+ // Only add if detail exists (not a deselection)
248
+ if (detail && detail.id !== null && detail.id !== undefined) {
249
+ updatedSelected.push({ ...detail, option_id: option.id });
250
+ }
251
+ }
252
+ this.selectedOptions = {
253
+ ...this.selectedOptions,
254
+ [cacheKey]: updatedSelected,
255
+ };
256
+ }
257
+ else {
258
+ // No existing selections, component returned empty, and we're trying to add
259
+ // This might be the first selection, so add it manually
260
+ if (detail && detail.id !== null && detail.id !== undefined) {
261
+ this.selectedOptions = {
262
+ ...this.selectedOptions,
263
+ [cacheKey]: [{ ...detail, option_id: option.id }],
264
+ };
265
+ }
266
+ }
267
+ }
268
+ this.hasUnsavedChanges = true;
269
+ this.validationErrors = []; // Clear validation errors when user makes changes
270
+ }
271
+ async validateOptions() {
272
+ if (!this.product?.options)
273
+ return true;
274
+ const errors = [];
275
+ const productId = this.product.id;
276
+ const cacheKey = this.generateCacheKey(this.sectionId, this.productIndex, productId);
277
+ // Get the actual selected options from the component
278
+ const optionsEl = document.querySelector(`salla-product-options[product-id="${productId}"]`);
279
+ let currentSelected = [];
280
+ if (optionsEl) {
281
+ try {
282
+ currentSelected = (await optionsEl.getSelectedOptions()) || [];
283
+ // Also check our internal state as fallback
284
+ const internalSelected = this.selectedOptions[cacheKey] || [];
285
+ // Use whichever has more selections, or if component returns empty but internal has data, use internal
286
+ if (internalSelected.length > currentSelected.length ||
287
+ (currentSelected.length === 0 && internalSelected.length > 0)) {
288
+ currentSelected = internalSelected;
289
+ }
290
+ }
291
+ catch (e) {
292
+ // Fallback to internal state
293
+ currentSelected = this.selectedOptions[cacheKey] || [];
294
+ }
295
+ }
296
+ else {
297
+ // Fallback to internal state
298
+ currentSelected = this.selectedOptions[cacheKey] || [];
299
+ }
300
+ // Check if any options are selected at all
301
+ if (currentSelected.length === 0) {
302
+ errors.push(salla.lang.get('pages.products.no_options_selected'));
303
+ }
304
+ // Check required options
305
+ this.product.options.forEach(option => {
306
+ if (option.required) {
307
+ const hasSelection = currentSelected.some(selected => {
308
+ return selected.option_id == option.id; // Use == instead of === for type flexibility
309
+ });
310
+ if (!hasSelection) {
311
+ errors.push(salla.lang.get('pages.products.required_option_missing', {
312
+ option: option.name,
313
+ }));
314
+ }
315
+ }
316
+ });
317
+ this.validationErrors = errors;
318
+ return errors.length === 0;
319
+ }
320
+ async onSave(e) {
321
+ e.preventDefault();
322
+ const productId = this.product?.id;
323
+ if (!productId)
324
+ return;
325
+ const cacheKey = this.generateCacheKey(this.sectionId, this.productIndex, productId);
326
+ // Small delay to ensure component state is updated
327
+ await new Promise(resolve => setTimeout(resolve, 100));
328
+ // Validate options before saving
329
+ const isValid = await this.validateOptions();
330
+ if (!isValid) {
331
+ salla.notify.error(this.validationErrors.join(', '));
332
+ return;
333
+ }
334
+ this.isLoading = true;
335
+ try {
336
+ // please don't change this with this.host.querySelector it will return null
337
+ const optionsEl = document.querySelector(`salla-product-options[product-id="${productId}"]`);
338
+ let selectedOptions = await optionsEl?.getSelectedOptions();
339
+ // If component returns empty but we have internal state, use internal state
340
+ if ((!selectedOptions || selectedOptions.length === 0) &&
341
+ this.selectedOptions[cacheKey]?.length > 0) {
342
+ selectedOptions = this.selectedOptions[cacheKey];
343
+ }
344
+ if (!selectedOptions || selectedOptions.length === 0) {
345
+ this.isLoading = false;
346
+ return;
347
+ }
348
+ // Store the selected options for this product using cache key
349
+ this.selectedOptions = {
350
+ ...this.selectedOptions,
351
+ [cacheKey]: selectedOptions,
352
+ };
353
+ const form = this.host.closest('form');
354
+ if (!form) {
355
+ this.isLoading = false;
356
+ return;
357
+ }
358
+ // remove old inputs for this specific product in this specific section/index only
359
+ const productInputPattern = `bundle[${this.sectionId}][${this.productIndex}]`;
360
+ // Remove only hidden inputs and inputs with data-product-id, but preserve visible checkboxes
361
+ Array.from(form.querySelectorAll(`input[name^="${productInputPattern}"][type="hidden"]`)).forEach(el => el.remove());
362
+ // Also remove any inputs with data-product-id that match this specific pattern
363
+ Array.from(form.querySelectorAll(`[data-product-id="${productId}"][name^="${productInputPattern}"]`)).forEach(el => el.remove());
364
+ // Ensure the actual checkbox in the UI is checked to reflect the selection visually
365
+ const checkboxId = `bundle[${this.sectionId}][${this.productIndex}][id]`;
366
+ const checkbox = document.getElementById(checkboxId);
367
+ if (checkbox) {
368
+ checkbox.checked = true;
369
+ // Don't dispatch change event here to avoid double API calls
370
+ }
371
+ else {
372
+ // If checkbox doesn't exist, create a hidden input as fallback
373
+ const productSelectionInput = document.createElement('input');
374
+ productSelectionInput.type = 'hidden';
375
+ productSelectionInput.name = `bundle[${this.sectionId}][${this.productIndex}][id]`;
376
+ productSelectionInput.value = String(productId);
377
+ productSelectionInput.dataset.productId = String(productId);
378
+ form.appendChild(productSelectionInput);
379
+ }
380
+ // append new hidden inputs for options
381
+ selectedOptions.forEach((option) => {
382
+ // how to get option parent id?
383
+ const optionParentId = option.option_id;
384
+ const hidden = document.createElement('input');
385
+ hidden.type = 'hidden';
386
+ // Use productIndex for the form input name
387
+ hidden.name = this.generateFormInputName(this.sectionId, this.productIndex ?? 0, optionParentId);
388
+ hidden.value = String(option.id);
389
+ hidden.dataset.productId = String(productId);
390
+ form.appendChild(hidden);
391
+ });
392
+ // Trigger single form change event with all updates (product selection + options)
393
+ const changeEvent = new window.Event('change', { bubbles: true });
394
+ form.dispatchEvent(changeEvent);
395
+ // Emit custom event
396
+ this.optionsSaved.emit({
397
+ productId: Number(productId),
398
+ selectedOptions,
399
+ });
400
+ // Emit product selected event to check the card
401
+ if (this.sectionId) {
402
+ this.productSelected.emit({
403
+ productId: Number(productId),
404
+ sectionId: this.sectionId,
405
+ product: this.product,
406
+ fromModal: true,
407
+ });
408
+ }
409
+ // Show success message
410
+ salla.notify.success(salla.lang.get('pages.products.options_saved'));
411
+ this.hasUnsavedChanges = false;
412
+ this.validationErrors = [];
413
+ // close modal
414
+ this.modal.close();
415
+ }
416
+ catch (error) {
417
+ salla.notify.error(salla.lang.get('pages.products.options_save_error'));
418
+ }
419
+ finally {
420
+ this.isLoading = false;
421
+ }
422
+ }
423
+ // Method to get options with selected state preserved
424
+ getOptionsWithSelectedState() {
425
+ if (!this.product?.options)
426
+ return [];
427
+ const cacheKey = this.generateCacheKey(this.sectionId, this.productIndex, this.product.id);
428
+ const savedOptions = this.selectedOptions[cacheKey] || [];
429
+ return this.product.options.map(option => ({
430
+ ...option,
431
+ details: option.details.map(detail => {
432
+ const isSelected = savedOptions.some(saved => {
433
+ return saved.id === detail.id;
434
+ });
435
+ return {
436
+ ...detail,
437
+ is_selected: isSelected,
438
+ };
439
+ }),
440
+ }));
441
+ }
442
+ render() {
443
+ const productId = this.product?.id;
444
+ const optionsWithSelectedState = this.getOptionsWithSelectedState();
445
+ return (h(Host, { key: '52efc988e52036a0be8c5dfe7d9375aed2072b55' }, h("salla-modal", { key: 'e07dd856effc65a718528c6836884cd82520e94e', 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: '5365b7d796d48759a8cd0e7bb7e6cd755382afc8', slot: "loading" }, h("salla-skeleton", { key: 'deb66b5f95587584ade5581da3c891a95d3750af', height: "100%", width: "100%" })), this.product?.images && this.product?.images.length > 0 && (h("salla-slider", { key: 'e79b63e49ba9c29ef9d625ca99ffd17bbf282f79', 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
+ centeredSlides: true,
447
+ centeredSlidesBounds: true,
448
+ slidesPerView: Math.min(5, Math.max(1, this.product?.images.length)),
449
+ watchOverflow: true,
450
+ watchSlidesVisibility: true,
451
+ watchSlidesProgress: true,
452
+ direction: 'vertical',
453
+ spaceBetween: 10,
454
+ } }, h("div", { key: '3c3f3d2a1de4869a0d2d15583630d04a400097d7', slot: "items" }, this.product?.images &&
455
+ 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
+ e.target.style.display = 'none';
457
+ } }))))), this.product?.images && this.product?.images.length > 1 && (h("div", { key: '5d0f67677595c442d76f0fb3a42dacb1996e58db', slot: "thumbs" }, this.product?.images &&
458
+ 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
+ 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: '1f166bdaf78a78b99aeecc141e6f99b9fa1e50b1', slot: "footer" }, h("div", { key: 'e4ea869eaf9690ee3aba7319f976a82f8187767e', class: "s-multiple-bundle-product-options-modal-footer" }, h("salla-button", { key: '17e4f97284528019b25bd640ff3843dbbefb5dae', onClick: e => this.onSave(e), loading: this.isLoading, disabled: this.isLoading }, this.isLoading
461
+ ? salla.lang.get('common.elements.saving')
462
+ : salla.lang.get('common.elements.save')))))));
463
+ }
464
+ static get is() { return "salla-multiple-bundle-product-options-modal"; }
465
+ static get encapsulation() { return "shadow"; }
466
+ static get originalStyleUrls() {
467
+ return {
468
+ "$": ["salla-multiple-bundle-product-options-modal.scss"]
469
+ };
470
+ }
471
+ static get styleUrls() {
472
+ return {
473
+ "$": ["salla-multiple-bundle-product-options-modal.css"]
474
+ };
475
+ }
476
+ static get states() {
477
+ return {
478
+ "product": {},
479
+ "sectionId": {},
480
+ "sectionIndex": {},
481
+ "productIndex": {},
482
+ "selectedOptions": {},
483
+ "isLoading": {},
484
+ "hasUnsavedChanges": {},
485
+ "validationErrors": {}
486
+ };
487
+ }
488
+ static get events() {
489
+ return [{
490
+ "method": "optionsSaved",
491
+ "name": "optionsSaved",
492
+ "bubbles": true,
493
+ "cancelable": true,
494
+ "composed": true,
495
+ "docs": {
496
+ "tags": [],
497
+ "text": ""
498
+ },
499
+ "complexType": {
500
+ "original": "{ productId: number; selectedOptions: SelectedOption[] }",
501
+ "resolved": "{ productId: number; selectedOptions: SelectedOption[]; }",
502
+ "references": {
503
+ "SelectedOption": {
504
+ "location": "import",
505
+ "path": "../interfaces",
506
+ "id": "src/components/salla-multiple-bundle-product/interfaces.ts::SelectedOption"
507
+ }
508
+ }
509
+ }
510
+ }, {
511
+ "method": "productSelected",
512
+ "name": "productSelected",
513
+ "bubbles": true,
514
+ "cancelable": true,
515
+ "composed": true,
516
+ "docs": {
517
+ "tags": [],
518
+ "text": ""
519
+ },
520
+ "complexType": {
521
+ "original": "{\n productId: number;\n sectionId: string | number;\n product?: BundleProduct;\n fromModal?: boolean;\n }",
522
+ "resolved": "{ productId: number; sectionId: string | number; product?: BundleProduct; fromModal?: boolean; }",
523
+ "references": {
524
+ "BundleProduct": {
525
+ "location": "import",
526
+ "path": "../interfaces",
527
+ "id": "src/components/salla-multiple-bundle-product/interfaces.ts::BundleProduct"
528
+ }
529
+ }
530
+ }
531
+ }];
532
+ }
533
+ static get methods() {
534
+ return {
535
+ "open": {
536
+ "complexType": {
537
+ "signature": "() => Promise<void>",
538
+ "parameters": [],
539
+ "references": {
540
+ "Promise": {
541
+ "location": "global",
542
+ "id": "global::Promise"
543
+ }
544
+ },
545
+ "return": "Promise<void>"
546
+ },
547
+ "docs": {
548
+ "text": "",
549
+ "tags": []
550
+ }
551
+ },
552
+ "close": {
553
+ "complexType": {
554
+ "signature": "() => Promise<void>",
555
+ "parameters": [],
556
+ "references": {
557
+ "Promise": {
558
+ "location": "global",
559
+ "id": "global::Promise"
560
+ }
561
+ },
562
+ "return": "Promise<void>"
563
+ },
564
+ "docs": {
565
+ "text": "",
566
+ "tags": []
567
+ }
568
+ },
569
+ "refreshOptionsState": {
570
+ "complexType": {
571
+ "signature": "() => Promise<void>",
572
+ "parameters": [],
573
+ "references": {
574
+ "Promise": {
575
+ "location": "global",
576
+ "id": "global::Promise"
577
+ }
578
+ },
579
+ "return": "Promise<void>"
580
+ },
581
+ "docs": {
582
+ "text": "",
583
+ "tags": []
584
+ }
585
+ }
586
+ };
587
+ }
588
+ static get elementRef() { return "host"; }
589
+ static get watchers() {
590
+ return [{
591
+ "propName": "product",
592
+ "methodName": "handleProductChange"
593
+ }];
594
+ }
595
+ }