@salla.sa/twilight-components 2.14.470 → 2.14.472

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 (494) hide show
  1. package/dist/cjs/{filepond-jdX95qxM.js → filepond-Cy1e6Ro5.js} +1 -1
  2. package/dist/cjs/{filepond-plugin-file-poster-DC9ozntr.js → filepond-plugin-file-poster-CLtWPKuV.js} +1 -1
  3. package/dist/cjs/{filepond-plugin-file-validate-size-DxUUyj2Z.js → filepond-plugin-file-validate-size-VaxUnQB7.js} +1 -1
  4. package/dist/cjs/{filepond-plugin-file-validate-type-DB4YCfw-.js → filepond-plugin-file-validate-type-qjNEM_4Q.js} +1 -1
  5. package/dist/cjs/{filepond-plugin-image-edit-QlnXOcNf.js → filepond-plugin-image-edit-DZdFIpzD.js} +1 -1
  6. package/dist/cjs/{filepond-plugin-image-exif-orientation-D6HJ47N2.js → filepond-plugin-image-exif-orientation-CMDdMoTf.js} +1 -1
  7. package/dist/cjs/{filepond-plugin-image-preview-DCaj9jNI.js → filepond-plugin-image-preview-CckneKBe.js} +1 -1
  8. package/dist/cjs/{functions-C_kzehHT.js → functions-DDLs9J1M.js} +1 -1
  9. package/dist/cjs/{index-CmPl0fIy.js → index-BLZPuy15.js} +10 -14
  10. package/dist/cjs/{index-SIy6bIWx.js → index-MGCYfYcr.js} +1 -1
  11. package/dist/cjs/loader.cjs.js +2 -2
  12. package/dist/cjs/salla-accordion-body_2.cjs.entry.js +4 -4
  13. package/dist/cjs/salla-accordion_6.cjs.entry.js +24 -8
  14. package/dist/cjs/salla-add-product-button_5.cjs.entry.js +422 -49
  15. package/dist/cjs/salla-advertisement.cjs.entry.js +1 -1
  16. package/dist/cjs/salla-alert_2.cjs.entry.js +4 -4
  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 +2 -2
  20. package/dist/cjs/salla-booking-field_7.cjs.entry.js +18 -18
  21. package/dist/cjs/salla-bullet-delivery_2.cjs.entry.js +5 -5
  22. package/dist/cjs/salla-cart-coupons.cjs.entry.js +2 -2
  23. package/dist/cjs/salla-cart-item-offers_2.cjs.entry.js +2 -2
  24. package/dist/cjs/salla-cashback-banner.cjs.entry.js +1 -1
  25. package/dist/cjs/salla-comment-form_8.cjs.entry.js +5 -5
  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 +2 -2
  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 +3 -3
  34. package/dist/cjs/salla-filters.cjs.entry.js +2 -2
  35. package/dist/cjs/salla-fulfillment-methods.cjs.entry.js +1 -1
  36. package/dist/cjs/salla-gifting.cjs.entry.js +3 -3
  37. package/dist/cjs/salla-hook.cjs.entry.js +2 -2
  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 +2 -2
  41. package/dist/cjs/salla-localization-modal.cjs.entry.js +2 -2
  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 +9 -9
  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-points-history.cjs.entry.js +2 -2
  48. package/dist/cjs/salla-loyalty-prize-item.cjs.entry.js +2 -2
  49. package/dist/cjs/salla-loyalty-program.cjs.entry.js +3 -3
  50. package/dist/cjs/salla-loyalty-reward.cjs.entry.js +4 -4
  51. package/dist/cjs/salla-loyalty.cjs.entry.js +1 -1
  52. package/dist/cjs/salla-maintenance-alert.cjs.entry.js +2 -2
  53. package/dist/cjs/{salla-map.cjs.entry.js → salla-map_2.cjs.entry.js} +70 -4
  54. package/dist/cjs/salla-menu.cjs.entry.js +1 -1
  55. package/dist/cjs/salla-metadata.cjs.entry.js +1 -1
  56. package/dist/cjs/salla-multiple-bundle-product-cart_2.cjs.entry.js +4 -4
  57. package/dist/cjs/salla-multiple-bundle-product-options-modal_2.cjs.entry.js +6 -6
  58. package/dist/cjs/salla-multiple-bundle-product.cjs.entry.js +2 -2
  59. package/dist/cjs/salla-next-order-coupon.cjs.entry.js +1 -1
  60. package/dist/cjs/salla-notification-item.cjs.entry.js +2 -2
  61. package/dist/cjs/salla-notifications.cjs.entry.js +1 -1
  62. package/dist/cjs/salla-offer-modal.cjs.entry.js +2 -2
  63. package/dist/cjs/salla-offer.cjs.entry.js +1 -1
  64. package/dist/cjs/salla-order-branch.cjs.entry.js +1 -1
  65. package/dist/cjs/salla-order-details-multiple-bundle-product.cjs.entry.js +1 -1
  66. package/dist/cjs/salla-order-details-options.cjs.entry.js +1 -1
  67. package/dist/cjs/salla-order-details.cjs.entry.js +2 -2
  68. package/dist/cjs/salla-order-edit-item.cjs.entry.js +1 -1
  69. package/dist/cjs/salla-order-edit-product-card.cjs.entry.js +2 -2
  70. package/dist/cjs/salla-order-edit.cjs.entry.js +1 -1
  71. package/dist/cjs/{salla-product-card_2.cjs.entry.js → salla-order-options-modal_3.cjs.entry.js} +209 -6
  72. package/dist/cjs/salla-order-summary.cjs.entry.js +2 -2
  73. package/dist/cjs/salla-order-totals-card.cjs.entry.js +1 -1
  74. package/dist/cjs/salla-orders.cjs.entry.js +1 -1
  75. package/dist/cjs/salla-payments.cjs.entry.js +3 -3
  76. package/dist/cjs/salla-placeholder.cjs.entry.js +2 -2
  77. package/dist/cjs/salla-price-range.cjs.entry.js +3 -3
  78. package/dist/cjs/salla-product-card-embed.cjs.entry.js +2 -2
  79. package/dist/cjs/salla-product-size-guide.cjs.entry.js +3 -3
  80. package/dist/cjs/salla-products-list.cjs.entry.js +1 -1
  81. package/dist/cjs/salla-quick-order.cjs.entry.js +1 -1
  82. package/dist/cjs/salla-rating-modal.cjs.entry.js +1 -1
  83. package/dist/cjs/salla-reward-action_4.cjs.entry.js +10 -10
  84. package/dist/cjs/salla-scopes.cjs.entry.js +2 -2
  85. package/dist/cjs/salla-search.cjs.entry.js +6 -6
  86. package/dist/cjs/salla-skeleton.cjs.entry.js +2 -2
  87. package/dist/cjs/salla-slider.cjs.entry.js +1 -1
  88. package/dist/cjs/salla-social-share.cjs.entry.js +2 -2
  89. package/dist/cjs/salla-social.cjs.entry.js +2 -2
  90. package/dist/cjs/salla-tab-content_3.cjs.entry.js +4 -4
  91. package/dist/cjs/salla-tiered-offer.cjs.entry.js +1 -1
  92. package/dist/cjs/salla-tooltip.cjs.entry.js +2 -2
  93. package/dist/cjs/salla-trust-badges.cjs.entry.js +1 -1
  94. package/dist/cjs/salla-user-menu.cjs.entry.js +1 -1
  95. package/dist/cjs/salla-user-profile.cjs.entry.js +1 -1
  96. package/dist/cjs/salla-user-settings.cjs.entry.js +2 -2
  97. package/dist/cjs/salla-verify.cjs.entry.js +1 -1
  98. package/dist/cjs/salla-wallet.cjs.entry.js +1 -1
  99. package/dist/cjs/salla-wishlist-actions.cjs.entry.js +2 -2
  100. package/dist/cjs/{tracked-promise-D-gQXgPZ.js → tracked-promise-B-bFT1y-.js} +1 -1
  101. package/dist/cjs/twilight.cjs.js +2 -2
  102. package/dist/cjs/{vanilla-picker-CZ_8m6i_.js → vanilla-picker-CP29RTHf.js} +1 -1
  103. package/dist/collection/collection-manifest.json +1 -0
  104. package/dist/collection/components/salla-accordion/salla-accordion-body.js +1 -1
  105. package/dist/collection/components/salla-accordion/salla-accordion-head.js +2 -2
  106. package/dist/collection/components/salla-accordion/salla-accordion.js +1 -1
  107. package/dist/collection/components/salla-add-product-button/salla-add-product-button.js +10 -0
  108. package/dist/collection/components/salla-alert/salla-alert.js +1 -1
  109. package/dist/collection/components/salla-badge/salla-badge.js +1 -1
  110. package/dist/collection/components/salla-booking-field/salla-booking-field.js +1 -1
  111. package/dist/collection/components/salla-bottom-alert/salla-bottom-alert.js +2 -2
  112. package/dist/collection/components/salla-breadcrumb/salla-breadcrumb.js +21 -5
  113. package/dist/collection/components/salla-cart-coupons/salla-cart-coupons.js +1 -1
  114. package/dist/collection/components/salla-cart-summary/salla-cart-summary.js +1 -1
  115. package/dist/collection/components/salla-color-picker/salla-color-picker.js +1 -1
  116. package/dist/collection/components/salla-comment-form/salla-comment-form.js +1 -1
  117. package/dist/collection/components/salla-conditional-fields/salla-conditional-fields.js +1 -1
  118. package/dist/collection/components/salla-count-down/salla-count-down.js +1 -1
  119. package/dist/collection/components/salla-datetime-picker/salla-datetime-picker.js +1 -1
  120. package/dist/collection/components/salla-file-upload/salla-file-upload.js +2 -2
  121. package/dist/collection/components/salla-filters/salla-filters.js +1 -1
  122. package/dist/collection/components/salla-filters-widget/salla-filters-widget.js +2 -2
  123. package/dist/collection/components/salla-gifting/salla-gifting.js +2 -2
  124. package/dist/collection/components/salla-hook/salla-hook.js +1 -1
  125. package/dist/collection/components/salla-list-tile/salla-list-tile.js +1 -1
  126. package/dist/collection/components/salla-loading/salla-loading.js +1 -1
  127. package/dist/collection/components/salla-localization-modal/salla-localization-modal.js +1 -1
  128. package/dist/collection/components/salla-loyalty/salla-loyalty-prize-item.js +1 -1
  129. package/dist/collection/components/salla-loyalty-points-history/salla-loyalty-points-history.js +1 -1
  130. package/dist/collection/components/salla-loyalty-program/salla-loyalty-hero.js +3 -3
  131. package/dist/collection/components/salla-loyalty-program/salla-loyalty-point.js +4 -4
  132. package/dist/collection/components/salla-loyalty-program/salla-loyalty-reward.js +2 -2
  133. package/dist/collection/components/salla-loyalty-program/salla-reward-card.js +1 -1
  134. package/dist/collection/components/salla-loyalty-program/salla-reward-details.js +3 -3
  135. package/dist/collection/components/salla-loyalty-program/salla-reward-exchange.js +3 -3
  136. package/dist/collection/components/salla-maintenance-alert/salla-maintenance-alert.js +1 -1
  137. package/dist/collection/components/salla-map/salla-map.js +3 -3
  138. package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-cart.js +1 -1
  139. package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-details.js +2 -2
  140. package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-options-modal.js +4 -4
  141. package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-slider.js +1 -1
  142. package/dist/collection/components/salla-multiple-bundle-product/salla-multiple-bundle-product.js +1 -1
  143. package/dist/collection/components/salla-notifications/salla-notification-item.js +1 -1
  144. package/dist/collection/components/salla-offer-modal/salla-offer-modal.js +1 -1
  145. package/dist/collection/components/salla-order-details/salla-order-details.js +1 -1
  146. package/dist/collection/components/salla-order-edit/salla-order-edit-product-card.js +1 -1
  147. package/dist/collection/components/salla-order-options-modal/apple-pay-order-options.js +84 -0
  148. package/dist/collection/components/salla-order-options-modal/order-options-gate.js +136 -0
  149. package/dist/collection/components/salla-order-options-modal/salla-order-options-modal.css +35 -0
  150. package/dist/collection/components/salla-order-options-modal/salla-order-options-modal.js +282 -0
  151. package/dist/collection/components/salla-order-summary/salla-order-summary.js +1 -1
  152. package/dist/collection/components/salla-payments/salla-payments.js +2 -2
  153. package/dist/collection/components/salla-placeholder/salla-placeholder.js +1 -1
  154. package/dist/collection/components/salla-price-range/salla-price-range.js +2 -2
  155. package/dist/collection/components/salla-product-availability/salla-product-availability.js +1 -1
  156. package/dist/collection/components/salla-product-card/salla-product-card.js +5 -5
  157. package/dist/collection/components/salla-product-card-embed/salla-product-card-embed.js +1 -1
  158. package/dist/collection/components/salla-product-options/availability-utils.js +54 -0
  159. package/dist/collection/components/salla-product-options/salla-product-options.js +105 -31
  160. package/dist/collection/components/salla-product-size-guide/salla-product-size-guide.js +2 -2
  161. package/dist/collection/components/salla-quantity-input/salla-quantity-input.js +1 -1
  162. package/dist/collection/components/salla-quick-buy/salla-quick-buy.js +70 -16
  163. package/dist/collection/components/salla-review-card/salla-review-card.js +1 -1
  164. package/dist/collection/components/salla-reviews/salla-reviews.js +1 -1
  165. package/dist/collection/components/salla-reviews-page/salla-reviews-page.js +1 -1
  166. package/dist/collection/components/salla-scopes/salla-scopes.js +1 -1
  167. package/dist/collection/components/salla-search/salla-search.js +5 -5
  168. package/dist/collection/components/salla-searchable-dropdown/salla-searchable-dropdown.js +4 -4
  169. package/dist/collection/components/salla-skeleton/salla-skeleton.js +1 -1
  170. package/dist/collection/components/salla-social/salla-social.js +1 -1
  171. package/dist/collection/components/salla-social-share/salla-social-share.js +1 -1
  172. package/dist/collection/components/salla-tabs/salla-tab-content.js +1 -1
  173. package/dist/collection/components/salla-tabs/salla-tab-header.js +1 -1
  174. package/dist/collection/components/salla-tabs/salla-tabs.js +1 -1
  175. package/dist/collection/components/salla-tel-input/salla-tel-input.js +1 -1
  176. package/dist/collection/components/salla-tooltip/salla-tooltip.js +1 -1
  177. package/dist/collection/components/salla-user-settings/salla-user-settings.js +1 -1
  178. package/dist/collection/components/salla-wishlist-actions/salla-wishlist-actions.js +1 -1
  179. package/dist/components/index.js +2 -2
  180. package/dist/components/index2.js +2540 -1699
  181. package/dist/components/index3.js +1699 -2540
  182. package/dist/components/location.js +2 -2
  183. package/dist/components/salla-accordion-body2.js +1 -1
  184. package/dist/components/salla-accordion-head2.js +2 -2
  185. package/dist/components/salla-accordion2.js +1 -1
  186. package/dist/components/salla-add-product-button2.js +205 -8
  187. package/dist/components/salla-alert.js +1 -1
  188. package/dist/components/salla-badge2.js +1 -1
  189. package/dist/components/salla-booking-field2.js +1 -1
  190. package/dist/components/salla-bottom-alert.js +2 -2
  191. package/dist/components/salla-breadcrumb.js +21 -5
  192. package/dist/components/salla-bullet-delivery.js +3 -3
  193. package/dist/components/salla-cart-coupons.js +1 -1
  194. package/dist/components/salla-cart-summary.js +1 -1
  195. package/dist/components/salla-color-picker2.js +1 -1
  196. package/dist/components/salla-comment-form2.js +1 -1
  197. package/dist/components/salla-conditional-fields2.js +1 -1
  198. package/dist/components/salla-count-down2.js +1 -1
  199. package/dist/components/salla-datetime-picker2.js +2 -2
  200. package/dist/components/salla-file-upload2.js +2 -2
  201. package/dist/components/salla-filters-widget2.js +2 -2
  202. package/dist/components/salla-filters.js +1 -1
  203. package/dist/components/salla-gifting.js +2 -2
  204. package/dist/components/salla-hook.js +1 -1
  205. package/dist/components/salla-list-tile2.js +1 -1
  206. package/dist/components/salla-loading2.js +1 -1
  207. package/dist/components/salla-localization-modal.js +1 -1
  208. package/dist/components/salla-loyalty-hero2.js +3 -3
  209. package/dist/components/salla-loyalty-panel.js +66 -18
  210. package/dist/components/salla-loyalty-point2.js +6 -6
  211. package/dist/components/salla-loyalty-points-history.js +1 -1
  212. package/dist/components/salla-loyalty-prize-item.js +1 -1
  213. package/dist/components/salla-loyalty-program.js +68 -20
  214. package/dist/components/salla-loyalty-reward.js +2 -2
  215. package/dist/components/salla-maintenance-alert.js +1 -1
  216. package/dist/components/salla-map2.js +4 -4
  217. package/dist/components/salla-multiple-bundle-product-cart2.js +1 -1
  218. package/dist/components/salla-multiple-bundle-product-details2.js +2 -2
  219. package/dist/components/salla-multiple-bundle-product-options-modal2.js +4 -4
  220. package/dist/components/salla-multiple-bundle-product-slider2.js +1 -1
  221. package/dist/components/salla-multiple-bundle-product.js +1 -1
  222. package/dist/components/salla-notification-item2.js +1 -1
  223. package/dist/components/salla-offer-modal.js +65 -17
  224. package/dist/components/salla-order-details.js +1 -1
  225. package/dist/components/salla-order-edit-product-card.js +1 -1
  226. package/dist/components/salla-order-options-modal.d.ts +11 -0
  227. package/dist/components/salla-order-options-modal.js +9 -0
  228. package/dist/components/salla-order-options-modal2.js +303 -0
  229. package/dist/components/salla-order-summary.js +1 -1
  230. package/dist/components/salla-payments.js +2 -2
  231. package/dist/components/salla-placeholder2.js +1 -1
  232. package/dist/components/salla-price-range2.js +2 -2
  233. package/dist/components/salla-product-availability2.js +1 -1
  234. package/dist/components/salla-product-card-embed.js +1 -1
  235. package/dist/components/salla-product-card2.js +65 -17
  236. package/dist/components/salla-product-options2.js +120 -30
  237. package/dist/components/salla-product-size-guide.js +2 -2
  238. package/dist/components/salla-products-slider2.js +62 -14
  239. package/dist/components/salla-quantity-input2.js +1 -1
  240. package/dist/components/salla-quick-buy2.js +233 -18
  241. package/dist/components/salla-review-card2.js +1 -1
  242. package/dist/components/salla-reviews-page.js +1 -1
  243. package/dist/components/salla-reviews.js +1 -1
  244. package/dist/components/salla-reward-card2.js +1 -1
  245. package/dist/components/salla-reward-details2.js +67 -19
  246. package/dist/components/salla-reward-exchange2.js +3 -3
  247. package/dist/components/salla-scopes.js +1 -1
  248. package/dist/components/salla-search.js +5 -5
  249. package/dist/components/salla-searchable-dropdown2.js +4 -4
  250. package/dist/components/salla-skeleton2.js +1 -1
  251. package/dist/components/salla-social-share2.js +1 -1
  252. package/dist/components/salla-social.js +1 -1
  253. package/dist/components/salla-tab-content2.js +1 -1
  254. package/dist/components/salla-tab-header2.js +1 -1
  255. package/dist/components/salla-tabs2.js +1 -1
  256. package/dist/components/salla-tel-input2.js +2 -2
  257. package/dist/components/salla-tooltip2.js +1 -1
  258. package/dist/components/salla-user-settings.js +1 -1
  259. package/dist/components/salla-wishlist-actions.js +1 -1
  260. package/dist/esm/{filepond-DLJR7kqO.js → filepond-BOdFx-k4.js} +1 -1
  261. package/dist/esm/{filepond-plugin-file-poster-BPPxfj_a.js → filepond-plugin-file-poster-B0plGjbP.js} +1 -1
  262. package/dist/esm/{filepond-plugin-file-validate-size-CCqZAz2o.js → filepond-plugin-file-validate-size-BFnLP4vL.js} +1 -1
  263. package/dist/esm/{filepond-plugin-file-validate-type-YEjyqpU3.js → filepond-plugin-file-validate-type-CKf0Z8YX.js} +1 -1
  264. package/dist/esm/{filepond-plugin-image-edit-tiyoM7iJ.js → filepond-plugin-image-edit-lPLGnaWD.js} +1 -1
  265. package/dist/esm/{filepond-plugin-image-exif-orientation-CESSG4q3.js → filepond-plugin-image-exif-orientation-ad7mrSt5.js} +1 -1
  266. package/dist/esm/{filepond-plugin-image-preview-CTrGLHaX.js → filepond-plugin-image-preview-D5dtrQjv.js} +1 -1
  267. package/dist/esm/{functions-iGPmc3ui.js → functions-nnPBSJY6.js} +1 -1
  268. package/dist/esm/{index-pj-XyI3U.js → index-BtIvUNme.js} +1 -1
  269. package/dist/esm/{index-Dckjjczv.js → index-CjnbnAFU.js} +10 -14
  270. package/dist/esm/loader.js +3 -3
  271. package/dist/esm/salla-accordion-body_2.entry.js +4 -4
  272. package/dist/esm/salla-accordion_6.entry.js +24 -8
  273. package/dist/esm/salla-add-product-button_5.entry.js +422 -49
  274. package/dist/esm/salla-advertisement.entry.js +1 -1
  275. package/dist/esm/salla-alert_2.entry.js +4 -4
  276. package/dist/esm/salla-app-install-alert.entry.js +1 -1
  277. package/dist/esm/salla-apps-icons.entry.js +1 -1
  278. package/dist/esm/salla-badge.entry.js +2 -2
  279. package/dist/esm/salla-booking-field_7.entry.js +18 -18
  280. package/dist/esm/salla-bullet-delivery_2.entry.js +5 -5
  281. package/dist/esm/salla-cart-coupons.entry.js +2 -2
  282. package/dist/esm/salla-cart-item-offers_2.entry.js +2 -2
  283. package/dist/esm/salla-cashback-banner.entry.js +1 -1
  284. package/dist/esm/salla-comment-form_8.entry.js +5 -5
  285. package/dist/esm/salla-conditional-offer.entry.js +1 -1
  286. package/dist/esm/salla-contacts.entry.js +1 -1
  287. package/dist/esm/salla-cookies-bar.entry.js +1 -1
  288. package/dist/esm/salla-count-down.entry.js +2 -2
  289. package/dist/esm/salla-custom-fields.entry.js +1 -1
  290. package/dist/esm/salla-delivery-promise.entry.js +1 -1
  291. package/dist/esm/salla-edit-order-button.entry.js +1 -1
  292. package/dist/esm/salla-filters-widget.entry.js +3 -3
  293. package/dist/esm/salla-filters.entry.js +2 -2
  294. package/dist/esm/salla-fulfillment-methods.entry.js +1 -1
  295. package/dist/esm/salla-gifting.entry.js +3 -3
  296. package/dist/esm/salla-hook.entry.js +2 -2
  297. package/dist/esm/salla-infinite-scroll.entry.js +1 -1
  298. package/dist/esm/salla-installment.entry.js +1 -1
  299. package/dist/esm/salla-list-tile.entry.js +2 -2
  300. package/dist/esm/salla-localization-modal.entry.js +2 -2
  301. package/dist/esm/salla-login-modal.entry.js +1 -1
  302. package/dist/esm/salla-loyalty-banner.entry.js +2 -2
  303. package/dist/esm/salla-loyalty-hero_2.entry.js +9 -9
  304. package/dist/esm/salla-loyalty-panel.entry.js +3 -3
  305. package/dist/esm/salla-loyalty-points-banner.entry.js +1 -1
  306. package/dist/esm/salla-loyalty-points-history.entry.js +2 -2
  307. package/dist/esm/salla-loyalty-prize-item.entry.js +2 -2
  308. package/dist/esm/salla-loyalty-program.entry.js +3 -3
  309. package/dist/esm/salla-loyalty-reward.entry.js +4 -4
  310. package/dist/esm/salla-loyalty.entry.js +1 -1
  311. package/dist/esm/salla-maintenance-alert.entry.js +2 -2
  312. package/dist/esm/{salla-map.entry.js → salla-map_2.entry.js} +70 -5
  313. package/dist/esm/salla-menu.entry.js +1 -1
  314. package/dist/esm/salla-metadata.entry.js +1 -1
  315. package/dist/esm/salla-multiple-bundle-product-cart_2.entry.js +4 -4
  316. package/dist/esm/salla-multiple-bundle-product-options-modal_2.entry.js +6 -6
  317. package/dist/esm/salla-multiple-bundle-product.entry.js +2 -2
  318. package/dist/esm/salla-next-order-coupon.entry.js +1 -1
  319. package/dist/esm/salla-notification-item.entry.js +2 -2
  320. package/dist/esm/salla-notifications.entry.js +1 -1
  321. package/dist/esm/salla-offer-modal.entry.js +2 -2
  322. package/dist/esm/salla-offer.entry.js +1 -1
  323. package/dist/esm/salla-order-branch.entry.js +1 -1
  324. package/dist/esm/salla-order-details-multiple-bundle-product.entry.js +1 -1
  325. package/dist/esm/salla-order-details-options.entry.js +1 -1
  326. package/dist/esm/salla-order-details.entry.js +2 -2
  327. package/dist/esm/salla-order-edit-item.entry.js +1 -1
  328. package/dist/esm/salla-order-edit-product-card.entry.js +2 -2
  329. package/dist/esm/salla-order-edit.entry.js +1 -1
  330. package/dist/esm/{salla-product-card_2.entry.js → salla-order-options-modal_3.entry.js} +209 -7
  331. package/dist/esm/salla-order-summary.entry.js +2 -2
  332. package/dist/esm/salla-order-totals-card.entry.js +1 -1
  333. package/dist/esm/salla-orders.entry.js +1 -1
  334. package/dist/esm/salla-payments.entry.js +3 -3
  335. package/dist/esm/salla-placeholder.entry.js +2 -2
  336. package/dist/esm/salla-price-range.entry.js +3 -3
  337. package/dist/esm/salla-product-card-embed.entry.js +2 -2
  338. package/dist/esm/salla-product-size-guide.entry.js +3 -3
  339. package/dist/esm/salla-products-list.entry.js +1 -1
  340. package/dist/esm/salla-quick-order.entry.js +1 -1
  341. package/dist/esm/salla-rating-modal.entry.js +1 -1
  342. package/dist/esm/salla-reward-action_4.entry.js +10 -10
  343. package/dist/esm/salla-scopes.entry.js +2 -2
  344. package/dist/esm/salla-search.entry.js +6 -6
  345. package/dist/esm/salla-skeleton.entry.js +2 -2
  346. package/dist/esm/salla-slider.entry.js +1 -1
  347. package/dist/esm/salla-social-share.entry.js +2 -2
  348. package/dist/esm/salla-social.entry.js +2 -2
  349. package/dist/esm/salla-tab-content_3.entry.js +4 -4
  350. package/dist/esm/salla-tiered-offer.entry.js +1 -1
  351. package/dist/esm/salla-tooltip.entry.js +2 -2
  352. package/dist/esm/salla-trust-badges.entry.js +1 -1
  353. package/dist/esm/salla-user-menu.entry.js +1 -1
  354. package/dist/esm/salla-user-profile.entry.js +1 -1
  355. package/dist/esm/salla-user-settings.entry.js +2 -2
  356. package/dist/esm/salla-verify.entry.js +1 -1
  357. package/dist/esm/salla-wallet.entry.js +1 -1
  358. package/dist/esm/salla-wishlist-actions.entry.js +2 -2
  359. package/dist/esm/{tracked-promise-CfOFv_ZQ.js → tracked-promise-DxK5ancc.js} +1 -1
  360. package/dist/esm/twilight.js +3 -3
  361. package/dist/esm/{vanilla-picker-BwAhzkb2.js → vanilla-picker-BNKvceoq.js} +1 -1
  362. package/dist/twilight/{p-193f4672.entry.js → p-01995780.entry.js} +1 -1
  363. package/dist/twilight/{p-46b75509.entry.js → p-02822e9f.entry.js} +1 -1
  364. package/dist/twilight/p-080444bb.entry.js +4 -0
  365. package/dist/twilight/{p-e573c23d.entry.js → p-0d01c327.entry.js} +1 -1
  366. package/dist/twilight/{p-9ac3d874.entry.js → p-0dcb8111.entry.js} +1 -1
  367. package/dist/twilight/p-129c20ed.entry.js +4 -0
  368. package/dist/twilight/{p-e2e38f7d.entry.js → p-15541ca3.entry.js} +1 -1
  369. package/dist/twilight/p-155d4693.entry.js +4 -0
  370. package/dist/twilight/{p-85d1767d.entry.js → p-1982cd13.entry.js} +1 -1
  371. package/dist/twilight/{p-b1d439e7.entry.js → p-1b8c59cf.entry.js} +1 -1
  372. package/dist/twilight/{p-3100186f.entry.js → p-1dc58168.entry.js} +1 -1
  373. package/dist/twilight/{p-768b4a83.entry.js → p-1f3480ba.entry.js} +1 -1
  374. package/dist/twilight/p-241b94a6.entry.js +4 -0
  375. package/dist/twilight/{p-69e7eb15.entry.js → p-2b75426a.entry.js} +1 -1
  376. package/dist/twilight/{p-6e2c05e8.entry.js → p-2dc46abc.entry.js} +1 -1
  377. package/dist/twilight/p-2eaf114e.entry.js +4 -0
  378. package/dist/twilight/{p-780abf03.entry.js → p-304f3de9.entry.js} +1 -1
  379. package/dist/twilight/p-35f30553.entry.js +4 -0
  380. package/dist/twilight/{p-d059046e.entry.js → p-3adacc75.entry.js} +1 -1
  381. package/dist/twilight/p-3e9f8d3c.entry.js +4 -0
  382. package/dist/twilight/{p-6543c5eb.entry.js → p-407a0c14.entry.js} +1 -1
  383. package/dist/twilight/{p-61bcbf9a.entry.js → p-43affbdd.entry.js} +1 -1
  384. package/dist/twilight/{p-a8a9b151.entry.js → p-456cfec5.entry.js} +1 -1
  385. package/dist/twilight/{p-3995c76e.entry.js → p-46c8b2d4.entry.js} +1 -1
  386. package/dist/twilight/{p-badfd153.entry.js → p-474b22b8.entry.js} +1 -1
  387. package/dist/twilight/{p-9f8a065c.entry.js → p-49c42118.entry.js} +1 -1
  388. package/dist/twilight/p-5089b72f.entry.js +4 -0
  389. package/dist/twilight/{p-c907509d.entry.js → p-5229c8aa.entry.js} +1 -1
  390. package/dist/twilight/{p-5f989a35.entry.js → p-550a91fe.entry.js} +1 -1
  391. package/dist/twilight/{p-463cf5ea.entry.js → p-594694e9.entry.js} +1 -1
  392. package/dist/twilight/{p-6ee5c24d.entry.js → p-5a18c6cc.entry.js} +1 -1
  393. package/dist/twilight/{p-38b5829a.entry.js → p-5aa08192.entry.js} +1 -1
  394. package/dist/twilight/p-5bda616b.entry.js +4 -0
  395. package/dist/twilight/p-5d9b57c8.entry.js +4 -0
  396. package/dist/twilight/{p-c4c3e16f.entry.js → p-6030f1fd.entry.js} +1 -1
  397. package/dist/twilight/{p-a756b0a4.entry.js → p-62010e29.entry.js} +1 -1
  398. package/dist/twilight/{p-df72e6a9.entry.js → p-63f1acc7.entry.js} +1 -1
  399. package/dist/twilight/p-6790943b.entry.js +4 -0
  400. package/dist/twilight/{p-fe2a4d07.entry.js → p-67d41cbb.entry.js} +1 -1
  401. package/dist/twilight/{p-9668a8aa.entry.js → p-6c39606a.entry.js} +1 -1
  402. package/dist/twilight/{p-fca82074.entry.js → p-6d6184c0.entry.js} +1 -1
  403. package/dist/twilight/{p-f145dc81.entry.js → p-6eab2444.entry.js} +1 -1
  404. package/dist/twilight/{p-dcc34752.entry.js → p-72a1b702.entry.js} +1 -1
  405. package/dist/twilight/{p-30fe7a02.entry.js → p-7442c41a.entry.js} +1 -1
  406. package/dist/twilight/{p-51b4ab80.entry.js → p-7f4d4e3c.entry.js} +1 -1
  407. package/dist/twilight/{p-be077285.entry.js → p-7fdeec2b.entry.js} +1 -1
  408. package/dist/twilight/{p-f4f47286.entry.js → p-83cb6915.entry.js} +1 -1
  409. package/dist/twilight/{p-017500f8.entry.js → p-88bed460.entry.js} +1 -1
  410. package/dist/twilight/{p-623b0c48.entry.js → p-8d1c4f93.entry.js} +1 -1
  411. package/dist/twilight/{p-4d2f0573.entry.js → p-8d427c53.entry.js} +1 -1
  412. package/dist/twilight/p-929e5aed.entry.js +4 -0
  413. package/dist/twilight/p-956d6683.entry.js +4 -0
  414. package/dist/twilight/{p-BPasfwVf.js → p-BKKN_hn3.js} +1 -1
  415. package/dist/twilight/{p-DVCS8qoq.js → p-BT5S72c8.js} +1 -1
  416. package/dist/twilight/{p-D2W2ygY1.js → p-ByL3FHQ6.js} +1 -1
  417. package/dist/twilight/p-CBwG3dWv.js +9 -0
  418. package/dist/twilight/{p-Dckjjczv.js → p-CjnbnAFU.js} +1 -1
  419. package/dist/twilight/{p-DNU1AEuR.js → p-ClNJhnhN.js} +1 -1
  420. package/dist/twilight/{p-DzHsJ03K.js → p-Cq2cbPYZ.js} +1 -1
  421. package/dist/twilight/p-Czf4a8gg.js +9 -0
  422. package/dist/twilight/{p--Jfvyk1f.js → p-D6Z2cDb0.js} +1 -1
  423. package/dist/twilight/{p-BgFqaLNN.js → p-DBxZFsVz.js} +1 -1
  424. package/dist/twilight/{p-BxhAwisc.js → p-DXVmi29t.js} +1 -1
  425. package/dist/twilight/{p-CHsBLTlN.js → p-DY6O-SiT.js} +1 -1
  426. package/dist/twilight/{p-1fa5c385.entry.js → p-a1e520d5.entry.js} +1 -1
  427. package/dist/twilight/{p-0052df8e.entry.js → p-a26fe1e5.entry.js} +1 -1
  428. package/dist/twilight/{p-0fa958a8.entry.js → p-a30cfade.entry.js} +1 -1
  429. package/dist/twilight/{p-eaf8f509.entry.js → p-a9090afd.entry.js} +1 -1
  430. package/dist/twilight/{p-89dae763.entry.js → p-ae2c963f.entry.js} +1 -1
  431. package/dist/twilight/{p-0a8fdddc.entry.js → p-b18a446a.entry.js} +1 -1
  432. package/dist/twilight/{p-9196d137.entry.js → p-b1c97472.entry.js} +1 -1
  433. package/dist/twilight/{p-bc1725dd.entry.js → p-bc6c4c1c.entry.js} +1 -1
  434. package/dist/twilight/{p-31fca96b.entry.js → p-be10a9c3.entry.js} +1 -1
  435. package/dist/twilight/p-c26cf3fa.entry.js +4 -0
  436. package/dist/twilight/{p-092318cc.entry.js → p-c4655810.entry.js} +1 -1
  437. package/dist/twilight/{p-ba55e58f.entry.js → p-c5211eca.entry.js} +1 -1
  438. package/dist/twilight/{p-6ce0ab6e.entry.js → p-cbd793c8.entry.js} +1 -1
  439. package/dist/twilight/{p-052922a0.entry.js → p-cfb9665f.entry.js} +2 -2
  440. package/dist/twilight/p-d46fb24a.entry.js +4 -0
  441. package/dist/twilight/{p-a2ff9abd.entry.js → p-d6cb423a.entry.js} +1 -1
  442. package/dist/twilight/{p-721ae2c4.entry.js → p-d7a2e982.entry.js} +1 -1
  443. package/dist/twilight/{p-77db23d2.entry.js → p-d9868f07.entry.js} +1 -1
  444. package/dist/twilight/{p-ba5d1170.entry.js → p-dbe3a5bb.entry.js} +1 -1
  445. package/dist/twilight/{p-66d2b9e3.entry.js → p-e041fe56.entry.js} +1 -1
  446. package/dist/twilight/{p-37299c40.entry.js → p-e058b62c.entry.js} +1 -1
  447. package/dist/twilight/{p-6f63f391.entry.js → p-e07c9a85.entry.js} +1 -1
  448. package/dist/twilight/{p-ddbffad3.entry.js → p-e1275bf7.entry.js} +1 -1
  449. package/dist/twilight/{p-7a75c505.entry.js → p-e5d5a6b3.entry.js} +1 -1
  450. package/dist/twilight/p-e5e6ea75.entry.js +4 -0
  451. package/dist/twilight/{p-9a6ea758.entry.js → p-e7a255a3.entry.js} +1 -1
  452. package/dist/twilight/{p-de70e0f6.entry.js → p-ebebcd55.entry.js} +1 -1
  453. package/dist/twilight/{p-6f86922a.entry.js → p-f0d7247d.entry.js} +1 -1
  454. package/dist/twilight/{p-3d65f310.entry.js → p-f222bf9f.entry.js} +1 -1
  455. package/dist/twilight/{p-1da95f6f.entry.js → p-f2594407.entry.js} +1 -1
  456. package/dist/twilight/{p-21e43f89.entry.js → p-f4235325.entry.js} +1 -1
  457. package/dist/twilight/p-fafdeea7.entry.js +4 -0
  458. package/dist/twilight/{p-ef26e3be.entry.js → p-fb7de7c4.entry.js} +1 -1
  459. package/dist/twilight/{p-1eadcac5.entry.js → p-fc1e3854.entry.js} +1 -1
  460. package/dist/twilight/{p-7288ff02.entry.js → p-fc72b631.entry.js} +1 -1
  461. package/dist/twilight/{p-681a053f.entry.js → p-fce2579c.entry.js} +1 -1
  462. package/dist/twilight/twilight.esm.js +1 -1
  463. package/dist/types/components/salla-add-product-button/salla-add-product-button.d.ts +2 -0
  464. package/dist/types/components/salla-breadcrumb/salla-breadcrumb.d.ts +1 -0
  465. package/dist/types/components/salla-order-options-modal/apple-pay-order-options.d.ts +26 -0
  466. package/dist/types/components/salla-order-options-modal/order-options-gate.d.ts +23 -0
  467. package/dist/types/components/salla-order-options-modal/salla-order-options-modal.d.ts +66 -0
  468. package/dist/types/components/salla-product-options/availability-utils.d.ts +19 -0
  469. package/dist/types/components/salla-product-options/salla-product-options.d.ts +14 -0
  470. package/dist/types/components/salla-quick-buy/salla-quick-buy.d.ts +14 -0
  471. package/dist/types/components.d.ts +62 -0
  472. package/package.json +5 -5
  473. package/dist/cjs/salla-progress-bar.cjs.entry.js +0 -73
  474. package/dist/esm/salla-progress-bar.entry.js +0 -71
  475. package/dist/twilight/p-05ffde56.entry.js +0 -4
  476. package/dist/twilight/p-0bf6b9ad.entry.js +0 -4
  477. package/dist/twilight/p-294a3248.entry.js +0 -4
  478. package/dist/twilight/p-2b2af618.entry.js +0 -4
  479. package/dist/twilight/p-45a786cd.entry.js +0 -4
  480. package/dist/twilight/p-476463ea.entry.js +0 -4
  481. package/dist/twilight/p-56f4d005.entry.js +0 -4
  482. package/dist/twilight/p-58bcae28.entry.js +0 -4
  483. package/dist/twilight/p-5d19859e.entry.js +0 -4
  484. package/dist/twilight/p-63f20aa0.entry.js +0 -4
  485. package/dist/twilight/p-83222f33.entry.js +0 -4
  486. package/dist/twilight/p-84dc489a.entry.js +0 -4
  487. package/dist/twilight/p-869773d3.entry.js +0 -4
  488. package/dist/twilight/p-97b74b76.entry.js +0 -4
  489. package/dist/twilight/p-9dca7f59.entry.js +0 -4
  490. package/dist/twilight/p-BFEfBkEW.js +0 -9
  491. package/dist/twilight/p-DWcI2hUr.js +0 -9
  492. package/dist/twilight/p-ad60969e.entry.js +0 -4
  493. package/dist/twilight/p-dc9b7a8e.entry.js +0 -4
  494. package/dist/twilight/p-fc7a1f2f.entry.js +0 -4
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * Crafted with ❤ by Salla
3
3
  */
4
- import { r as registerInstance, c as createEvent, h, H as Host, a as getElement, e as axios } from './index-Dckjjczv.js';
4
+ import { r as registerInstance, c as createEvent, h, H as Host, a as getElement, e as axios } from './index-CjnbnAFU.js';
5
5
  import { P as PendingOrdersIcon } from './cart-DY4LZmNP.js';
6
6
  import { H as Helper } from './Helper-BXj4f_Qj.js';
7
7
  import { B as BellRing } from './bell-ring-D3mWkc-3.js';
@@ -17,6 +17,140 @@ var WalletIcon = `<!-- Generated by IcoMoon.io -->
17
17
  </svg>
18
18
  `;
19
19
 
20
+ /**
21
+ * Order-options gate for the fast-checkout widget — keeps <salla-add-product-button> thin.
22
+ * Intercepts the widget click → runs the order-options modal → injects the result → re-fires the click.
23
+ */
24
+ const PRODUCT_FORM_SELECTOR = 'form.product-form';
25
+ class OrderOptionsGate {
26
+ constructor(host, productId) {
27
+ this.host = host;
28
+ this.productId = productId;
29
+ /** True on the re-fired click so it passes through instead of re-gating. */
30
+ this.collected = false;
31
+ /** Live PDP price (one onPriceUpdated subscription per widget). */
32
+ this.livePrice = 0;
33
+ }
34
+ /** Attach once to the widget. Returns false when there's no widget (e.g. product cards) so the caller retries. */
35
+ static attach(host, productId) {
36
+ const widget = host.querySelector('salla-mini-checkout-widget');
37
+ if (!widget)
38
+ return false;
39
+ const gate = new OrderOptionsGate(host, String(productId));
40
+ // One subscription per widget (PDP only) — no per-card leak.
41
+ salla.product?.event?.onPriceUpdated?.((response) => {
42
+ gate.livePrice = Number(response?.data?.price) || gate.livePrice;
43
+ });
44
+ widget.addEventListener('click', (event) => gate.handleWidgetClick(event, widget), true);
45
+ return true;
46
+ }
47
+ /** Quantity from the same form the widget submits (PRODUCT_FORM_SELECTOR), not the button's nearest form. */
48
+ getSelectedQuantity() {
49
+ try {
50
+ const form = document.querySelector(PRODUCT_FORM_SELECTOR);
51
+ const data = form?.getElementSallaData?.();
52
+ const qty = Number(data instanceof FormData ? data.get('quantity') : data?.quantity);
53
+ if (Number.isFinite(qty) && qty > 0)
54
+ return qty;
55
+ }
56
+ catch {
57
+ // fall through to the attribute
58
+ }
59
+ return Number(this.host.getAttribute('quantity')) || 1;
60
+ }
61
+ async handleWidgetClick(event, widget) {
62
+ if (this.collected) {
63
+ this.collected = false;
64
+ return;
65
+ }
66
+ event.preventDefault();
67
+ event.stopImmediatePropagation();
68
+ if (!await this.validatePdpOptions())
69
+ return;
70
+ if (salla.config.isGuest()) {
71
+ salla.api.auth.requireLoginThen('salla-add-product-button::oo.after-login', () => this.handleWidgetClick(event, widget));
72
+ return;
73
+ }
74
+ widget.classList.add('s-add-product-button-busy');
75
+ let resp;
76
+ try {
77
+ resp = await salla.api.withoutNotifier(() => salla.product.api.getOrderOptions([{ id: this.productId, quantity: this.getSelectedQuantity() }]));
78
+ }
79
+ catch (error) {
80
+ salla?.logger?.warn?.('order-options: fetch failed', error);
81
+ widget.classList.remove('s-add-product-button-busy');
82
+ this.resumeWidget(widget);
83
+ return;
84
+ }
85
+ widget.classList.remove('s-add-product-button-busy');
86
+ const items = resp?.data?.order_options || [];
87
+ if (!items.length) {
88
+ this.resumeWidget(widget);
89
+ return;
90
+ }
91
+ const basePrice = this.livePrice > 0
92
+ ? this.livePrice
93
+ : Number(resp?.data?.products?.[0]?.price?.amount) || 0;
94
+ const modal = this.ensureModal();
95
+ try {
96
+ const result = await modal.open({ orderOptions: items, basePrice });
97
+ this.injectIntoMini(result?.orderOptions || []);
98
+ this.resumeWidget(widget);
99
+ }
100
+ catch {
101
+ // user dismissed — widget stays blocked, they re-click to retry.
102
+ }
103
+ }
104
+ async validatePdpOptions() {
105
+ const optionsEl = document.querySelector(`salla-product-options[product-id="${this.productId}"]`);
106
+ if (!optionsEl)
107
+ return true;
108
+ if (typeof optionsEl.validateAndScroll === 'function') {
109
+ return await optionsEl.validateAndScroll();
110
+ }
111
+ if (typeof optionsEl.reportValidity === 'function') {
112
+ return await optionsEl.reportValidity();
113
+ }
114
+ return true;
115
+ }
116
+ /** Inject order_options into the next cart-add payload via `cart::before.add.item` (one-shot, scoped to productId). */
117
+ injectIntoMini(orderOptions) {
118
+ if (!orderOptions.length)
119
+ return;
120
+ const productId = this.productId;
121
+ const onceHandler = (eventData) => {
122
+ if (String(eventData?.id) !== String(productId))
123
+ return;
124
+ try {
125
+ eventData?.payload?.set?.('order_options', orderOptions);
126
+ }
127
+ finally {
128
+ salla.event.off('cart::before.add.item', onceHandler);
129
+ }
130
+ };
131
+ salla.event.on('cart::before.add.item', onceHandler);
132
+ }
133
+ ensureModal() {
134
+ let modal = document.querySelector('salla-order-options-modal');
135
+ if (!modal) {
136
+ modal = document.createElement('salla-order-options-modal');
137
+ document.body.appendChild(modal);
138
+ }
139
+ return modal;
140
+ }
141
+ resumeWidget(widget) {
142
+ this.collected = true;
143
+ // Real click target lives in the widget's shadow DOM.
144
+ const innerBtn = widget.shadowRoot?.querySelector?.('.s-fast-checkout-button');
145
+ if (innerBtn) {
146
+ innerBtn.click();
147
+ }
148
+ else if (typeof widget.click === 'function') {
149
+ widget.click();
150
+ }
151
+ }
152
+ }
153
+
20
154
  const sallaAddProductButtonCss = ":host{display:block}salla-add-product-button[width=wide]{width:100%}";
21
155
 
22
156
  const SallaAddProductButton = class {
@@ -42,6 +176,8 @@ const SallaAddProductButton = class {
42
176
  /** Use matchMedia instead of window.innerWidth to avoid forced reflow (Lighthouse/PageSpeed) */
43
177
  this.isDesktopViewport = typeof window !== 'undefined' ? window.matchMedia('(min-width: 768px)').matches : true;
44
178
  this.viewportMediaQuery = null;
179
+ /** Guards one-time attachment of the order-options gate to the mini-checkout widget. */
180
+ this.orderOptionsGateAttached = false;
45
181
  this.onViewportChange = (e) => {
46
182
  this.isDesktopViewport = e.matches;
47
183
  this.btn?.setText((e.matches && !!this.passedLabel) ? this.passedLabel : this.getLabel());
@@ -229,6 +365,13 @@ const SallaAddProductButton = class {
229
365
  });
230
366
  }
231
367
  componentDidRender() {
368
+ // Wire the order-options gate to the fast-checkout widget once it renders (logic lives in OrderOptionsGate).
369
+ // Only when the merchant enabled order options; otherwise the widget runs the normal fast-checkout flow.
370
+ if (!this.orderOptionsGateAttached && this.productId
371
+ && salla.config.get('store.settings.order_options.mandatory', false)
372
+ && OrderOptionsGate.attach(this.host, this.productId)) {
373
+ this.orderOptionsGateAttached = true;
374
+ }
232
375
  //if label not passed, get label
233
376
  if (!!this.passedLabel && (!this.supportStickyBar || this.isDesktopViewport)) {
234
377
  // if passed label, set it
@@ -574,7 +717,7 @@ const SallaProductAvailability = class {
574
717
  field.nextElementSibling['innerText'] = '* ' + errorMsg;
575
718
  }
576
719
  render() {
577
- return (h(Host, { key: '144b0687a0e527fa493aa701c334db76a7b42164', class: "s-product-availability-wrap" }, this.isSubscribedToProduct
720
+ return (h(Host, { key: '0779c3aef2637bfcd30ecf110d0cd31d819a82a5', class: "s-product-availability-wrap" }, this.isSubscribedToProduct
578
721
  ? h("div", { class: "s-product-availability-subscribed" }, h("span", { innerHTML: BellRing, class: "s-product-availability-subs-icon" }), salla.lang.get('pages.products.notify_availability_success'))
579
722
  :
580
723
  h("salla-button", { width: "wide", onClick: () => this.isUser ? this.submit() : this.openModel() }, salla.lang.get('pages.products.notify_availability')), this.isUser || this.isSubscribedToProduct ? '' : this.renderModal()));
@@ -596,6 +739,58 @@ const SallaProductAvailability = class {
596
739
  };
597
740
  SallaProductAvailability.style = sallaProductAvailabilityCss;
598
741
 
742
+ /**
743
+ * Builds a per-detail availability map from SKU-level data.
744
+ *
745
+ * Exported as a pure function so it can be unit-tested independently of the
746
+ * Stencil component (the @State availabilityMap backing-store is not accessible
747
+ * via page.rootInstance in the Stencil mock-doc test environment).
748
+ *
749
+ * Status values:
750
+ * 'available' – at least one in-stock SKU for this detail + current selections
751
+ * 'out_of_stock' – all matching SKUs are out of stock
752
+ * 'impossible' – no SKU intersection exists for this combination
753
+ *
754
+ * skus_availability is always the authoritative source when present; is_out is
755
+ * consulted only as a last resort when a detail has no SKU data at all.
756
+ */
757
+ function computeAvailabilityMap(optionsData, selectedOptions) {
758
+ const map = {};
759
+ if (!optionsData?.length)
760
+ return map;
761
+ const variantGroups = optionsData.filter(opt => opt.details?.some(d => d.skus_availability && Object.keys(d.skus_availability).length > 0));
762
+ const isSingleGroup = variantGroups.length <= 1;
763
+ for (const optionGroup of variantGroups) {
764
+ const otherSelected = selectedOptions.filter(s => s.option_id !== optionGroup.id);
765
+ for (const detail of optionGroup.details) {
766
+ const skusAvail = detail.skus_availability;
767
+ // No skus_availability data — fall back to is_out as last resort only.
768
+ if (!skusAvail || !Object.keys(skusAvail).length) {
769
+ map[detail.id] = detail.is_out ? 'out_of_stock' : 'available';
770
+ continue;
771
+ }
772
+ const detailSkus = Object.keys(skusAvail).map(Number);
773
+ // No cross-group context yet — evaluate this detail's own SKUs directly.
774
+ if (isSingleGroup || otherSelected.length === 0) {
775
+ map[detail.id] = detailSkus.some(sku => skusAvail[sku]) ? 'available' : 'out_of_stock';
776
+ continue;
777
+ }
778
+ // Intersect this detail's SKUs with those of each other selected detail.
779
+ let candidates = detailSkus;
780
+ for (const other of otherSelected) {
781
+ const otherSkus = new Set(Object.keys(other.skus_availability || {}).map(Number));
782
+ candidates = candidates.filter(sku => otherSkus.has(sku));
783
+ }
784
+ if (!candidates.length) {
785
+ map[detail.id] = 'impossible';
786
+ continue;
787
+ }
788
+ map[detail.id] = candidates.some(sku => skusAvail[sku]) ? 'available' : 'out_of_stock';
789
+ }
790
+ }
791
+ return map;
792
+ }
793
+
599
794
  var FileIcon = `<!-- Generated by IcoMoon.io -->
600
795
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
601
796
  <title>file-upload</title>
@@ -628,6 +823,7 @@ const SallaProductOptions = class {
628
823
  this.availableDigitalCardValues = [];
629
824
  this.userInitiatedValidation = false;
630
825
  this.isCartMode = false;
826
+ this.availabilityMap = {};
631
827
  this.outSkus = [];
632
828
  /**
633
829
  * Avoid selection of previous default or selected card value option
@@ -638,6 +834,11 @@ const SallaProductOptions = class {
638
834
  * The id of the product to which the options are going to be fetched for.
639
835
  */
640
836
  this.productId = salla.config.get('page.id');
837
+ /**
838
+ * Strip the wrapper's padding (keeps the background, rounded corners, margin).
839
+ * Used by callers that need the options to sit flush inside their own surface.
840
+ */
841
+ this.noPadding = false;
641
842
  this.handleDonationOptions = (event, detail, type, _option) => {
642
843
  // Donating-amount input only: onInput updates price and dispatches native change for form price watcher.
643
844
  if (detail === 'custom' && type === 'input') {
@@ -718,12 +919,14 @@ const SallaProductOptions = class {
718
919
  */
719
920
  async setOptionsData(optionsData) {
720
921
  this.optionsData = optionsData;
721
- const that = this;
722
- this.optionsData[0]?.details?.forEach(function (detail) {
922
+ this.outSkus = [];
923
+ this.optionsData[0]?.details?.forEach(detail => {
723
924
  Object.entries(detail.skus_availability || {})
724
- .filter(sku => !sku[1])
725
- .map(sku => that.outSkus.push(Number(sku[0])));
925
+ .filter(([, available]) => !available)
926
+ .forEach(([sku]) => this.outSkus.push(Number(sku)));
726
927
  });
928
+ this.fillSelectedOptions();
929
+ this.computeAvailability();
727
930
  }
728
931
  /**
729
932
  * Get the current options state, including selected values/details.
@@ -909,8 +1112,9 @@ const SallaProductOptions = class {
909
1112
  */
910
1113
  setSelectedSkus() {
911
1114
  this.selectedSkus = this.selectedOptions.map(detail => Object.keys(detail.skus_availability || {}))
912
- .reduce((p, c) => p.filter(e => c.includes(e)), []) // Initialize accumulator as an empty array
1115
+ .reduce((p, c) => p.filter(e => c.includes(e)), [])
913
1116
  .map(sku => Number(sku));
1117
+ this.computeAvailability();
914
1118
  }
915
1119
  handleRequiredMultipleOptions(option) {
916
1120
  if (option.type !== DisplayType.MULTIPLE_OPTIONS || !option.required) {
@@ -1114,7 +1318,7 @@ const SallaProductOptions = class {
1114
1318
  if (this.optionsData?.length === 0) {
1115
1319
  return;
1116
1320
  }
1117
- return (h(Host, { class: "s-product-options-wrapper" }, h("salla-conditional-fields", null, this.optionsData.map((option) => h("div", { key: option.id, class: `s-product-options-option-container${option.visibility_condition || this.hideDigitalCardsOptions(option) ? ' hidden' : ''}`, "data-option-id": option.id, ...this.getOptionShownWhen(option) }, option.name === 'splitter' ?
1321
+ return (h(Host, { class: { 's-product-options-wrapper': true, 's-product-options-no-padding': this.noPadding } }, h("salla-conditional-fields", null, this.optionsData.map((option) => h("div", { key: option.id, class: `s-product-options-option-container${option.visibility_condition || this.hideDigitalCardsOptions(option) ? ' hidden' : ''}`, "data-option-id": option.id, ...this.getOptionShownWhen(option) }, option.name === 'splitter' ?
1118
1322
  this.splitterOption()
1119
1323
  : h("div", { class: { "s-product-options-option": true, "s-product-options-option-booking": option.type === DisplayType.BOOKING && salla.url.is_page("cart") }, "data-option-type": option.type, "data-option-required": `${option.required}` }, h("label", { htmlFor: this.generateInputId(option.id), class: `s-product-options-option-label ${this.hideLabel(option) ? 's-product-options-option-label-hidden' : ''}` }, h("b", null, option.name, option.required && h("span", null, " * "), " "), h("small", null, option.placeholder)), h("div", { class: `s-product-options-option-content ${this.hideLabel(option) || (option.type === DisplayType.BOOKING && salla.url.is_page("cart")) ? 's-product-options-option-content-full-width' : ''}` }, this.getDisplayForType(option))))))));
1120
1324
  }
@@ -1169,7 +1373,9 @@ const SallaProductOptions = class {
1169
1373
  }
1170
1374
  fillSelectedOptions() {
1171
1375
  this.selectedOptions = this.optionsData.reduce((acc, opt) => {
1172
- const selectedDetails = opt.details.filter(detail => detail.is_selected);
1376
+ // `details` is optional on the Option interface — input-type options
1377
+ // (text/number/date/file) carry no choice list, so guard before filtering.
1378
+ const selectedDetails = (opt.details ?? []).filter(detail => detail.is_selected);
1173
1379
  const mappedDetails = selectedDetails.map(detail => ({
1174
1380
  ...detail,
1175
1381
  option_id: opt.id
@@ -1177,6 +1383,25 @@ const SallaProductOptions = class {
1177
1383
  return acc.concat(mappedDetails);
1178
1384
  }, []);
1179
1385
  }
1386
+ /**
1387
+ * Seed `selectedOptions` from API defaults (`is_selected: true`).
1388
+ * componentWillLoad does this only on the cart page; non-cart callers
1389
+ * (e.g. order-options modal) call this after mount to avoid the first
1390
+ * multi-select toggle wiping the pre-selected defaults.
1391
+ * */
1392
+ async seedSelectedOptions() {
1393
+ this.fillSelectedOptions();
1394
+ // A required multi-select renders every checkbox `required`; handleRequiredMultipleOptions
1395
+ // clears that once one is checked, but it only fires on user `change`. After seeding a
1396
+ // pre-selected default we run it for the initial DOM so a defaulted-but-untouched required
1397
+ // multi-select doesn't fail validation and block checkout. Defer to rAF so the seeded
1398
+ // `checked` state is painted before we count it (matches the change-handler pattern above).
1399
+ requestAnimationFrame(() => {
1400
+ this.optionsData
1401
+ ?.filter(o => o.type === DisplayType.MULTIPLE_OPTIONS && o.required)
1402
+ .forEach(o => this.handleRequiredMultipleOptions(o));
1403
+ });
1404
+ }
1180
1405
  async componentDidLoad() {
1181
1406
  if (!this.optionsData?.length) {
1182
1407
  return;
@@ -1239,6 +1464,7 @@ const SallaProductOptions = class {
1239
1464
  this.disableCardValue = false;
1240
1465
  this.canDisabled = true;
1241
1466
  this.fillSelectedOptions();
1467
+ this.computeAvailability();
1242
1468
  }
1243
1469
  /**
1244
1470
  * Enable user-initiated validation mode so invalid fields will scroll into view
@@ -1349,22 +1575,14 @@ const SallaProductOptions = class {
1349
1575
  //and because we are using this inside select option, we need to replace the html currency symbol with the store currency symbol
1350
1576
  return detailName.replace('<i class=sicon-sar></i>', salla.config.currency()?.symbol || 'ر.س');
1351
1577
  }
1578
+ computeAvailability() {
1579
+ this.availabilityMap = computeAvailabilityMap(this.optionsData || [], this.selectedOptions || []);
1580
+ }
1352
1581
  isOptionDetailOut(detail) {
1353
- if (detail.is_out || !detail.skus_availability || !this.selectedSkus?.length) {
1354
- return detail.is_out;
1355
- }
1356
- const isDetailSelected = this.selectedOptions.filter(option => option.id === detail.id).length;
1357
- //if the current options is the only selected option, so we are sure that it's not out, because there is no other options selected yet
1358
- if (isDetailSelected && this.selectedOptions.length === 1) {
1359
- return false;
1360
- }
1361
- //if current details has sku in the possible outSkus it's out for sure
1362
- if (isDetailSelected) {
1363
- //here we will get the possible outSkus for current selected options
1364
- const outSelectableSkus = this.selectedSkus.filter(sku => this.outSkus.includes(sku));
1365
- return Object.keys(detail.skus_availability).some(sku => outSelectableSkus.includes(Number(sku)));
1366
- }
1367
- return this.selectedOptions.some(option => option.is_out && option.option_id !== detail.option_id);
1582
+ const status = this.availabilityMap[detail.id];
1583
+ // !!detail.is_out guards against TypeScript optimising away `?? false`
1584
+ // for the non-nullable `is_out: boolean` field when the value is actually undefined at runtime.
1585
+ return status !== undefined ? status !== 'available' : !!detail.is_out;
1368
1586
  }
1369
1587
  /**
1370
1588
  * Renders a single input element (radio or checkbox) for an option detail.
@@ -1377,10 +1595,14 @@ const SallaProductOptions = class {
1377
1595
  */
1378
1596
  renderInput(type, detail, option, isRequired, name, buttonStyle) {
1379
1597
  const id = this.generateUniqueKey(`${type}-${option.id}-${detail.id}`);
1380
- const isDisabled = this.isOptionDetailOut(detail);
1598
+ const isOutOfStock = this.isOptionDetailOut(detail);
1381
1599
  return (h("label", { class: {
1382
- "s-product-options-disabled": isDisabled,
1383
- } }, h("input", { id: id, type: type, name: name, value: detail.id, disabled: isDisabled, required: isRequired, checked: detail.is_selected, onInvalid: (e) => this.invalidHandler(e, option), onChange: (e) => this.changedHandler(e, option) }), h("div", { class: { "s-product-options-grid-mode-span": buttonStyle, "s-product-options-disabled": isDisabled } }, this.getOptionDetailName(detail))));
1600
+ "s-product-options-disabled": this.canDisabled && isOutOfStock,
1601
+ "s-product-options-option-stock-out": isOutOfStock,
1602
+ } }, h("input", { id: id, type: type, name: name, value: detail.id, disabled: this.canDisabled && isOutOfStock, required: isRequired, checked: detail.is_selected, onInvalid: (e) => this.invalidHandler(e, option), onChange: (e) => this.changedHandler(e, option) }), h("div", { class: {
1603
+ "s-product-options-grid-mode-span": buttonStyle,
1604
+ "s-product-options-disabled": this.canDisabled && isOutOfStock,
1605
+ } }, this.getOptionDetailName(detail))));
1384
1606
  }
1385
1607
  /**
1386
1608
  * Renders a collection of input elements for all details of an option.
@@ -1453,15 +1675,22 @@ const SallaProductOptions = class {
1453
1675
  }
1454
1676
  //@ts-ignore
1455
1677
  colorOption(option) {
1456
- return (h("fieldset", { class: "s-product-options-colors-wrapper" }, option?.details.map((detail) => (h("div", { class: "s-product-options-colors-item", key: detail.id }, h("input", { type: "radio", value: detail.id, required: !option.visibility_condition && option.required, checked: detail.is_selected, name: this.generateInputName(option.id), disabled: this.canDisabled && this.isOptionDetailOut(detail), id: this.generateUniqueKey(`color-${this.productId}-${option.id}-${detail.id}`), onInvalid: (e) => this.invalidHandler(e, option), onChange: (e) => this.changedHandler(e, option), "data-img-id": detail.option_value }), h("label", { htmlFor: this.generateUniqueKey(`color-${this.productId}-${option.id}-${detail.id}`), "data-img-id": detail.option_value }, h("span", { style: { backgroundColor: detail.color } }), h("div", { innerHTML: this.getOptionDetailName(detail, true, option.type) })))))));
1678
+ return (h("fieldset", { class: "s-product-options-colors-wrapper" }, option?.details.map((detail) => {
1679
+ const isOutOfStock = this.isOptionDetailOut(detail);
1680
+ return (h("div", { class: {
1681
+ "s-product-options-colors-item": true,
1682
+ "s-product-options-option-stock-out": isOutOfStock,
1683
+ }, key: detail.id }, h("input", { type: "radio", value: detail.id, required: !option.visibility_condition && option.required, checked: detail.is_selected, name: this.generateInputName(option.id), disabled: this.canDisabled && isOutOfStock, id: this.generateUniqueKey(`color-${this.productId}-${option.id}-${detail.id}`), onInvalid: (e) => this.invalidHandler(e, option), onChange: (e) => this.changedHandler(e, option), "data-img-id": detail.option_value }), h("label", { htmlFor: this.generateUniqueKey(`color-${this.productId}-${option.id}-${detail.id}`), "data-img-id": detail.option_value }, h("span", { style: { backgroundColor: detail.color } }), h("div", { innerHTML: this.getOptionDetailName(detail, true, option.type) }))));
1684
+ })));
1457
1685
  }
1458
1686
  //@ts-ignore
1459
1687
  thumbnailOption(option) {
1460
1688
  return h("div", { class: "s-product-options-thumbnails-wrapper" }, option.details.map((detail) => {
1461
- return h("div", { key: detail.id }, h("input", { type: "radio", value: detail.id, "data-itemid": detail.id, required: !option.visibility_condition && option.required, checked: detail.is_selected, name: this.generateInputName(option.id), "data-img-id": detail.option_value, disabled: this.canDisabled && this.isOptionDetailOut(detail), id: this.generateUniqueKey(`option_${this.productId}-${option.id}_${detail.id}`), onInvalid: (e) => this.invalidHandler(e, option), onChange: (e) => this.changedHandler(e, option) }), h("label", { htmlFor: this.generateUniqueKey(`option_${this.productId}-${option.id}_${detail.id}`), "data-img-id": detail.option_value, class: "go-to-slide" }, h("img", { "data-src": detail.image, src: detail.image, title: detail.name, alt: detail.name }), h("span", { innerHTML: SICheck, class: "s-product-options-thumbnails-icon" }), this.isOptionDetailOut(detail) ?
1689
+ const isOutOfStock = this.isOptionDetailOut(detail);
1690
+ return h("div", { key: detail.id, class: { "s-product-options-option-stock-out": isOutOfStock } }, h("input", { type: "radio", value: detail.id, "data-itemid": detail.id, required: !option.visibility_condition && option.required, checked: detail.is_selected, name: this.generateInputName(option.id), "data-img-id": detail.option_value, disabled: this.canDisabled && isOutOfStock, id: this.generateUniqueKey(`option_${this.productId}-${option.id}_${detail.id}`), onInvalid: (e) => this.invalidHandler(e, option), onChange: (e) => this.changedHandler(e, option) }), h("label", { htmlFor: this.generateUniqueKey(`option_${this.productId}-${option.id}_${detail.id}`), "data-img-id": detail.option_value, class: "go-to-slide" }, h("img", { "data-src": detail.image, src: detail.image, title: detail.name, alt: detail.name }), h("span", { innerHTML: SICheck, class: "s-product-options-thumbnails-icon" }), isOutOfStock ?
1462
1691
  [
1463
- h("small", { key: detail.id, class: "s-product-options-thumbnails-stock-badge" }, this.outOfStockText),
1464
- this.canDisabled ? h("div", { key: detail.id, class: "s-product-options-thumbnails-badge-overlay" }) : '',
1692
+ h("small", { key: `badge-${detail.id}`, class: "s-product-options-thumbnails-stock-badge" }, this.outOfStockText),
1693
+ this.canDisabled ? h("div", { key: `overlay-${detail.id}`, class: "s-product-options-thumbnails-badge-overlay" }) : '',
1465
1694
  ]
1466
1695
  : ''), h("p", null, this.getOptionDetailName(detail, false), " "));
1467
1696
  }));
@@ -1476,7 +1705,8 @@ const SallaProductOptions = class {
1476
1705
  }
1477
1706
  countryOption(option) {
1478
1707
  return h("div", { class: "s-product-options-digital-card-wrapper" }, option.details.map((detail) => {
1479
- return h("label", { htmlFor: this.generateUniqueKey(detail.id.toString()), key: detail.id, class: { "s-product-options-digital-card-option": true, "s-product-options-digital-card-option-stock-out": detail.is_out } }, h("input", { id: this.generateUniqueKey(detail.id.toString()), type: "radio", class: "s-form-control s-product-options-digital-card-input", value: detail.id, name: this.generateInputName(option.id), disabled: detail.is_out, required: !option.visibility_condition && option.required, onInvalid: (e) => this.invalidHandler(e, option), onChange: e => this.changedHandler(e, option), onClick: () => { this.disableCardValue = false; }, ...(salla.url.is_page("cart") ? { defaultChecked: this.getSelectedDigitalCardOptions(option)?.id === detail.id } : {}) }), h("img", { loading: "lazy", alt: detail.code, height: 24, width: 24, class: "s-product-options-country-flag", src: `https://cdn.assets.salla.network/prod/admin/cp/assets/flags/1x1/${String(detail.code).toLocaleLowerCase()}.svg`, onError: e => {
1708
+ const isOutOfStock = this.isOptionDetailOut(detail);
1709
+ return h("label", { htmlFor: this.generateUniqueKey(detail.id.toString()), key: detail.id, class: { "s-product-options-digital-card-option": true, "s-product-options-digital-card-option-stock-out": isOutOfStock, "s-product-options-option-stock-out": isOutOfStock } }, h("input", { id: this.generateUniqueKey(detail.id.toString()), type: "radio", class: "s-form-control s-product-options-digital-card-input", value: detail.id, name: this.generateInputName(option.id), disabled: this.canDisabled && isOutOfStock, required: !option.visibility_condition && option.required, onInvalid: (e) => this.invalidHandler(e, option), onChange: e => this.changedHandler(e, option), onClick: () => { this.disableCardValue = false; }, ...(salla.url.is_page("cart") ? { defaultChecked: this.getSelectedDigitalCardOptions(option)?.id === detail.id } : {}) }), h("img", { loading: "lazy", alt: detail.code, height: 24, width: 24, class: "s-product-options-country-flag", src: `https://cdn.assets.salla.network/prod/admin/cp/assets/flags/1x1/${String(detail.code).toLocaleLowerCase()}.svg`, onError: e => {
1480
1710
  e.currentTarget.onerror = null;
1481
1711
  e.currentTarget.src =
1482
1712
  salla.url.cdn('images/globe.svg');
@@ -1998,7 +2228,15 @@ window.SallaApplePay = {
1998
2228
  SallaApplePay.session.oncouponcodechanged = SallaApplePay.onCouponCodeChanged;
1999
2229
  SallaApplePay.session.onpaymentmethodselected = SallaApplePay.onPaymentMethodSelected;
2000
2230
 
2001
- SallaApplePay.session.begin();
2231
+ // Hook between session creation and begin(). Return truthy to skip
2232
+ // begin() (caller handles it later, e.g. after async work).
2233
+ let skipBegin;
2234
+ if (typeof SallaApplePay.detail.onStartedSession === 'function') {
2235
+ skipBegin = SallaApplePay.detail.onStartedSession(SallaApplePay.session);
2236
+ }
2237
+ if (!skipBegin) {
2238
+ SallaApplePay.session.begin();
2239
+ }
2002
2240
  },
2003
2241
  onPaymentMethodSelected: async (event) => {
2004
2242
  salla.logger.log('🍏 Pay: onPaymentMethodSelected', event);
@@ -2416,6 +2654,88 @@ if (window.ApplePaySession?.canMakePayments()) {
2416
2654
  document.querySelectorAll('data-show-if-apple-pay-supported').forEach(element => element.style.display = 'none');
2417
2655
  }
2418
2656
 
2657
+ /**
2658
+ * Order-options helpers for the Apple Pay quick-buy flow — keeps <salla-quick-buy> to thin AP wiring.
2659
+ * Apple Pay resolves options inside the session-started hook (single gesture), so the caller owns
2660
+ * the ApplePaySession and drives it via callbacks.
2661
+ */
2662
+ /** Get-or-create the singleton order-options modal on <body>. */
2663
+ function ensureOrderOptionsModal() {
2664
+ let modal = document.querySelector('salla-order-options-modal');
2665
+ if (!modal) {
2666
+ modal = document.createElement('salla-order-options-modal');
2667
+ document.body.appendChild(modal);
2668
+ }
2669
+ return modal;
2670
+ }
2671
+ /** Sync PDP-option validity (an `await` would consume the Apple Pay gesture). Skips hidden/disabled inputs. */
2672
+ function reportProductOptionsValiditySync(productId) {
2673
+ const optionsElement = document.querySelector(`salla-product-options[product-id="${productId}"]`);
2674
+ if (!optionsElement)
2675
+ return true;
2676
+ const requiredInputs = optionsElement.querySelectorAll('[required]');
2677
+ let pass = true;
2678
+ requiredInputs.forEach((input) => {
2679
+ if (input.disabled || input.closest('.hidden'))
2680
+ return;
2681
+ if ('reportValidity' in input && !input.reportValidity())
2682
+ pass = false;
2683
+ });
2684
+ return pass;
2685
+ }
2686
+ /** Merge collected order-options into the quick-purchase payload (FormData or plain object). */
2687
+ function appendOrderOptionsToPayload(data, orderOptions) {
2688
+ if (!orderOptions.length)
2689
+ return;
2690
+ if (data && typeof data.append === 'function') {
2691
+ orderOptions.forEach((entry, i) => {
2692
+ data.append(`order_options[${i}][id]`, String(entry.id));
2693
+ data.append(`order_options[${i}][value]`, String(entry.value));
2694
+ });
2695
+ return;
2696
+ }
2697
+ if (data && typeof data === 'object') {
2698
+ data.order_options = orderOptions;
2699
+ }
2700
+ }
2701
+ /**
2702
+ * Fetch order options and, if any, collect them via the modal (apple-pay mode). Callbacks drive the
2703
+ * caller's pre-created session: `beginPendingSession` (no options), `discardPendingSession` (options
2704
+ * found — the modal's AP button starts a fresh one), `onSubmit` (submitted).
2705
+ */
2706
+ async function resolveApplePayOrderOptions(opts) {
2707
+ let resp;
2708
+ try {
2709
+ resp = await salla.api.withoutNotifier(() => salla.product.api.getOrderOptions([{ id: opts.productId, quantity: opts.quantity }]));
2710
+ }
2711
+ catch (error) {
2712
+ salla?.logger?.warn?.('order-options: fetch failed', error);
2713
+ opts.beginPendingSession();
2714
+ return;
2715
+ }
2716
+ const items = resp?.data?.order_options || [];
2717
+ if (!items.length) {
2718
+ opts.beginPendingSession(); // begin() doesn't need a fresh gesture
2719
+ return;
2720
+ }
2721
+ opts.discardPendingSession(); // drop the unused session; the modal builds a fresh one
2722
+ const basePrice = Number(opts.amount) > 0
2723
+ ? Number(opts.amount)
2724
+ : Number(resp?.data?.products?.[0]?.price?.amount) || 0;
2725
+ const modal = ensureOrderOptionsModal();
2726
+ try {
2727
+ await modal.open({
2728
+ orderOptions: items,
2729
+ basePrice,
2730
+ paymentMode: 'apple-pay',
2731
+ onSubmit: opts.onSubmit,
2732
+ });
2733
+ }
2734
+ catch {
2735
+ // dismissed — no live session
2736
+ }
2737
+ }
2738
+
2419
2739
  const sallaQuickBuyCss = ".s-quick-buy-button .s-button-text{display:flex}apple-pay-button{--apple-pay-button-width:100%;--apple-pay-button-height:40px;--apple-pay-button-border-radius:.75rem;--apple-pay-button-box-sizing:content-box}";
2420
2740
 
2421
2741
  const SallaQuickBuy = class {
@@ -2443,32 +2763,82 @@ const SallaQuickBuy = class {
2443
2763
  * @default {}
2444
2764
  */
2445
2765
  this.options = {};
2766
+ /** Modal selections, merged into the quick-purchase payload. */
2767
+ this.collectedOrderOptions = [];
2768
+ /** Flips true after the first onStartedSession so the second dispatch begins. */
2769
+ this.optionsResolved = false;
2770
+ /** PDP price + selected order-option prices (from the modal). */
2771
+ this.applePayAmount = 0;
2772
+ /** Session from the initial gesture; begun later when there are no order options. */
2773
+ this.pendingApplePaySession = null;
2446
2774
  this.quickBuy = salla.lang.get('pages.products.buy_now');
2775
+ /** Apple Pay onStartedSession: first call defers begin() to run the OO check; second (resolved) begins. */
2776
+ this.handleApplePaySessionStarted = (session) => {
2777
+ // Order options disabled → let Apple Pay begin normally, as if the feature didn't exist.
2778
+ if (!salla.config.get('store.settings.order_options.mandatory', false))
2779
+ return false;
2780
+ if (this.optionsResolved)
2781
+ return false;
2782
+ this.optionsResolved = true;
2783
+ this.pendingApplePaySession = session;
2784
+ resolveApplePayOrderOptions({
2785
+ productId: this.productId,
2786
+ amount: Number(this.amount),
2787
+ quantity: this.getSelectedQuantity(),
2788
+ beginPendingSession: () => {
2789
+ this.pendingApplePaySession?.begin();
2790
+ this.pendingApplePaySession = null;
2791
+ },
2792
+ discardPendingSession: () => { this.pendingApplePaySession = null; },
2793
+ onSubmit: (selections, total) => {
2794
+ this.collectedOrderOptions = selections;
2795
+ this.applePayAmount = total;
2796
+ this.settlePayment();
2797
+ },
2798
+ });
2799
+ return true;
2800
+ };
2447
2801
  salla.lang.onLoaded(() => {
2448
2802
  this.quickBuy = salla.lang.get('pages.products.buy_now');
2449
2803
  });
2450
2804
  }
2451
- async quickBuyHandler() {
2452
- // user guest and guest-checkout not enabled
2805
+ quickBuyHandler() {
2453
2806
  if (salla.config.isGuest() && !this.isGuestCheckout()) {
2454
2807
  this.requireLogin.emit({ productId: this.productId });
2455
- // todo (low) :: find a way to re-fire the method after success
2456
- let afterLoginEvent = "salla-quick-buy::user.logged-in";
2457
- salla.event.on(afterLoginEvent, () => this.settlePayment());
2458
- salla.api.auth.setAfterLoginEvent(afterLoginEvent);
2459
- return salla.auth.event.dispatch('login::open', { withoutReload: true });
2808
+ salla.api.auth.requireLoginThen('salla-quick-buy::user.logged-in', () => this.quickBuyHandler());
2809
+ return;
2460
2810
  }
2461
- await this.settlePayment();
2811
+ // Sync validate — AP needs the gesture preserved for new ApplePaySession().
2812
+ if (!this.validatePdpOptionsSync())
2813
+ return;
2814
+ this.optionsResolved = false;
2815
+ this.collectedOrderOptions = [];
2816
+ this.applePayAmount = 0;
2817
+ this.settlePayment();
2818
+ }
2819
+ /** Sync PDP-option validity (preserves the AP gesture); emits + notifies on failure. */
2820
+ validatePdpOptionsSync() {
2821
+ if (reportProductOptionsValiditySync(this.productId))
2822
+ return true;
2823
+ this.validationFailed.emit({ productId: this.productId });
2824
+ salla.error(salla.lang.get('common.messages.required_fields'));
2825
+ return false;
2462
2826
  }
2463
- async settlePayment() {
2464
- let optionsElement = document.querySelector(`salla-product-options[product-id="${this.productId}"]`);
2465
- //make sure all the required options are selected
2466
- if (optionsElement && !await optionsElement.reportValidity()) {
2467
- this.validationFailed.emit({ productId: this.productId });
2468
- return salla.error(salla.lang.get('common.messages.required_fields'));
2827
+ /** Read the live PDP quantity from the form so order-options match the real cart line. */
2828
+ getSelectedQuantity() {
2829
+ try {
2830
+ const data = this.host.getElementSallaData?.();
2831
+ const qty = Number(data instanceof FormData ? data.get('quantity') : data?.quantity);
2832
+ return Number.isFinite(qty) && qty > 0 ? qty : 1;
2469
2833
  }
2834
+ catch {
2835
+ return 1;
2836
+ }
2837
+ }
2838
+ async settlePayment() {
2470
2839
  //use this way to get quantity too
2471
2840
  let data = this.host.getElementSallaData();
2841
+ appendOrderOptionsToPayload(data, this.collectedOrderOptions);
2472
2842
  // if the store doesn't have Apple Pay , just create a cart and then redirect to check out page
2473
2843
  if (!this.isApplePayActive) {
2474
2844
  // return salla.product.buyNow(this.productId, data);
@@ -2486,13 +2856,16 @@ const SallaQuickBuy = class {
2486
2856
  }
2487
2857
  // noinspection TypeScriptValidateJSTypes
2488
2858
  salla.event.dispatch('payments::apple-pay.start-transaction', {
2489
- amount: this.amount, // 1000
2859
+ // Prefer the modal's collected total (PDP price + selected OO additional_prices).
2860
+ // Falls back to PDP live amount when no OO modal ran.
2861
+ amount: this.applePayAmount > 0 ? this.applePayAmount : this.amount,
2490
2862
  currency: this.currency || 'SAR', // SAR
2491
2863
  requiredShippingContactFields: this.getRequiredShippingContactFields(),
2492
2864
  shippingMethods: this.isRequireShipping ? [] : undefined,
2493
2865
  supportedNetworks: salla.config.get('store.settings.buy_now.networks'),
2494
2866
  supportedCountries: salla.config.get('store.settings.buy_now.countries'),
2495
2867
  countryCode: salla.config.get('store.store_country') || 'SA',
2868
+ onStartedSession: this.handleApplePaySessionStarted,
2496
2869
  validateMerchant: {
2497
2870
  url: this.validateHost ? `${this.validateHost}/checkout/applepay/validate` : salla.url.get('checkout/applepay/validate'),
2498
2871
  onSuccess: (response) => {
@@ -2623,7 +2996,7 @@ const SallaQuickBuy = class {
2623
2996
  });
2624
2997
  }
2625
2998
  render() {
2626
- return h(Host, { key: '078fa17510403612cf8204899fee395f057b88bd' }, this.quickBuyButton());
2999
+ return h(Host, { key: 'fb1bdf862d9b9cea58df14862f7ec9c4be388585' }, this.quickBuyButton());
2627
3000
  }
2628
3001
  quickBuyButton() {
2629
3002
  return h("apple-pay-button", { locale: salla?.config?.get?.('user.language_code') || 'ar', onClick: () => this.quickBuyHandler(), "data-quick-purchase": "applepay", class: "s-quick-buy-apple-pay", "data-is-applepay": "1", buttonstyle: "black", type: this.type });