@salla.sa/twilight-components 2.14.439 → 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 (320) hide show
  1. package/dist/cjs/{filepond-DdDLuiM5.js → filepond-DOOLwTpX.js} +1 -1
  2. package/dist/cjs/{filepond-plugin-file-poster-yMQqced-.js → filepond-plugin-file-poster-D7nMzJ2p.js} +1 -1
  3. package/dist/cjs/{filepond-plugin-file-validate-size-ySnuQivZ.js → filepond-plugin-file-validate-size-DpCJ71im.js} +1 -1
  4. package/dist/cjs/{filepond-plugin-file-validate-type-DZR1JS8f.js → filepond-plugin-file-validate-type-CDZ5OaBc.js} +1 -1
  5. package/dist/cjs/{filepond-plugin-image-edit-D1I8S80L.js → filepond-plugin-image-edit-BzGZimte.js} +1 -1
  6. package/dist/cjs/{filepond-plugin-image-exif-orientation-C9XMlwy1.js → filepond-plugin-image-exif-orientation-D1fPPBi_.js} +1 -1
  7. package/dist/cjs/{filepond-plugin-image-preview-Bb0GALoo.js → filepond-plugin-image-preview-CEhIwZKp.js} +1 -1
  8. package/dist/cjs/{functions-wi2J1iyx.js → functions-CdVaIsQM.js} +1 -1
  9. package/dist/cjs/{index-gyLHvjDh.js → index-E66k07Rj.js} +1 -1
  10. package/dist/cjs/{index-CzYs-dhm.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 +1 -1
  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 +1 -1
  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 +3 -3
  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-DT3W4yYx.js → tracked-promise-DV0VuqZL.js} +1 -1
  99. package/dist/cjs/twilight.cjs.js +2 -2
  100. package/dist/cjs/{vanilla-picker-BdKuUhUF.js → vanilla-picker-DvOQTQXG.js} +1 -1
  101. package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-details.js +278 -41
  102. package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-options-modal.js +18 -4
  103. package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-slider.js +107 -20
  104. package/dist/collection/components/salla-product-card-embed/salla-product-card-embed.css +32 -0
  105. package/dist/components/index.js +2 -2
  106. package/dist/components/salla-multiple-bundle-product-details2.js +250 -42
  107. package/dist/components/salla-multiple-bundle-product-options-modal2.js +18 -4
  108. package/dist/components/salla-multiple-bundle-product-slider2.js +69 -20
  109. package/dist/components/salla-product-card-embed.js +1 -1
  110. package/dist/esm/{filepond-CuxNx4T_.js → filepond-Crf00c7G.js} +1 -1
  111. package/dist/esm/{filepond-plugin-file-poster-B0bm9HVP.js → filepond-plugin-file-poster-B3uKBJe-.js} +1 -1
  112. package/dist/esm/{filepond-plugin-file-validate-size-Ndd8bi5G.js → filepond-plugin-file-validate-size-CWVDRdsV.js} +1 -1
  113. package/dist/esm/{filepond-plugin-file-validate-type-DrPPjEtZ.js → filepond-plugin-file-validate-type-VQGNZwF9.js} +1 -1
  114. package/dist/esm/{filepond-plugin-image-edit-C96YLlHm.js → filepond-plugin-image-edit-DOhXVk8j.js} +1 -1
  115. package/dist/esm/{filepond-plugin-image-exif-orientation-BufhQyn4.js → filepond-plugin-image-exif-orientation-Co8jzTVW.js} +1 -1
  116. package/dist/esm/{filepond-plugin-image-preview-xyGt-4PS.js → filepond-plugin-image-preview-gQWAQlCp.js} +1 -1
  117. package/dist/esm/{functions-BXvEy71U.js → functions-D8zpoRMj.js} +1 -1
  118. package/dist/esm/{index-BVmIkaqr.js → index-DX6k_dv6.js} +1 -1
  119. package/dist/esm/{index-D0jpoyIT.js → index-XEcnGv2r.js} +2 -2
  120. package/dist/esm/loader.js +3 -3
  121. package/dist/esm/salla-accordion-body_2.entry.js +1 -1
  122. package/dist/esm/salla-accordion_6.entry.js +1 -1
  123. package/dist/esm/salla-add-product-button_5.entry.js +1 -1
  124. package/dist/esm/salla-advertisement.entry.js +1 -1
  125. package/dist/esm/salla-alert_2.entry.js +1 -1
  126. package/dist/esm/salla-app-install-alert.entry.js +1 -1
  127. package/dist/esm/salla-apps-icons.entry.js +1 -1
  128. package/dist/esm/salla-badge.entry.js +1 -1
  129. package/dist/esm/salla-booking-field_7.entry.js +10 -10
  130. package/dist/esm/salla-bullet-delivery_2.entry.js +1 -1
  131. package/dist/esm/salla-cart-coupons.entry.js +1 -1
  132. package/dist/esm/salla-cart-item-offers_2.entry.js +1 -1
  133. package/dist/esm/salla-cashback-banner.entry.js +1 -1
  134. package/dist/esm/salla-comment-form_8.entry.js +1 -1
  135. package/dist/esm/salla-conditional-offer.entry.js +1 -1
  136. package/dist/esm/salla-contacts.entry.js +1 -1
  137. package/dist/esm/salla-cookies-bar.entry.js +1 -1
  138. package/dist/esm/salla-count-down.entry.js +1 -1
  139. package/dist/esm/salla-custom-fields.entry.js +1 -1
  140. package/dist/esm/salla-delivery-promise.entry.js +1 -1
  141. package/dist/esm/salla-edit-order-button.entry.js +1 -1
  142. package/dist/esm/salla-filters-widget.entry.js +1 -1
  143. package/dist/esm/salla-filters.entry.js +1 -1
  144. package/dist/esm/salla-fulfillment-methods.entry.js +1 -1
  145. package/dist/esm/salla-gifting.entry.js +1 -1
  146. package/dist/esm/salla-hook.entry.js +1 -1
  147. package/dist/esm/salla-infinite-scroll.entry.js +1 -1
  148. package/dist/esm/salla-installment.entry.js +1 -1
  149. package/dist/esm/salla-list-tile.entry.js +1 -1
  150. package/dist/esm/salla-localization-modal.entry.js +1 -1
  151. package/dist/esm/salla-login-modal.entry.js +1 -1
  152. package/dist/esm/salla-loyalty-banner.entry.js +2 -2
  153. package/dist/esm/salla-loyalty-hero_2.entry.js +2 -2
  154. package/dist/esm/salla-loyalty-panel.entry.js +3 -3
  155. package/dist/esm/salla-loyalty-points-banner.entry.js +1 -1
  156. package/dist/esm/salla-loyalty-prize-item.entry.js +1 -1
  157. package/dist/esm/salla-loyalty-program.entry.js +3 -3
  158. package/dist/esm/salla-loyalty-reward.entry.js +2 -2
  159. package/dist/esm/salla-loyalty.entry.js +1 -1
  160. package/dist/esm/salla-maintenance-alert.entry.js +1 -1
  161. package/dist/esm/salla-map.entry.js +1 -1
  162. package/dist/esm/salla-menu.entry.js +1 -1
  163. package/dist/esm/salla-metadata.entry.js +1 -1
  164. package/dist/esm/salla-multiple-bundle-product-cart_2.entry.js +247 -42
  165. package/dist/esm/salla-multiple-bundle-product-options-modal_2.entry.js +86 -25
  166. package/dist/esm/salla-multiple-bundle-product.entry.js +1 -1
  167. package/dist/esm/salla-next-order-coupon.entry.js +1 -1
  168. package/dist/esm/salla-notification-item.entry.js +1 -1
  169. package/dist/esm/salla-notifications.entry.js +1 -1
  170. package/dist/esm/salla-offer-modal.entry.js +1 -1
  171. package/dist/esm/salla-offer.entry.js +1 -1
  172. package/dist/esm/salla-order-details-multiple-bundle-product.entry.js +1 -1
  173. package/dist/esm/salla-order-details-options.entry.js +1 -1
  174. package/dist/esm/salla-order-details.entry.js +1 -1
  175. package/dist/esm/salla-order-edit-item.entry.js +1 -1
  176. package/dist/esm/salla-order-edit-product-card.entry.js +1 -1
  177. package/dist/esm/salla-order-edit.entry.js +1 -1
  178. package/dist/esm/salla-order-summary.entry.js +1 -1
  179. package/dist/esm/salla-order-totals-card.entry.js +1 -1
  180. package/dist/esm/salla-orders.entry.js +1 -1
  181. package/dist/esm/salla-payments.entry.js +1 -1
  182. package/dist/esm/salla-placeholder.entry.js +1 -1
  183. package/dist/esm/salla-price-range.entry.js +1 -1
  184. package/dist/esm/salla-product-card-embed.entry.js +2 -2
  185. package/dist/esm/salla-product-card_2.entry.js +1 -1
  186. package/dist/esm/salla-product-size-guide.entry.js +1 -1
  187. package/dist/esm/salla-products-list.entry.js +1 -1
  188. package/dist/esm/salla-progress-bar.entry.js +1 -1
  189. package/dist/esm/salla-quick-order.entry.js +1 -1
  190. package/dist/esm/salla-rating-modal.entry.js +1 -1
  191. package/dist/esm/salla-reward-action_4.entry.js +3 -3
  192. package/dist/esm/salla-scopes.entry.js +1 -1
  193. package/dist/esm/salla-search.entry.js +1 -1
  194. package/dist/esm/salla-skeleton.entry.js +1 -1
  195. package/dist/esm/salla-slider.entry.js +1 -1
  196. package/dist/esm/salla-social-share.entry.js +1 -1
  197. package/dist/esm/salla-social.entry.js +1 -1
  198. package/dist/esm/salla-tab-content_3.entry.js +1 -1
  199. package/dist/esm/salla-tiered-offer.entry.js +1 -1
  200. package/dist/esm/salla-tooltip.entry.js +1 -1
  201. package/dist/esm/salla-trust-badges.entry.js +1 -1
  202. package/dist/esm/salla-user-menu.entry.js +1 -1
  203. package/dist/esm/salla-user-profile.entry.js +1 -1
  204. package/dist/esm/salla-user-settings.entry.js +1 -1
  205. package/dist/esm/salla-verify.entry.js +1 -1
  206. package/dist/esm/salla-wallet.entry.js +1 -1
  207. package/dist/esm/{tracked-promise-2BTc0cKI.js → tracked-promise-DhOWivzL.js} +1 -1
  208. package/dist/esm/twilight.js +3 -3
  209. package/dist/esm/{vanilla-picker-DN-pQ4Fw.js → vanilla-picker-C0njJzZd.js} +1 -1
  210. package/dist/twilight/{p-b44d2016.entry.js → p-00b633b2.entry.js} +1 -1
  211. package/dist/twilight/{p-9dc45b4d.entry.js → p-0238a9dd.entry.js} +1 -1
  212. package/dist/twilight/{p-0831e5fc.entry.js → p-05ae76f4.entry.js} +1 -1
  213. package/dist/twilight/{p-5eec5519.entry.js → p-06f77f81.entry.js} +1 -1
  214. package/dist/twilight/{p-5f7466cf.entry.js → p-07d26676.entry.js} +1 -1
  215. package/dist/twilight/{p-81985743.entry.js → p-07f973b1.entry.js} +1 -1
  216. package/dist/twilight/{p-7bdb6aca.entry.js → p-0c342e2d.entry.js} +1 -1
  217. package/dist/twilight/{p-1567d3b0.entry.js → p-11da2f39.entry.js} +1 -1
  218. package/dist/twilight/{p-9c6752e6.entry.js → p-1d8eb252.entry.js} +1 -1
  219. package/dist/twilight/{p-4b6e6fb8.entry.js → p-203d6ae6.entry.js} +1 -1
  220. package/dist/twilight/{p-19ab0abc.entry.js → p-2cae7b1c.entry.js} +1 -1
  221. package/dist/twilight/{p-04e8106c.entry.js → p-2dce17b0.entry.js} +1 -1
  222. package/dist/twilight/{p-bfe0be2b.entry.js → p-2eddcffd.entry.js} +1 -1
  223. package/dist/twilight/{p-4a9379a1.entry.js → p-31b06705.entry.js} +1 -1
  224. package/dist/twilight/{p-2ab53408.entry.js → p-33362e8b.entry.js} +1 -1
  225. package/dist/twilight/{p-0597375e.entry.js → p-39498902.entry.js} +1 -1
  226. package/dist/twilight/{p-79197700.entry.js → p-3ba87443.entry.js} +1 -1
  227. package/dist/twilight/{p-d9569632.entry.js → p-3e054be0.entry.js} +1 -1
  228. package/dist/twilight/{p-33a52238.entry.js → p-3edb7319.entry.js} +1 -1
  229. package/dist/twilight/{p-adc138bc.entry.js → p-461cd74c.entry.js} +1 -1
  230. package/dist/twilight/{p-6073673e.entry.js → p-476c4acb.entry.js} +1 -1
  231. package/dist/twilight/{p-078450b0.entry.js → p-4a3b5eca.entry.js} +1 -1
  232. package/dist/twilight/p-4e52fd6c.entry.js +4 -0
  233. package/dist/twilight/{p-77f85461.entry.js → p-55dfaddd.entry.js} +1 -1
  234. package/dist/twilight/{p-378a7e72.entry.js → p-56bd83f4.entry.js} +1 -1
  235. package/dist/twilight/{p-228413fa.entry.js → p-57a9293b.entry.js} +1 -1
  236. package/dist/twilight/{p-1ba82c7d.entry.js → p-5c972b65.entry.js} +1 -1
  237. package/dist/twilight/{p-0c174f16.entry.js → p-5df17c20.entry.js} +1 -1
  238. package/dist/twilight/{p-cd47fec2.entry.js → p-5e643edb.entry.js} +1 -1
  239. package/dist/twilight/{p-f81452e9.entry.js → p-5fd650c4.entry.js} +1 -1
  240. package/dist/twilight/{p-5b106fd4.entry.js → p-60d7a5e2.entry.js} +1 -1
  241. package/dist/twilight/{p-2dabb075.entry.js → p-6ab3e94b.entry.js} +1 -1
  242. package/dist/twilight/{p-baed03c3.entry.js → p-6c63e8a6.entry.js} +1 -1
  243. package/dist/twilight/{p-2a511b8a.entry.js → p-6d35b20c.entry.js} +1 -1
  244. package/dist/twilight/{p-90afbf42.entry.js → p-6fed57e8.entry.js} +1 -1
  245. package/dist/twilight/{p-637168d2.entry.js → p-6ff38910.entry.js} +1 -1
  246. package/dist/twilight/{p-fa049325.entry.js → p-78be4e2c.entry.js} +1 -1
  247. package/dist/twilight/{p-e2ad8bc7.entry.js → p-8207fb6f.entry.js} +1 -1
  248. package/dist/twilight/{p-eb53ef20.entry.js → p-854eb825.entry.js} +1 -1
  249. package/dist/twilight/{p-fadab0ac.entry.js → p-8a4da11a.entry.js} +1 -1
  250. package/dist/twilight/{p-e58b7d20.entry.js → p-8c34fab2.entry.js} +1 -1
  251. package/dist/twilight/{p-b0f25824.entry.js → p-924555bd.entry.js} +1 -1
  252. package/dist/twilight/p-925690e3.entry.js +4 -0
  253. package/dist/twilight/{p-b7e861b2.entry.js → p-925869b3.entry.js} +1 -1
  254. package/dist/twilight/{p-45708652.entry.js → p-93e060da.entry.js} +1 -1
  255. package/dist/twilight/{p-0bbf0061.entry.js → p-94b31962.entry.js} +1 -1
  256. package/dist/twilight/{p-b73471d3.entry.js → p-9731d50b.entry.js} +1 -1
  257. package/dist/twilight/{p-5131149c.entry.js → p-9b2ba1e6.entry.js} +1 -1
  258. package/dist/twilight/{p-68bcb0ba.entry.js → p-9c2942c3.entry.js} +1 -1
  259. package/dist/twilight/{p-d18400bb.entry.js → p-9c3d5fdc.entry.js} +1 -1
  260. package/dist/twilight/{p-xuGEmDhH.js → p-B2jZw8NF.js} +1 -1
  261. package/dist/twilight/{p-DwV68ec-.js → p-B5kt5KrJ.js} +1 -1
  262. package/dist/twilight/{p-DIsyGRAw.js → p-CMvDceec.js} +1 -1
  263. package/dist/twilight/{p-NBF3VaTJ.js → p-Cw0D47mx.js} +1 -1
  264. package/dist/twilight/{p-B3k6Ab4H.js → p-DL6eUQYK.js} +1 -1
  265. package/dist/twilight/{p-OK5pMKD1.js → p-DWyUFC7G.js} +1 -1
  266. package/dist/twilight/{p-D-wessdE.js → p-DXDm8GqM.js} +1 -1
  267. package/dist/twilight/p-Dar-Px4H.js +4 -0
  268. package/dist/twilight/{p-DvcNoEfM.js → p-DrCHWc9_.js} +1 -1
  269. package/dist/twilight/{p-KmhadCpx.js → p-DvOajQJL.js} +1 -1
  270. package/dist/twilight/{p-D0jpoyIT.js → p-XEcnGv2r.js} +1 -1
  271. package/dist/twilight/p-YUFLgZi3.js +9 -0
  272. package/dist/twilight/{p-0adb148a.entry.js → p-a14b7bb6.entry.js} +1 -1
  273. package/dist/twilight/{p-c207c587.entry.js → p-a2fa4306.entry.js} +1 -1
  274. package/dist/twilight/{p-fc3e6684.entry.js → p-a49d9c6e.entry.js} +1 -1
  275. package/dist/twilight/{p-3e5dbd96.entry.js → p-aaf3736b.entry.js} +1 -1
  276. package/dist/twilight/{p-c1823790.entry.js → p-aeeec3d8.entry.js} +1 -1
  277. package/dist/twilight/{p-12a6d03b.entry.js → p-b1f79652.entry.js} +1 -1
  278. package/dist/twilight/p-b352e237.entry.js +4 -0
  279. package/dist/twilight/{p-5bd8ffe5.entry.js → p-b3859adb.entry.js} +1 -1
  280. package/dist/twilight/{p-afdddba9.entry.js → p-b7e4542c.entry.js} +1 -1
  281. package/dist/twilight/{p-567ba930.entry.js → p-bea56108.entry.js} +1 -1
  282. package/dist/twilight/{p-d60ed03c.entry.js → p-c0162a6e.entry.js} +1 -1
  283. package/dist/twilight/{p-03718a72.entry.js → p-c12ff95c.entry.js} +1 -1
  284. package/dist/twilight/{p-3918f93c.entry.js → p-c3432589.entry.js} +1 -1
  285. package/dist/twilight/{p-f42fa303.entry.js → p-c5250fca.entry.js} +1 -1
  286. package/dist/twilight/{p-62c791c6.entry.js → p-c55b672d.entry.js} +1 -1
  287. package/dist/twilight/{p-083e5039.entry.js → p-c612ad0b.entry.js} +1 -1
  288. package/dist/twilight/{p-3f52dc98.entry.js → p-c999abc3.entry.js} +1 -1
  289. package/dist/twilight/{p-eec8bdb1.entry.js → p-cd5722c4.entry.js} +1 -1
  290. package/dist/twilight/{p-a0471050.entry.js → p-cff61b58.entry.js} +1 -1
  291. package/dist/twilight/{p-ef5d5f2a.entry.js → p-d0b10f8b.entry.js} +1 -1
  292. package/dist/twilight/{p-3c5b9e45.entry.js → p-d1808642.entry.js} +1 -1
  293. package/dist/twilight/{p-2404e668.entry.js → p-d1bfd0bc.entry.js} +1 -1
  294. package/dist/twilight/{p-e2ebc898.entry.js → p-d1e67236.entry.js} +1 -1
  295. package/dist/twilight/{p-0fd165b9.entry.js → p-d34f2a6c.entry.js} +1 -1
  296. package/dist/twilight/{p-fd7f2211.entry.js → p-d473010e.entry.js} +1 -1
  297. package/dist/twilight/{p-ea80046d.entry.js → p-deaebd7b.entry.js} +1 -1
  298. package/dist/twilight/{p-ebc0b840.entry.js → p-e50b4426.entry.js} +1 -1
  299. package/dist/twilight/{p-eb352a06.entry.js → p-eab889dc.entry.js} +1 -1
  300. package/dist/twilight/{p-e59b3e07.entry.js → p-ed55bd99.entry.js} +1 -1
  301. package/dist/twilight/{p-631191d2.entry.js → p-ed770165.entry.js} +1 -1
  302. package/dist/twilight/{p-c05648b2.entry.js → p-f076d705.entry.js} +1 -1
  303. package/dist/twilight/{p-b05ce2ee.entry.js → p-f1bed530.entry.js} +1 -1
  304. package/dist/twilight/p-f34ea06b.entry.js +4 -0
  305. package/dist/twilight/{p-133aea32.entry.js → p-f5207897.entry.js} +1 -1
  306. package/dist/twilight/{p-d44c5dcc.entry.js → p-f668e5dd.entry.js} +1 -1
  307. package/dist/twilight/{p-ced32f4a.entry.js → p-f8d7196e.entry.js} +1 -1
  308. package/dist/twilight/twilight.esm.js +1 -1
  309. package/dist/types/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-details.d.ts +20 -0
  310. package/dist/types/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-options-modal.d.ts +1 -0
  311. package/dist/types/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-slider.d.ts +9 -0
  312. package/dist/types/components/salla-multiple-bundle-product/interfaces.d.ts +1 -0
  313. package/dist/types/components.d.ts +21 -0
  314. package/package.json +5 -5
  315. package/dist/twilight/p-1c53d114.entry.js +0 -4
  316. package/dist/twilight/p-4d21d259.entry.js +0 -4
  317. package/dist/twilight/p-COQaiMGv.js +0 -4
  318. package/dist/twilight/p-Cq8arVRH.js +0 -9
  319. package/dist/twilight/p-b33c50dc.entry.js +0 -4
  320. package/dist/twilight/p-e4bb0633.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
  }