@salla.sa/twilight-components 2.14.438 → 2.14.440

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 (330) hide show
  1. package/dist/cjs/{filepond-DMRIHf1C.js → filepond-DOOLwTpX.js} +1 -1
  2. package/dist/cjs/{filepond-plugin-file-poster-CM9PlkkE.js → filepond-plugin-file-poster-D7nMzJ2p.js} +1 -1
  3. package/dist/cjs/{filepond-plugin-file-validate-size-CtgoDQtd.js → filepond-plugin-file-validate-size-DpCJ71im.js} +1 -1
  4. package/dist/cjs/{filepond-plugin-file-validate-type-DqSFCcfx.js → filepond-plugin-file-validate-type-CDZ5OaBc.js} +1 -1
  5. package/dist/cjs/{filepond-plugin-image-edit-k32QwoLh.js → filepond-plugin-image-edit-BzGZimte.js} +1 -1
  6. package/dist/cjs/{filepond-plugin-image-exif-orientation-BsOFwzDp.js → filepond-plugin-image-exif-orientation-D1fPPBi_.js} +1 -1
  7. package/dist/cjs/{filepond-plugin-image-preview-Bh5GBaFR.js → filepond-plugin-image-preview-CEhIwZKp.js} +1 -1
  8. package/dist/cjs/{functions-g_kb3rFp.js → functions-CdVaIsQM.js} +1 -1
  9. package/dist/cjs/{index-BUh2wfzU.js → index-E66k07Rj.js} +1 -1
  10. package/dist/cjs/{index-BFaAWRue.js → index-oqqfD8M2.js} +2 -2
  11. package/dist/cjs/loader.cjs.js +2 -2
  12. package/dist/cjs/salla-accordion-body_2.cjs.entry.js +1 -1
  13. package/dist/cjs/salla-accordion_6.cjs.entry.js +1 -1
  14. package/dist/cjs/salla-add-product-button_5.cjs.entry.js +1 -1
  15. package/dist/cjs/salla-advertisement.cjs.entry.js +1 -1
  16. package/dist/cjs/salla-alert_2.cjs.entry.js +1 -1
  17. package/dist/cjs/salla-app-install-alert.cjs.entry.js +1 -1
  18. package/dist/cjs/salla-apps-icons.cjs.entry.js +1 -1
  19. package/dist/cjs/salla-badge.cjs.entry.js +1 -1
  20. package/dist/cjs/salla-booking-field_7.cjs.entry.js +10 -10
  21. package/dist/cjs/salla-bullet-delivery_2.cjs.entry.js +1 -1
  22. package/dist/cjs/salla-cart-coupons.cjs.entry.js +1 -1
  23. package/dist/cjs/salla-cart-item-offers_2.cjs.entry.js +1 -1
  24. package/dist/cjs/salla-cashback-banner.cjs.entry.js +1 -1
  25. package/dist/cjs/salla-comment-form_8.cjs.entry.js +1 -1
  26. package/dist/cjs/salla-conditional-offer.cjs.entry.js +1 -1
  27. package/dist/cjs/salla-contacts.cjs.entry.js +1 -1
  28. package/dist/cjs/salla-cookies-bar.cjs.entry.js +1 -1
  29. package/dist/cjs/salla-count-down.cjs.entry.js +1 -1
  30. package/dist/cjs/salla-custom-fields.cjs.entry.js +1 -1
  31. package/dist/cjs/salla-delivery-promise.cjs.entry.js +1 -1
  32. package/dist/cjs/salla-edit-order-button.cjs.entry.js +1 -1
  33. package/dist/cjs/salla-filters-widget.cjs.entry.js +1 -1
  34. package/dist/cjs/salla-filters.cjs.entry.js +1 -1
  35. package/dist/cjs/salla-fulfillment-methods.cjs.entry.js +1 -1
  36. package/dist/cjs/salla-gifting.cjs.entry.js +1 -1
  37. package/dist/cjs/salla-hook.cjs.entry.js +1 -1
  38. package/dist/cjs/salla-infinite-scroll.cjs.entry.js +1 -1
  39. package/dist/cjs/salla-installment.cjs.entry.js +1 -1
  40. package/dist/cjs/salla-list-tile.cjs.entry.js +1 -1
  41. package/dist/cjs/salla-localization-modal.cjs.entry.js +1 -1
  42. package/dist/cjs/salla-login-modal.cjs.entry.js +1 -1
  43. package/dist/cjs/salla-loyalty-banner.cjs.entry.js +2 -2
  44. package/dist/cjs/salla-loyalty-hero_2.cjs.entry.js +2 -2
  45. package/dist/cjs/salla-loyalty-panel.cjs.entry.js +3 -3
  46. package/dist/cjs/salla-loyalty-points-banner.cjs.entry.js +1 -1
  47. package/dist/cjs/salla-loyalty-prize-item.cjs.entry.js +1 -1
  48. package/dist/cjs/salla-loyalty-program.cjs.entry.js +3 -3
  49. package/dist/cjs/salla-loyalty-reward.cjs.entry.js +2 -2
  50. package/dist/cjs/salla-loyalty.cjs.entry.js +16 -6
  51. package/dist/cjs/salla-maintenance-alert.cjs.entry.js +1 -1
  52. package/dist/cjs/salla-map.cjs.entry.js +1 -1
  53. package/dist/cjs/salla-menu.cjs.entry.js +1 -1
  54. package/dist/cjs/salla-metadata.cjs.entry.js +1 -1
  55. package/dist/cjs/salla-multiple-bundle-product-cart_2.cjs.entry.js +247 -42
  56. package/dist/cjs/salla-multiple-bundle-product-options-modal_2.cjs.entry.js +86 -25
  57. package/dist/cjs/salla-multiple-bundle-product.cjs.entry.js +1 -1
  58. package/dist/cjs/salla-next-order-coupon.cjs.entry.js +1 -1
  59. package/dist/cjs/salla-notification-item.cjs.entry.js +1 -1
  60. package/dist/cjs/salla-notifications.cjs.entry.js +1 -1
  61. package/dist/cjs/salla-offer-modal.cjs.entry.js +1 -1
  62. package/dist/cjs/salla-offer.cjs.entry.js +1 -1
  63. package/dist/cjs/salla-order-details-multiple-bundle-product.cjs.entry.js +1 -1
  64. package/dist/cjs/salla-order-details-options.cjs.entry.js +1 -1
  65. package/dist/cjs/salla-order-details.cjs.entry.js +1 -1
  66. package/dist/cjs/salla-order-edit-item.cjs.entry.js +1 -1
  67. package/dist/cjs/salla-order-edit-product-card.cjs.entry.js +1 -1
  68. package/dist/cjs/salla-order-edit.cjs.entry.js +29 -5
  69. package/dist/cjs/salla-order-summary.cjs.entry.js +1 -1
  70. package/dist/cjs/salla-order-totals-card.cjs.entry.js +1 -1
  71. package/dist/cjs/salla-orders.cjs.entry.js +1 -1
  72. package/dist/cjs/salla-payments.cjs.entry.js +1 -1
  73. package/dist/cjs/salla-placeholder.cjs.entry.js +1 -1
  74. package/dist/cjs/salla-price-range.cjs.entry.js +1 -1
  75. package/dist/cjs/salla-product-card-embed.cjs.entry.js +2 -2
  76. package/dist/cjs/salla-product-card_2.cjs.entry.js +1 -1
  77. package/dist/cjs/salla-product-size-guide.cjs.entry.js +1 -1
  78. package/dist/cjs/salla-products-list.cjs.entry.js +1 -1
  79. package/dist/cjs/salla-progress-bar.cjs.entry.js +1 -1
  80. package/dist/cjs/salla-quick-order.cjs.entry.js +1 -1
  81. package/dist/cjs/salla-rating-modal.cjs.entry.js +1 -1
  82. package/dist/cjs/salla-reward-action_4.cjs.entry.js +13 -8
  83. package/dist/cjs/salla-scopes.cjs.entry.js +1 -1
  84. package/dist/cjs/salla-search.cjs.entry.js +1 -1
  85. package/dist/cjs/salla-skeleton.cjs.entry.js +1 -1
  86. package/dist/cjs/salla-slider.cjs.entry.js +1 -1
  87. package/dist/cjs/salla-social-share.cjs.entry.js +1 -1
  88. package/dist/cjs/salla-social.cjs.entry.js +1 -1
  89. package/dist/cjs/salla-tab-content_3.cjs.entry.js +1 -1
  90. package/dist/cjs/salla-tiered-offer.cjs.entry.js +1 -1
  91. package/dist/cjs/salla-tooltip.cjs.entry.js +1 -1
  92. package/dist/cjs/salla-trust-badges.cjs.entry.js +1 -1
  93. package/dist/cjs/salla-user-menu.cjs.entry.js +1 -1
  94. package/dist/cjs/salla-user-profile.cjs.entry.js +1 -1
  95. package/dist/cjs/salla-user-settings.cjs.entry.js +1 -1
  96. package/dist/cjs/salla-verify.cjs.entry.js +1 -1
  97. package/dist/cjs/salla-wallet.cjs.entry.js +1 -1
  98. package/dist/cjs/{tracked-promise-hdme5g67.js → tracked-promise-DV0VuqZL.js} +1 -1
  99. package/dist/cjs/twilight.cjs.js +2 -2
  100. package/dist/cjs/{vanilla-picker-D37h-mXi.js → vanilla-picker-DvOQTQXG.js} +1 -1
  101. package/dist/collection/components/salla-loyalty/salla-loyalty.js +17 -7
  102. package/dist/collection/components/salla-loyalty-program/salla-reward-exchange.js +10 -5
  103. package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-details.js +278 -41
  104. package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-options-modal.js +18 -4
  105. package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-slider.js +107 -20
  106. package/dist/collection/components/salla-order-edit/salla-order-edit.js +47 -4
  107. package/dist/collection/components/salla-product-card-embed/salla-product-card-embed.css +32 -0
  108. package/dist/components/index.js +2 -2
  109. package/dist/components/salla-loyalty.js +15 -5
  110. package/dist/components/salla-multiple-bundle-product-details2.js +250 -42
  111. package/dist/components/salla-multiple-bundle-product-options-modal2.js +18 -4
  112. package/dist/components/salla-multiple-bundle-product-slider2.js +69 -20
  113. package/dist/components/salla-order-edit.js +29 -4
  114. package/dist/components/salla-product-card-embed.js +1 -1
  115. package/dist/components/salla-reward-exchange2.js +10 -5
  116. package/dist/esm/{filepond-B_eTEvbP.js → filepond-Crf00c7G.js} +1 -1
  117. package/dist/esm/{filepond-plugin-file-poster-C9WrU6X2.js → filepond-plugin-file-poster-B3uKBJe-.js} +1 -1
  118. package/dist/esm/{filepond-plugin-file-validate-size-CXza6gk6.js → filepond-plugin-file-validate-size-CWVDRdsV.js} +1 -1
  119. package/dist/esm/{filepond-plugin-file-validate-type-NwmI_I3c.js → filepond-plugin-file-validate-type-VQGNZwF9.js} +1 -1
  120. package/dist/esm/{filepond-plugin-image-edit-BkFkrboM.js → filepond-plugin-image-edit-DOhXVk8j.js} +1 -1
  121. package/dist/esm/{filepond-plugin-image-exif-orientation-q63RMohC.js → filepond-plugin-image-exif-orientation-Co8jzTVW.js} +1 -1
  122. package/dist/esm/{filepond-plugin-image-preview-DBrJFq-R.js → filepond-plugin-image-preview-gQWAQlCp.js} +1 -1
  123. package/dist/esm/{functions-BiPE31Ri.js → functions-D8zpoRMj.js} +1 -1
  124. package/dist/esm/{index-DMFHjmvU.js → index-DX6k_dv6.js} +1 -1
  125. package/dist/esm/{index-DQ335bXf.js → index-XEcnGv2r.js} +2 -2
  126. package/dist/esm/loader.js +3 -3
  127. package/dist/esm/salla-accordion-body_2.entry.js +1 -1
  128. package/dist/esm/salla-accordion_6.entry.js +1 -1
  129. package/dist/esm/salla-add-product-button_5.entry.js +1 -1
  130. package/dist/esm/salla-advertisement.entry.js +1 -1
  131. package/dist/esm/salla-alert_2.entry.js +1 -1
  132. package/dist/esm/salla-app-install-alert.entry.js +1 -1
  133. package/dist/esm/salla-apps-icons.entry.js +1 -1
  134. package/dist/esm/salla-badge.entry.js +1 -1
  135. package/dist/esm/salla-booking-field_7.entry.js +10 -10
  136. package/dist/esm/salla-bullet-delivery_2.entry.js +1 -1
  137. package/dist/esm/salla-cart-coupons.entry.js +1 -1
  138. package/dist/esm/salla-cart-item-offers_2.entry.js +1 -1
  139. package/dist/esm/salla-cashback-banner.entry.js +1 -1
  140. package/dist/esm/salla-comment-form_8.entry.js +1 -1
  141. package/dist/esm/salla-conditional-offer.entry.js +1 -1
  142. package/dist/esm/salla-contacts.entry.js +1 -1
  143. package/dist/esm/salla-cookies-bar.entry.js +1 -1
  144. package/dist/esm/salla-count-down.entry.js +1 -1
  145. package/dist/esm/salla-custom-fields.entry.js +1 -1
  146. package/dist/esm/salla-delivery-promise.entry.js +1 -1
  147. package/dist/esm/salla-edit-order-button.entry.js +1 -1
  148. package/dist/esm/salla-filters-widget.entry.js +1 -1
  149. package/dist/esm/salla-filters.entry.js +1 -1
  150. package/dist/esm/salla-fulfillment-methods.entry.js +1 -1
  151. package/dist/esm/salla-gifting.entry.js +1 -1
  152. package/dist/esm/salla-hook.entry.js +1 -1
  153. package/dist/esm/salla-infinite-scroll.entry.js +1 -1
  154. package/dist/esm/salla-installment.entry.js +1 -1
  155. package/dist/esm/salla-list-tile.entry.js +1 -1
  156. package/dist/esm/salla-localization-modal.entry.js +1 -1
  157. package/dist/esm/salla-login-modal.entry.js +1 -1
  158. package/dist/esm/salla-loyalty-banner.entry.js +2 -2
  159. package/dist/esm/salla-loyalty-hero_2.entry.js +2 -2
  160. package/dist/esm/salla-loyalty-panel.entry.js +3 -3
  161. package/dist/esm/salla-loyalty-points-banner.entry.js +1 -1
  162. package/dist/esm/salla-loyalty-prize-item.entry.js +1 -1
  163. package/dist/esm/salla-loyalty-program.entry.js +3 -3
  164. package/dist/esm/salla-loyalty-reward.entry.js +2 -2
  165. package/dist/esm/salla-loyalty.entry.js +16 -6
  166. package/dist/esm/salla-maintenance-alert.entry.js +1 -1
  167. package/dist/esm/salla-map.entry.js +1 -1
  168. package/dist/esm/salla-menu.entry.js +1 -1
  169. package/dist/esm/salla-metadata.entry.js +1 -1
  170. package/dist/esm/salla-multiple-bundle-product-cart_2.entry.js +247 -42
  171. package/dist/esm/salla-multiple-bundle-product-options-modal_2.entry.js +86 -25
  172. package/dist/esm/salla-multiple-bundle-product.entry.js +1 -1
  173. package/dist/esm/salla-next-order-coupon.entry.js +1 -1
  174. package/dist/esm/salla-notification-item.entry.js +1 -1
  175. package/dist/esm/salla-notifications.entry.js +1 -1
  176. package/dist/esm/salla-offer-modal.entry.js +1 -1
  177. package/dist/esm/salla-offer.entry.js +1 -1
  178. package/dist/esm/salla-order-details-multiple-bundle-product.entry.js +1 -1
  179. package/dist/esm/salla-order-details-options.entry.js +1 -1
  180. package/dist/esm/salla-order-details.entry.js +1 -1
  181. package/dist/esm/salla-order-edit-item.entry.js +1 -1
  182. package/dist/esm/salla-order-edit-product-card.entry.js +1 -1
  183. package/dist/esm/salla-order-edit.entry.js +29 -5
  184. package/dist/esm/salla-order-summary.entry.js +1 -1
  185. package/dist/esm/salla-order-totals-card.entry.js +1 -1
  186. package/dist/esm/salla-orders.entry.js +1 -1
  187. package/dist/esm/salla-payments.entry.js +1 -1
  188. package/dist/esm/salla-placeholder.entry.js +1 -1
  189. package/dist/esm/salla-price-range.entry.js +1 -1
  190. package/dist/esm/salla-product-card-embed.entry.js +2 -2
  191. package/dist/esm/salla-product-card_2.entry.js +1 -1
  192. package/dist/esm/salla-product-size-guide.entry.js +1 -1
  193. package/dist/esm/salla-products-list.entry.js +1 -1
  194. package/dist/esm/salla-progress-bar.entry.js +1 -1
  195. package/dist/esm/salla-quick-order.entry.js +1 -1
  196. package/dist/esm/salla-rating-modal.entry.js +1 -1
  197. package/dist/esm/salla-reward-action_4.entry.js +13 -8
  198. package/dist/esm/salla-scopes.entry.js +1 -1
  199. package/dist/esm/salla-search.entry.js +1 -1
  200. package/dist/esm/salla-skeleton.entry.js +1 -1
  201. package/dist/esm/salla-slider.entry.js +1 -1
  202. package/dist/esm/salla-social-share.entry.js +1 -1
  203. package/dist/esm/salla-social.entry.js +1 -1
  204. package/dist/esm/salla-tab-content_3.entry.js +1 -1
  205. package/dist/esm/salla-tiered-offer.entry.js +1 -1
  206. package/dist/esm/salla-tooltip.entry.js +1 -1
  207. package/dist/esm/salla-trust-badges.entry.js +1 -1
  208. package/dist/esm/salla-user-menu.entry.js +1 -1
  209. package/dist/esm/salla-user-profile.entry.js +1 -1
  210. package/dist/esm/salla-user-settings.entry.js +1 -1
  211. package/dist/esm/salla-verify.entry.js +1 -1
  212. package/dist/esm/salla-wallet.entry.js +1 -1
  213. package/dist/esm/{tracked-promise-BhtDirMQ.js → tracked-promise-DhOWivzL.js} +1 -1
  214. package/dist/esm/twilight.js +3 -3
  215. package/dist/esm/{vanilla-picker-BzZq8SzV.js → vanilla-picker-C0njJzZd.js} +1 -1
  216. package/dist/twilight/{p-d4e63cb0.entry.js → p-00b633b2.entry.js} +1 -1
  217. package/dist/twilight/{p-221134fb.entry.js → p-0238a9dd.entry.js} +1 -1
  218. package/dist/twilight/{p-6e08db14.entry.js → p-05ae76f4.entry.js} +1 -1
  219. package/dist/twilight/{p-aa36205d.entry.js → p-06f77f81.entry.js} +1 -1
  220. package/dist/twilight/{p-07be70d2.entry.js → p-07d26676.entry.js} +1 -1
  221. package/dist/twilight/{p-f1557ed0.entry.js → p-07f973b1.entry.js} +1 -1
  222. package/dist/twilight/{p-b9c8c411.entry.js → p-0c342e2d.entry.js} +1 -1
  223. package/dist/twilight/{p-369177eb.entry.js → p-11da2f39.entry.js} +1 -1
  224. package/dist/twilight/{p-6cec9d8b.entry.js → p-1d8eb252.entry.js} +1 -1
  225. package/dist/twilight/{p-5fed66db.entry.js → p-203d6ae6.entry.js} +1 -1
  226. package/dist/twilight/{p-c30d45a8.entry.js → p-2cae7b1c.entry.js} +1 -1
  227. package/dist/twilight/{p-d066ae04.entry.js → p-2dce17b0.entry.js} +1 -1
  228. package/dist/twilight/{p-5fb93465.entry.js → p-2eddcffd.entry.js} +1 -1
  229. package/dist/twilight/{p-6d38d301.entry.js → p-31b06705.entry.js} +1 -1
  230. package/dist/twilight/{p-3be9c04b.entry.js → p-33362e8b.entry.js} +1 -1
  231. package/dist/twilight/{p-3e154bc2.entry.js → p-39498902.entry.js} +1 -1
  232. package/dist/twilight/{p-e6f8fcfc.entry.js → p-3ba87443.entry.js} +1 -1
  233. package/dist/twilight/{p-daafcb01.entry.js → p-3e054be0.entry.js} +1 -1
  234. package/dist/twilight/{p-589cb52c.entry.js → p-3edb7319.entry.js} +1 -1
  235. package/dist/twilight/{p-bea852ea.entry.js → p-461cd74c.entry.js} +1 -1
  236. package/dist/twilight/{p-881a5342.entry.js → p-476c4acb.entry.js} +1 -1
  237. package/dist/twilight/{p-b4092e4a.entry.js → p-4a3b5eca.entry.js} +1 -1
  238. package/dist/twilight/p-4e52fd6c.entry.js +4 -0
  239. package/dist/twilight/{p-f8b95b7e.entry.js → p-55dfaddd.entry.js} +1 -1
  240. package/dist/twilight/{p-a0206469.entry.js → p-56bd83f4.entry.js} +1 -1
  241. package/dist/twilight/{p-eb2d7c1e.entry.js → p-57a9293b.entry.js} +1 -1
  242. package/dist/twilight/{p-4897c441.entry.js → p-5c972b65.entry.js} +1 -1
  243. package/dist/twilight/{p-33d27bc3.entry.js → p-5df17c20.entry.js} +1 -1
  244. package/dist/twilight/p-5e643edb.entry.js +4 -0
  245. package/dist/twilight/{p-2d79709b.entry.js → p-5fd650c4.entry.js} +1 -1
  246. package/dist/twilight/{p-9696f2bd.entry.js → p-60d7a5e2.entry.js} +1 -1
  247. package/dist/twilight/{p-718e1549.entry.js → p-6ab3e94b.entry.js} +1 -1
  248. package/dist/twilight/{p-ff688f7c.entry.js → p-6c63e8a6.entry.js} +1 -1
  249. package/dist/twilight/{p-2b7ee145.entry.js → p-6d35b20c.entry.js} +1 -1
  250. package/dist/twilight/{p-be37a491.entry.js → p-6fed57e8.entry.js} +1 -1
  251. package/dist/twilight/{p-ef9ca9c4.entry.js → p-6ff38910.entry.js} +1 -1
  252. package/dist/twilight/{p-d5faf3f2.entry.js → p-78be4e2c.entry.js} +1 -1
  253. package/dist/twilight/{p-8bacc84d.entry.js → p-8207fb6f.entry.js} +1 -1
  254. package/dist/twilight/{p-ebe41004.entry.js → p-854eb825.entry.js} +1 -1
  255. package/dist/twilight/{p-ed845161.entry.js → p-8a4da11a.entry.js} +1 -1
  256. package/dist/twilight/{p-d8db1e81.entry.js → p-8c34fab2.entry.js} +1 -1
  257. package/dist/twilight/{p-6202fa66.entry.js → p-924555bd.entry.js} +1 -1
  258. package/dist/twilight/p-925690e3.entry.js +4 -0
  259. package/dist/twilight/{p-297ec2ce.entry.js → p-925869b3.entry.js} +1 -1
  260. package/dist/twilight/{p-bb8c7088.entry.js → p-93e060da.entry.js} +1 -1
  261. package/dist/twilight/{p-ff876842.entry.js → p-94b31962.entry.js} +1 -1
  262. package/dist/twilight/{p-24e09615.entry.js → p-9731d50b.entry.js} +1 -1
  263. package/dist/twilight/{p-0ddfb0d5.entry.js → p-9b2ba1e6.entry.js} +1 -1
  264. package/dist/twilight/{p-7eb778b4.entry.js → p-9c2942c3.entry.js} +1 -1
  265. package/dist/twilight/{p-a346db45.entry.js → p-9c3d5fdc.entry.js} +1 -1
  266. package/dist/twilight/{p-DWu6q1tc.js → p-B2jZw8NF.js} +1 -1
  267. package/dist/twilight/{p-CTwbej6G.js → p-B5kt5KrJ.js} +1 -1
  268. package/dist/twilight/{p-DMjajnP-.js → p-CMvDceec.js} +1 -1
  269. package/dist/twilight/{p-DjXDHHNL.js → p-Cw0D47mx.js} +1 -1
  270. package/dist/twilight/{p-RIEsmIVs.js → p-DL6eUQYK.js} +1 -1
  271. package/dist/twilight/{p-BUMSWZZf.js → p-DWyUFC7G.js} +1 -1
  272. package/dist/twilight/{p-Fxr_hOjI.js → p-DXDm8GqM.js} +1 -1
  273. package/dist/twilight/{p-w0fuGkIE.js → p-Dar-Px4H.js} +1 -1
  274. package/dist/twilight/{p-DoYiSf8E.js → p-DrCHWc9_.js} +1 -1
  275. package/dist/twilight/{p-wzq5caUN.js → p-DvOajQJL.js} +1 -1
  276. package/dist/twilight/{p-DQ335bXf.js → p-XEcnGv2r.js} +1 -1
  277. package/dist/twilight/p-YUFLgZi3.js +9 -0
  278. package/dist/twilight/{p-6fa0cf74.entry.js → p-a14b7bb6.entry.js} +1 -1
  279. package/dist/twilight/{p-11eecd61.entry.js → p-a2fa4306.entry.js} +1 -1
  280. package/dist/twilight/{p-9cf93a24.entry.js → p-a49d9c6e.entry.js} +1 -1
  281. package/dist/twilight/{p-cfd727fa.entry.js → p-aaf3736b.entry.js} +1 -1
  282. package/dist/twilight/{p-d4b8eba6.entry.js → p-aeeec3d8.entry.js} +1 -1
  283. package/dist/twilight/{p-2e289f17.entry.js → p-b1f79652.entry.js} +1 -1
  284. package/dist/twilight/p-b352e237.entry.js +4 -0
  285. package/dist/twilight/{p-85716765.entry.js → p-b3859adb.entry.js} +1 -1
  286. package/dist/twilight/{p-70736834.entry.js → p-b7e4542c.entry.js} +1 -1
  287. package/dist/twilight/{p-d20aefbc.entry.js → p-bea56108.entry.js} +1 -1
  288. package/dist/twilight/{p-a0791739.entry.js → p-c0162a6e.entry.js} +1 -1
  289. package/dist/twilight/{p-b57c111f.entry.js → p-c12ff95c.entry.js} +1 -1
  290. package/dist/twilight/{p-3388bef7.entry.js → p-c3432589.entry.js} +1 -1
  291. package/dist/twilight/{p-0cff0922.entry.js → p-c5250fca.entry.js} +1 -1
  292. package/dist/twilight/{p-ae40f1ae.entry.js → p-c55b672d.entry.js} +1 -1
  293. package/dist/twilight/{p-541ff06e.entry.js → p-c612ad0b.entry.js} +1 -1
  294. package/dist/twilight/{p-07beed15.entry.js → p-c999abc3.entry.js} +1 -1
  295. package/dist/twilight/{p-d8878610.entry.js → p-cd5722c4.entry.js} +1 -1
  296. package/dist/twilight/{p-0d3c80d3.entry.js → p-cff61b58.entry.js} +1 -1
  297. package/dist/twilight/{p-c0dc55a8.entry.js → p-d0b10f8b.entry.js} +1 -1
  298. package/dist/twilight/{p-26731090.entry.js → p-d1808642.entry.js} +1 -1
  299. package/dist/twilight/{p-cbad4eaa.entry.js → p-d1bfd0bc.entry.js} +1 -1
  300. package/dist/twilight/{p-c8971552.entry.js → p-d1e67236.entry.js} +1 -1
  301. package/dist/twilight/{p-fa3ad81b.entry.js → p-d34f2a6c.entry.js} +1 -1
  302. package/dist/twilight/{p-655adc8d.entry.js → p-d473010e.entry.js} +1 -1
  303. package/dist/twilight/{p-c756f476.entry.js → p-deaebd7b.entry.js} +1 -1
  304. package/dist/twilight/{p-ca19f9fb.entry.js → p-e50b4426.entry.js} +1 -1
  305. package/dist/twilight/p-eab889dc.entry.js +4 -0
  306. package/dist/twilight/{p-037a87a1.entry.js → p-ed55bd99.entry.js} +1 -1
  307. package/dist/twilight/{p-bbcb1943.entry.js → p-ed770165.entry.js} +1 -1
  308. package/dist/twilight/{p-a17e97a0.entry.js → p-f076d705.entry.js} +1 -1
  309. package/dist/twilight/{p-4c211080.entry.js → p-f1bed530.entry.js} +1 -1
  310. package/dist/twilight/p-f34ea06b.entry.js +4 -0
  311. package/dist/twilight/{p-2f2c7468.entry.js → p-f5207897.entry.js} +1 -1
  312. package/dist/twilight/{p-0a5550c2.entry.js → p-f668e5dd.entry.js} +1 -1
  313. package/dist/twilight/{p-6e4e0af9.entry.js → p-f8d7196e.entry.js} +1 -1
  314. package/dist/twilight/twilight.esm.js +1 -1
  315. package/dist/types/components/salla-loyalty/salla-loyalty.d.ts +2 -1
  316. package/dist/types/components/salla-loyalty-program/salla-reward-exchange.d.ts +1 -0
  317. package/dist/types/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-details.d.ts +20 -0
  318. package/dist/types/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-options-modal.d.ts +1 -0
  319. package/dist/types/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-slider.d.ts +9 -0
  320. package/dist/types/components/salla-multiple-bundle-product/interfaces.d.ts +1 -0
  321. package/dist/types/components/salla-order-edit/salla-order-edit.d.ts +4 -0
  322. package/dist/types/components.d.ts +30 -1
  323. package/package.json +5 -5
  324. package/dist/twilight/p-21f83b12.entry.js +0 -4
  325. package/dist/twilight/p-23d555d3.entry.js +0 -4
  326. package/dist/twilight/p-6e4d10a8.entry.js +0 -4
  327. package/dist/twilight/p-7fbf8aef.entry.js +0 -4
  328. package/dist/twilight/p-8b0a38e7.entry.js +0 -4
  329. package/dist/twilight/p-QRBCTWM0.js +0 -9
  330. package/dist/twilight/p-a7fcca2e.entry.js +0 -4
@@ -12,22 +12,37 @@ export class SallaMultipleBundleProductDetails {
12
12
  this.productSelectedHandler = null;
13
13
  // handle selecting a product (toggle)
14
14
  this.onSelectProduct = (sectionId, product) => {
15
+ const productId = product.id;
16
+ const wasSelected = this.selectedProducts[sectionId]?.has(productId) ?? false;
17
+ const section = this.sections.find(s => s.id == sectionId);
18
+ if (wasSelected && section && this.isProductSelectionLocked(section)) {
19
+ return;
20
+ }
21
+ if (!wasSelected) {
22
+ if (!section) {
23
+ return;
24
+ }
25
+ if (this.getEffectiveMax(section) !== 1 && this.isAtSelectionLimit(section)) {
26
+ return;
27
+ }
28
+ }
15
29
  this.selectedProducts = {
16
30
  ...this.selectedProducts,
17
31
  [sectionId]: new Set(this.selectedProducts[sectionId] || []),
18
32
  };
19
- const productId = product.id;
20
- const wasSelected = this.selectedProducts[sectionId].has(productId);
21
33
  if (wasSelected) {
22
- // Product is being deselected
23
34
  this.selectedProducts[sectionId].delete(productId);
24
- // Clear form data and modal options for this product in this specific section
25
35
  this.clearProductFormData(productId, sectionId);
26
36
  this.clearProductModalOptions(productId, sectionId);
27
37
  }
28
38
  else {
29
- // Product is being selected
30
- this.selectedProducts[sectionId].add(productId);
39
+ const effectiveMax = this.getEffectiveMax(section);
40
+ if (effectiveMax === 1) {
41
+ this.syncSectionSelection(sectionId, productId);
42
+ }
43
+ else {
44
+ this.selectedProducts[sectionId].add(productId);
45
+ }
31
46
  }
32
47
  // force re-render
33
48
  this.selectedProducts = { ...this.selectedProducts };
@@ -47,31 +62,45 @@ export class SallaMultipleBundleProductDetails {
47
62
  [sectionId]: new Set(this.selectedProducts[sectionId] || []),
48
63
  };
49
64
  const productId = product.id;
50
- // Only add if not already selected
51
- if (!this.selectedProducts[sectionId].has(productId)) {
65
+ if (this.selectedProducts[sectionId].has(productId)) {
66
+ return;
67
+ }
68
+ const section = this.sections.find(s => s.id == sectionId);
69
+ if (!section) {
70
+ return;
71
+ }
72
+ const effectiveMax = this.getEffectiveMax(section);
73
+ if (effectiveMax === 1) {
74
+ this.syncSectionSelection(sectionId, productId);
75
+ }
76
+ else if (effectiveMax > 1 && this.isAtSelectionLimit(section)) {
77
+ return;
78
+ }
79
+ else {
52
80
  this.selectedProducts[sectionId].add(productId);
53
- // force re-render
54
- this.selectedProducts = { ...this.selectedProducts };
55
- // dispatch event
56
- salla.event.dispatch('on-bundle-product-selected', {
57
- id: product.id,
58
- name: product.name,
59
- options: product.options,
60
- });
61
81
  }
82
+ this.selectedProducts = { ...this.selectedProducts };
83
+ salla.event.dispatch('on-bundle-product-selected', {
84
+ id: product.id,
85
+ name: product.name,
86
+ options: product.options,
87
+ });
62
88
  };
63
89
  // open product options modal
64
90
  this.onSelectProductOptions = (product, sectionId) => {
65
- // Find the section index from the sectionId
66
- const sectionIndex = this.sections.findIndex(section => section.id == sectionId);
67
- // Find the product index within the section
68
- const section = this.sections.find(section => section.id == sectionId);
69
- const productIndex = section?.products?.findIndex(p => p.id == product.id) ?? 0;
91
+ const section = this.sections.find(s => s.id == sectionId);
92
+ if (!section || !this.canSelectProductInSection(section, product.id)) {
93
+ return;
94
+ }
95
+ const sectionIndex = this.sections.findIndex(s => s.id == sectionId);
96
+ const productIndex = section.products?.findIndex(p => p.id == product.id) ?? 0;
97
+ const isProductAlreadySelected = this.selectedProducts[sectionId]?.has(product.id) ?? false;
70
98
  salla.event.dispatch('multiple-bundle-product-modal::open', {
71
99
  product,
72
100
  sectionId,
73
101
  sectionIndex,
74
102
  productIndex,
103
+ isProductAlreadySelected,
75
104
  });
76
105
  };
77
106
  // Event handlers for bundle slider component
@@ -84,22 +113,164 @@ export class SallaMultipleBundleProductDetails {
84
113
  this.onSelectProductOptions(product, sectionId);
85
114
  };
86
115
  }
116
+ isSingleProductSection(section) {
117
+ return (section.products?.length ?? 0) === 1;
118
+ }
119
+ getObligatoryMin(section) {
120
+ const min = section.obligatory_products;
121
+ if (min == null) {
122
+ return 0;
123
+ }
124
+ const numericMin = Number(min);
125
+ return Number.isNaN(numericMin) ? 0 : numericMin;
126
+ }
127
+ isProductSelectionLocked(section) {
128
+ return this.isSingleProductSection(section) && this.getObligatoryMin(section) === 1;
129
+ }
130
+ /** Empty max → cap is the number of products in the section. */
131
+ getEffectiveMax(section) {
132
+ const productCount = section.products?.length ?? 0;
133
+ const max = section.max_obligatory_products;
134
+ if (max != null && max > 0) {
135
+ return Math.min(max, productCount);
136
+ }
137
+ return productCount;
138
+ }
139
+ getSelectedCount(sectionId) {
140
+ return this.selectedProducts[sectionId]?.size ?? 0;
141
+ }
142
+ isAtSelectionLimit(section) {
143
+ return this.getSelectedCount(section.id) >= this.getEffectiveMax(section);
144
+ }
145
+ canSelectProductInSection(section, productId) {
146
+ if (this.selectedProducts[section.id]?.has(productId)) {
147
+ return true;
148
+ }
149
+ if (this.getEffectiveMax(section) === 1) {
150
+ return true;
151
+ }
152
+ return !this.isAtSelectionLimit(section);
153
+ }
154
+ async canSelectBundleProduct(sectionId, productId) {
155
+ const section = this.sections.find(s => s.id == sectionId);
156
+ if (!section) {
157
+ return false;
158
+ }
159
+ return this.canSelectProductInSection(section, productId);
160
+ }
161
+ queryProductCheckbox(sectionId, productIndex) {
162
+ const selector = `input.s-multiple-bundle-product-checkbox[name="bundle[${sectionId}][${productIndex}][id]"]`;
163
+ const form = this.host.closest('form');
164
+ const fromForm = form?.querySelector(selector);
165
+ if (fromForm) {
166
+ return fromForm;
167
+ }
168
+ for (const slider of this.host.querySelectorAll('salla-multiple-bundle-product-slider')) {
169
+ const root = slider.shadowRoot ?? slider;
170
+ const input = root.querySelector(selector);
171
+ if (input) {
172
+ return input;
173
+ }
174
+ }
175
+ return null;
176
+ }
177
+ dispatchBubblingChange(target) {
178
+ requestAnimationFrame(() => {
179
+ target.dispatchEvent(new window.Event('change', { bubbles: true }));
180
+ });
181
+ }
182
+ /** Uncheck checkbox, remove form inputs, and reset modal state for one product slot. */
183
+ clearSectionProductSlot(sectionId, productId, productIndex) {
184
+ const checkbox = this.queryProductCheckbox(sectionId, productIndex);
185
+ if (checkbox) {
186
+ checkbox.checked = false;
187
+ }
188
+ const form = this.host.closest('form');
189
+ if (form) {
190
+ const slotPrefix = `bundle[${sectionId}][${productIndex}]`;
191
+ Array.from(form.querySelectorAll('input')).forEach((input) => {
192
+ const inSlot = input.name?.startsWith(slotPrefix) ?? false;
193
+ if (!inSlot) {
194
+ return;
195
+ }
196
+ if (input.type === 'checkbox' && input.name?.endsWith('][id]')) {
197
+ input.checked = false;
198
+ return;
199
+ }
200
+ input.remove();
201
+ });
202
+ }
203
+ this.clearProductModalOptions(productId, sectionId);
204
+ }
205
+ /** max=1: replace section selection and keep DOM/form in sync. */
206
+ syncSectionSelection(sectionId, productId) {
207
+ const section = this.sections.find(s => s.id == sectionId);
208
+ section?.products?.forEach((product, productIndex) => {
209
+ if (product.id != productId) {
210
+ this.clearSectionProductSlot(sectionId, product.id, productIndex);
211
+ }
212
+ });
213
+ this.selectedProducts[sectionId] = new Set([productId]);
214
+ const selectedIndex = section?.products?.findIndex(p => p.id == productId) ?? -1;
215
+ const checkbox = selectedIndex >= 0 ? this.queryProductCheckbox(sectionId, selectedIndex) : null;
216
+ if (checkbox) {
217
+ checkbox.checked = true;
218
+ this.dispatchBubblingChange(checkbox);
219
+ }
220
+ }
221
+ autoSelectSingleProductSections() {
222
+ if (!this.sections?.length) {
223
+ return;
224
+ }
225
+ const newSelectedProducts = { ...this.selectedProducts };
226
+ let updated = false;
227
+ const selectedEvents = [];
228
+ for (const section of this.sections) {
229
+ if (!this.isProductSelectionLocked(section)) {
230
+ continue;
231
+ }
232
+ const product = section.products?.[0];
233
+ if (!product || (!product.unlimited_quantity && (product.quantity ?? 0) <= 0)) {
234
+ continue;
235
+ }
236
+ const sectionId = section.id;
237
+ const currentSet = new Set(newSelectedProducts[sectionId] || []);
238
+ if (currentSet.has(product.id)) {
239
+ continue;
240
+ }
241
+ currentSet.add(product.id);
242
+ newSelectedProducts[sectionId] = currentSet;
243
+ updated = true;
244
+ selectedEvents.push({ product });
245
+ }
246
+ if (!updated) {
247
+ return;
248
+ }
249
+ this.selectedProducts = newSelectedProducts;
250
+ selectedEvents.forEach(({ product }) => {
251
+ salla.event.dispatch('on-bundle-product-selected', {
252
+ id: product.id,
253
+ name: product.name,
254
+ options: product.options,
255
+ });
256
+ });
257
+ }
87
258
  // Clear form data for a specific product in specific section
88
259
  clearProductFormData(productId, sectionId) {
89
- const form = this.host.closest('form');
90
- if (sectionId) {
91
- // Remove inputs for specific section/productIndex combination
92
- const productInputPattern = `bundle[${sectionId}][`;
93
- const inputsToRemove = Array.from(form.querySelectorAll('input')).filter((input) => input.getAttribute('data-product-id') === String(productId) &&
94
- input.name &&
95
- input.name.startsWith(productInputPattern));
96
- inputsToRemove.forEach(input => input.remove());
260
+ if (sectionId != null) {
261
+ const section = this.sections.find(s => s.id == sectionId);
262
+ const productIndex = section?.products?.findIndex(product => product.id == productId) ?? -1;
263
+ if (productIndex >= 0) {
264
+ this.clearSectionProductSlot(sectionId, productId, productIndex);
265
+ return;
266
+ }
97
267
  }
98
- else {
99
- // Fallback: Remove all hidden inputs related to this product (legacy behavior)
100
- const inputsToRemove = form.querySelectorAll(`[data-product-id="${productId}"]`);
101
- inputsToRemove.forEach(input => input.remove());
268
+ const form = this.host.closest('form');
269
+ if (!form) {
270
+ return;
102
271
  }
272
+ const inputsToRemove = form.querySelectorAll(`[data-product-id="${productId}"]`);
273
+ inputsToRemove.forEach(input => input.remove());
103
274
  }
104
275
  // Clear modal options state for a specific product
105
276
  clearProductModalOptions(productId, sectionId) {
@@ -123,10 +294,42 @@ export class SallaMultipleBundleProductDetails {
123
294
  productIndex,
124
295
  });
125
296
  }
126
- renderAccordionHeader(section, selectedCount) {
127
- return (h(Fragment, null, h("h2", { slot: "title" }, section?.name), section?.obligatory_products ? (h("span", { slot: "note" }, salla.lang.get('pages.products.obligatory_products', {
128
- count: section?.obligatory_products || 0,
129
- }))) : '', h("span", { slot: "progress" }, selectedCount, "/", section?.products?.length || 0)));
297
+ getProgressStatus(section) {
298
+ const selectedCount = this.getSelectedCount(section.id);
299
+ const effectiveMax = this.getEffectiveMax(section);
300
+ if (effectiveMax > 0) {
301
+ return `${selectedCount}/${effectiveMax}`;
302
+ }
303
+ return '0';
304
+ }
305
+ getSectionSelectionNote(section) {
306
+ const min = this.getObligatoryMin(section);
307
+ const max = Number(section.max_obligatory_products) || 0;
308
+ const hasMin = min > 0;
309
+ const hasMax = max > 0;
310
+ if (!hasMin && !hasMax) {
311
+ return null;
312
+ }
313
+ if (hasMin && hasMax) {
314
+ if (min === max) {
315
+ return salla.lang.getWithDefault('pages.products.bundle_select_exact', `اختر ${min} منتجات`, { count: min });
316
+ }
317
+ return salla.lang.getWithDefault('pages.products.bundle_select_range', `اختر من ${min} إلى ${max} منتجات`, { min, max });
318
+ }
319
+ if (hasMin) {
320
+ return salla.lang.getWithDefault('pages.products.bundle_select_min', `اختر على الأقل ${min} منتجات`, { min });
321
+ }
322
+ return salla.lang.getWithDefault('pages.products.bundle_select_max', `اختر حتى ${max} منتجات`, { max });
323
+ }
324
+ handleSectionsChange() {
325
+ this.autoSelectSingleProductSections();
326
+ }
327
+ componentWillLoad() {
328
+ this.autoSelectSingleProductSections();
329
+ }
330
+ renderAccordionHeader(section) {
331
+ const selectionNote = this.getSectionSelectionNote(section);
332
+ return (h(Fragment, null, h("h2", { slot: "title" }, section?.name), selectionNote ? h("span", { slot: "note" }, selectionNote) : null, h("span", { slot: "progress" }, this.getProgressStatus(section))));
130
333
  }
131
334
  componentDidLoad() {
132
335
  // Listen for product selected event from modal
@@ -157,10 +360,9 @@ export class SallaMultipleBundleProductDetails {
157
360
  }
158
361
  }
159
362
  render() {
160
- return (h(Host, { key: '27a3d6baa97585e983db19522ab2981ecc9e50f1', class: "s-multiple-bundle-product-wrapper" }, h("div", { key: 'c96cf52dfaee161a03a6bf97de267d9942a47a49', class: "s-multiple-bundle-product-wrapper-sections" }, this.sections.map((section, index) => {
161
- const selectedCount = this.selectedProducts[section.id]?.size || 0;
162
- return (h("salla-accordion", { key: section.id, collapsed: index === 0 ? false : true }, h("salla-accordion-head", null, this.renderAccordionHeader(section, selectedCount)), h("salla-accordion-body", null, h("salla-multiple-bundle-product-slider", { section: section, sectionIndex: index, selectedProducts: this.selectedProducts, onProductSelected: this.handleBundleSliderProductSelected, onProductOptionsSelected: this.handleBundleSliderProductOptionsSelected }))));
163
- })), h("salla-multiple-bundle-product-options-modal", { key: '6627ee4f67bcd775b16e470dd4735848e6087fd4' })));
363
+ return (h(Host, { key: '74b123c432e77263cf0ddcf20ab742885c54d5f4', class: "s-multiple-bundle-product-wrapper" }, h("div", { key: '24bef0958a2a7d29bb4485eac08c7e6b8614a00d', class: "s-multiple-bundle-product-wrapper-sections" }, this.sections.map((section, index) => {
364
+ return (h("salla-accordion", { key: section.id, collapsed: index === 0 ? false : true }, h("salla-accordion-head", null, this.renderAccordionHeader(section)), h("salla-accordion-body", null, h("salla-multiple-bundle-product-slider", { section: section, sectionIndex: index, selectedProducts: this.selectedProducts, selectionLimit: this.getEffectiveMax(section), isSelectionLocked: this.isProductSelectionLocked(section), onProductSelected: this.handleBundleSliderProductSelected, onProductOptionsSelected: this.handleBundleSliderProductOptionsSelected }))));
365
+ })), h("salla-multiple-bundle-product-options-modal", { key: '556b4e51a4b79dfc00371a07296556fb74111524' })));
164
366
  }
165
367
  static get is() { return "salla-multiple-bundle-product-details"; }
166
368
  static get originalStyleUrls() {
@@ -207,5 +409,40 @@ export class SallaMultipleBundleProductDetails {
207
409
  "selectedProducts": {}
208
410
  };
209
411
  }
412
+ static get methods() {
413
+ return {
414
+ "canSelectBundleProduct": {
415
+ "complexType": {
416
+ "signature": "(sectionId: string | number, productId: string | number) => Promise<boolean>",
417
+ "parameters": [{
418
+ "name": "sectionId",
419
+ "type": "string | number",
420
+ "docs": ""
421
+ }, {
422
+ "name": "productId",
423
+ "type": "string | number",
424
+ "docs": ""
425
+ }],
426
+ "references": {
427
+ "Promise": {
428
+ "location": "global",
429
+ "id": "global::Promise"
430
+ }
431
+ },
432
+ "return": "Promise<boolean>"
433
+ },
434
+ "docs": {
435
+ "text": "",
436
+ "tags": []
437
+ }
438
+ }
439
+ };
440
+ }
210
441
  static get elementRef() { return "host"; }
442
+ static get watchers() {
443
+ return [{
444
+ "propName": "sections",
445
+ "methodName": "handleSectionsChange"
446
+ }];
447
+ }
211
448
  }
@@ -13,6 +13,7 @@ export class SallaMultipleBundleProductOptionsModal {
13
13
  this.isLoading = false;
14
14
  this.hasUnsavedChanges = false;
15
15
  this.validationErrors = [];
16
+ this.isProductAlreadySelected = false;
16
17
  }
17
18
  /**
18
19
  * Generate a unique cache key for selected options using section ID, product index, and product ID
@@ -74,6 +75,7 @@ export class SallaMultipleBundleProductOptionsModal {
74
75
  this.sectionId = data.sectionId || null;
75
76
  this.sectionIndex = data.sectionIndex || 0;
76
77
  this.productIndex = data.productIndex || 0;
78
+ this.isProductAlreadySelected = !!data.isProductAlreadySelected;
77
79
  this.open();
78
80
  };
79
81
  salla.event.on('multiple-bundle-product-modal::open', this.modalOpenListener);
@@ -104,6 +106,10 @@ export class SallaMultipleBundleProductOptionsModal {
104
106
  // Extract section info from the checkbox name: bundle[sectionId][productIndex][id]
105
107
  const nameMatch = target.name.match(/^bundle\[([^\]]+)\]\[([^\]]+)\]\[id\]$/);
106
108
  if (nameMatch && !target.checked) {
109
+ if (target.getAttribute('data-selection-locked') === 'true') {
110
+ target.checked = true;
111
+ return;
112
+ }
107
113
  const [, sectionId, productIndex] = nameMatch;
108
114
  const productId = target.value;
109
115
  const form = this.host.closest('form');
@@ -342,6 +348,14 @@ export class SallaMultipleBundleProductOptionsModal {
342
348
  salla.notify.error(this.validationErrors.join(', '));
343
349
  return;
344
350
  }
351
+ if (!this.isProductAlreadySelected && this.sectionId != null) {
352
+ const details = this.host.closest('salla-multiple-bundle-product-details');
353
+ const canSelect = await details?.canSelectBundleProduct(this.sectionId, productId);
354
+ if (!canSelect) {
355
+ salla.notify.error(salla.lang.getWithDefault('pages.products.bundle_selection_limit_reached', 'لا يمكنك اختيار المزيد من المنتجات في هذا القسم'));
356
+ return;
357
+ }
358
+ }
345
359
  this.isLoading = true;
346
360
  try {
347
361
  // please don't change this with this.host.querySelector it will return null
@@ -458,7 +472,7 @@ export class SallaMultipleBundleProductOptionsModal {
458
472
  const cacheKey = this.generateCacheKey(this.sectionId, this.productIndex, productId);
459
473
  const resetToken = this.optionsResetTokens[cacheKey] || 0;
460
474
  const isDisabled = this.isLoading || optionsWithSelectedState.some(opt => opt.details.some(d => d.is_selected && d.is_out === true));
461
- return (h(Host, { key: 'd9dc4018798fe902048f3e3e37fcb2edf84713b0' }, h("salla-modal", { key: 'af3cc56a9c2c969dc0cbb2b4caba14fd270a11bb', 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: '10fcc08be35bfd4231f9cf48501614ae49a985a3', slot: "loading" }, h("salla-skeleton", { key: '1aee9616e4f05188067708506352b0d97d504696', height: "100%", width: "100%" })), this.product?.images && this.product?.images.length > 0 && (h("salla-slider", { key: 'a7d7a459d383c353b5ef716365ba0a0ac5d3a0b7', 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: {
475
+ return (h(Host, { key: '6c1d1d3911867e30240676f3e2b7353e9ecf76c3' }, h("salla-modal", { key: 'b02110d80cd422d64962d78812ae0b0637c56237', 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: '20a52bbc732c6edfffde86577e99bbe300a1a4c8', slot: "loading" }, h("salla-skeleton", { key: '3a69fc75939d8b8f8639983d0f2f8dd8bf961152', height: "100%", width: "100%" })), this.product?.images && this.product?.images.length > 0 && (h("salla-slider", { key: '185639c54f79188093df98ac1cece1958879f71d', 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: {
462
476
  centeredSlides: true,
463
477
  centeredSlidesBounds: true,
464
478
  slidesPerView: Math.min(5, Math.max(1, this.product?.images.length)),
@@ -466,13 +480,13 @@ export class SallaMultipleBundleProductOptionsModal {
466
480
  watchSlidesProgress: true,
467
481
  direction: 'vertical',
468
482
  spaceBetween: 10,
469
- } }, h("div", { key: '11970032bdc37e5d20d6737e3109fcec9b4de4cb', slot: "items" }, this.product?.images &&
483
+ } }, h("div", { key: '3b6a88fe3862870d674dadc31967df6cc8fac365', slot: "items" }, this.product?.images &&
470
484
  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 => {
471
485
  e.target.style.display = 'none';
472
- } }))))), this.product?.images && this.product?.images.length > 1 && (h("div", { key: 'c7d0fd432d8449e4742f0686ddecb7e87bebf159', slot: "thumbs" }, this.product?.images &&
486
+ } }))))), this.product?.images && this.product?.images.length > 1 && (h("div", { key: '6fce48b5b035cc61866aaf6c339866fa2314be87', slot: "thumbs" }, this.product?.images &&
473
487
  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 => {
474
488
  e.target.style.display = 'none';
475
- } })))))))), h("salla-product-options", { options: JSON.stringify(optionsWithSelectedState), key: `${cacheKey}-reset-${resetToken}`, "product-id": productId, "unique-key": `${cacheKey}-reset-${resetToken}` }), h("div", { key: 'c9b5f53696d9f8800e3a6be31ec78b51f0cb9bb1', slot: "footer" }, h("div", { key: 'e972370006feae6c17797f54c415ef0d2aaa3f57', class: "s-multiple-bundle-product-options-modal-footer" }, h("salla-button", { key: '7a3787936eec6c0c8a69a64799af5595f51909f9', onClick: e => this.onSave(e), loading: this.isLoading, disabled: isDisabled }, this.isLoading
489
+ } })))))))), h("salla-product-options", { options: JSON.stringify(optionsWithSelectedState), key: `${cacheKey}-reset-${resetToken}`, "product-id": productId, "unique-key": `${cacheKey}-reset-${resetToken}` }), h("div", { key: '3d555ea40fe5d9f3685fc6dafa4b6fad16732091', slot: "footer" }, h("div", { key: '1b4c6834899efbd09f3ea1db251999f50ec655b2', class: "s-multiple-bundle-product-options-modal-footer" }, h("salla-button", { key: '0818a75a444cca510c7f0cfea2ec53414c12db53', onClick: e => this.onSave(e), loading: this.isLoading, disabled: isDisabled }, this.isLoading
476
490
  ? salla.lang.get('common.elements.saving')
477
491
  : salla.lang.get('common.elements.save')))))));
478
492
  }
@@ -8,39 +8,71 @@ export class SallaMultipleBundleProductSlider {
8
8
  constructor() {
9
9
  /** A dictionary tracking which product IDs are currently selected per section. */
10
10
  this.selectedProducts = {};
11
+ /** When true, the selected product cannot be deselected (single-product section with min = 1). */
12
+ this.isSelectionLocked = false;
13
+ /** Maximum selectable products for this section (empty max → all products in section). */
14
+ this.selectionLimit = 0;
11
15
  this.savedOptionsByInstance = {};
12
16
  this.handleProductClick = (product, productIndex) => {
13
- // Find the checkbox input for this product
14
- const checkboxId = this.generateEventName(this.section.id, productIndex);
15
- const checkbox = document.getElementById(checkboxId);
16
- if (!checkbox)
17
- return;
18
- if (checkbox) {
19
- const willBeChecked = !checkbox.checked;
20
- if (!willBeChecked) {
21
- this.dispatchClearOptionsEvent(product, productIndex);
22
- this.clearSavedOptionsState(this.section.id, productIndex);
17
+ const isChecked = this.selectedProducts[this.section.id]?.has(product.id) || false;
18
+ const checkbox = this.getCheckbox(this.section.id, productIndex);
19
+ if (isChecked && this.isSelectionLocked) {
20
+ if (checkbox) {
21
+ checkbox.checked = true;
23
22
  }
24
- // Toggle the checkbox state
25
- checkbox.checked = willBeChecked;
26
- // Dispatch a change event to trigger form validation/submission
27
- requestAnimationFrame(() => {
28
- const changeEvent = new window.Event('change', { bubbles: true });
29
- checkbox.dispatchEvent(changeEvent);
23
+ return;
24
+ }
25
+ if (!isChecked && this.isMaxSelectionReached() && this.selectionLimit !== 1) {
26
+ return;
27
+ }
28
+ // max = 1: parent replaces selection and syncs all checkboxes in the section
29
+ if (this.selectionLimit === 1 && !isChecked) {
30
+ this.productSelected.emit({
31
+ product,
32
+ sectionId: this.section.id,
30
33
  });
34
+ return;
35
+ }
36
+ if (!checkbox)
37
+ return;
38
+ const willBeChecked = !checkbox.checked;
39
+ if (!willBeChecked) {
40
+ this.dispatchClearOptionsEvent(product, productIndex);
41
+ this.clearSavedOptionsState(this.section.id, productIndex);
31
42
  }
43
+ checkbox.checked = willBeChecked;
44
+ requestAnimationFrame(() => {
45
+ const changeEvent = new window.Event('change', { bubbles: true });
46
+ checkbox.dispatchEvent(changeEvent);
47
+ });
32
48
  this.productSelected.emit({
33
49
  product,
34
50
  sectionId: this.section.id,
35
51
  });
36
52
  };
37
53
  this.handleOptionsClick = (product) => {
54
+ const isChecked = this.selectedProducts[this.section.id]?.has(product.id) || false;
55
+ if (!isChecked && this.isMaxSelectionReached() && this.selectionLimit !== 1) {
56
+ return;
57
+ }
38
58
  this.productOptionsSelected.emit({
39
59
  product,
40
60
  sectionId: this.section.id,
41
61
  });
42
62
  };
43
63
  }
64
+ getSelectedCount() {
65
+ return this.selectedProducts[this.section?.id]?.size ?? 0;
66
+ }
67
+ isMaxSelectionReached() {
68
+ return this.selectionLimit > 1 && this.getSelectedCount() >= this.selectionLimit;
69
+ }
70
+ isProductSelectionDisabled(product, isChecked) {
71
+ if (product.quantity === 0) {
72
+ return true;
73
+ }
74
+ return !isChecked && this.isMaxSelectionReached();
75
+ }
44
76
  getProductInstanceKey(sectionId, productIndex) {
45
77
  return `${sectionId}::${productIndex}`;
46
78
  }
@@ -86,9 +118,26 @@ export class SallaMultipleBundleProductSlider {
86
118
  generateEventName(sectionId, productIndex) {
87
119
  return `bundle[${sectionId}][${productIndex}][id]`;
88
120
  }
121
+ getCheckbox(sectionId, productIndex) {
122
+ const name = this.generateEventName(sectionId, productIndex);
123
+ return this.host.querySelector(`input.s-multiple-bundle-product-checkbox[name="${name}"]`);
124
+ }
125
+ preventLockedDeselect(event, isChecked) {
126
+ if (!this.isSelectionLocked || !isChecked) {
127
+ return;
128
+ }
129
+ event.preventDefault();
130
+ event.stopPropagation();
131
+ const checkbox = event.target;
132
+ if (checkbox?.type === 'checkbox') {
133
+ checkbox.checked = true;
134
+ }
135
+ }
89
136
  render() {
90
- return (h(Host, { key: 'ecdac4638007d9435ec8b06f32114a0dada03b86' }, h("salla-slider", { key: 'c245e7dcfd157908063fd5ec13c6d49f8862dd18', type: "carousel", controlsOuter: false, showControls: false, id: `accordion-multiple-bundle-product-${this.section.id}`, pagination: true, class: "s-multiple-bundle-product-wrapper-slider", sliderConfig: { spaceBetween: 0 } }, h("div", { key: '17bdd6def2ff6f1d2ad22fa8b5299fc0000b1e82', slot: "items" }, this?.section?.products?.map((product, productIndex) => {
137
+ return (h(Host, { key: 'd52eb26454606df2526fa4c086110a54f7466644' }, h("salla-slider", { key: '1aa1fce5943c3721a8e4f762171c864d9097bb28', type: "carousel", controlsOuter: false, showControls: false, id: `accordion-multiple-bundle-product-${this.section.id}`, pagination: true, class: "s-multiple-bundle-product-wrapper-slider", sliderConfig: { spaceBetween: 0 } }, h("div", { key: '9342381bc43389bae48b906a1ab23a4f3cf8d00a', slot: "items" }, this?.section?.products?.map((product, productIndex) => {
91
138
  const isChecked = this.selectedProducts[this.section.id]?.has(product.id) || false;
139
+ const isLocked = isChecked && this.isSelectionLocked;
140
+ const isDisabled = this.isProductSelectionDisabled(product, isChecked);
92
141
  const hasSavedOptions = this.savedOptionsByInstance[this.getProductInstanceKey(this.section.id, productIndex)];
93
142
  const optionsButtonLabel = hasSavedOptions
94
143
  ? salla.lang.getWithDefault('pages.products.edit_selected_options', 'تعديل الخيارات')
@@ -96,9 +145,7 @@ export class SallaMultipleBundleProductSlider {
96
145
  let optionsArrowIcon = salla.config.get('theme.is_rtl', true)
97
146
  ? KeyBoardArrowLeftIcon
98
147
  : KeyBoardArrowRightIcon;
99
- return (h("div", { class: `s-multiple-bundle-product-slide-one-third ${product.quantity == 0
100
- ? 's-multiple-bundle-product-slide-one-third-disabled'
101
- : ''}`, 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" }, h("a", { href: product?.url || '#', target: "_blank", rel: "noopener noreferrer" }, 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.regular_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 })))))));
148
+ return (h("div", { class: `s-multiple-bundle-product-slide-one-third${isDisabled ? ' s-multiple-bundle-product-slide-one-third-disabled' : ''}`, 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, "data-selection-locked": isLocked ? 'true' : undefined, name: this.generateEventName(this.section.id, productIndex), value: product.id, onClick: event => this.preventLockedDeselect(event, isChecked), onChange: event => this.preventLockedDeselect(event, isChecked) }), 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" }, h("a", { href: product?.url || '#', target: "_blank", rel: "noopener noreferrer" }, 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.regular_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 })))))));
102
149
  })))));
103
150
  }
104
151
  static get is() { return "salla-multiple-bundle-product-slider"; }
@@ -180,6 +227,46 @@ export class SallaMultipleBundleProductSlider {
180
227
  "getter": false,
181
228
  "setter": false,
182
229
  "defaultValue": "{}"
230
+ },
231
+ "isSelectionLocked": {
232
+ "type": "boolean",
233
+ "attribute": "is-selection-locked",
234
+ "mutable": false,
235
+ "complexType": {
236
+ "original": "boolean",
237
+ "resolved": "boolean",
238
+ "references": {}
239
+ },
240
+ "required": false,
241
+ "optional": false,
242
+ "docs": {
243
+ "tags": [],
244
+ "text": "When true, the selected product cannot be deselected (single-product section with min = 1)."
245
+ },
246
+ "getter": false,
247
+ "setter": false,
248
+ "reflect": false,
249
+ "defaultValue": "false"
250
+ },
251
+ "selectionLimit": {
252
+ "type": "number",
253
+ "attribute": "selection-limit",
254
+ "mutable": false,
255
+ "complexType": {
256
+ "original": "number",
257
+ "resolved": "number",
258
+ "references": {}
259
+ },
260
+ "required": false,
261
+ "optional": false,
262
+ "docs": {
263
+ "tags": [],
264
+ "text": "Maximum selectable products for this section (empty max \u2192 all products in section)."
265
+ },
266
+ "getter": false,
267
+ "setter": false,
268
+ "reflect": false,
269
+ "defaultValue": "0"
183
270
  }
184
271
  };
185
272
  }