@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.
- package/dist/cjs/{filepond-jdX95qxM.js → filepond-Cy1e6Ro5.js} +1 -1
- package/dist/cjs/{filepond-plugin-file-poster-DC9ozntr.js → filepond-plugin-file-poster-CLtWPKuV.js} +1 -1
- package/dist/cjs/{filepond-plugin-file-validate-size-DxUUyj2Z.js → filepond-plugin-file-validate-size-VaxUnQB7.js} +1 -1
- package/dist/cjs/{filepond-plugin-file-validate-type-DB4YCfw-.js → filepond-plugin-file-validate-type-qjNEM_4Q.js} +1 -1
- package/dist/cjs/{filepond-plugin-image-edit-QlnXOcNf.js → filepond-plugin-image-edit-DZdFIpzD.js} +1 -1
- package/dist/cjs/{filepond-plugin-image-exif-orientation-D6HJ47N2.js → filepond-plugin-image-exif-orientation-CMDdMoTf.js} +1 -1
- package/dist/cjs/{filepond-plugin-image-preview-DCaj9jNI.js → filepond-plugin-image-preview-CckneKBe.js} +1 -1
- package/dist/cjs/{functions-C_kzehHT.js → functions-DDLs9J1M.js} +1 -1
- package/dist/cjs/{index-CmPl0fIy.js → index-BLZPuy15.js} +10 -14
- package/dist/cjs/{index-SIy6bIWx.js → index-MGCYfYcr.js} +1 -1
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/salla-accordion-body_2.cjs.entry.js +4 -4
- package/dist/cjs/salla-accordion_6.cjs.entry.js +24 -8
- package/dist/cjs/salla-add-product-button_5.cjs.entry.js +422 -49
- package/dist/cjs/salla-advertisement.cjs.entry.js +1 -1
- package/dist/cjs/salla-alert_2.cjs.entry.js +4 -4
- package/dist/cjs/salla-app-install-alert.cjs.entry.js +1 -1
- package/dist/cjs/salla-apps-icons.cjs.entry.js +1 -1
- package/dist/cjs/salla-badge.cjs.entry.js +2 -2
- package/dist/cjs/salla-booking-field_7.cjs.entry.js +18 -18
- package/dist/cjs/salla-bullet-delivery_2.cjs.entry.js +5 -5
- package/dist/cjs/salla-cart-coupons.cjs.entry.js +2 -2
- package/dist/cjs/salla-cart-item-offers_2.cjs.entry.js +2 -2
- package/dist/cjs/salla-cashback-banner.cjs.entry.js +1 -1
- package/dist/cjs/salla-comment-form_8.cjs.entry.js +5 -5
- package/dist/cjs/salla-conditional-offer.cjs.entry.js +1 -1
- package/dist/cjs/salla-contacts.cjs.entry.js +1 -1
- package/dist/cjs/salla-cookies-bar.cjs.entry.js +1 -1
- package/dist/cjs/salla-count-down.cjs.entry.js +2 -2
- package/dist/cjs/salla-custom-fields.cjs.entry.js +1 -1
- package/dist/cjs/salla-delivery-promise.cjs.entry.js +1 -1
- package/dist/cjs/salla-edit-order-button.cjs.entry.js +1 -1
- package/dist/cjs/salla-filters-widget.cjs.entry.js +3 -3
- package/dist/cjs/salla-filters.cjs.entry.js +2 -2
- package/dist/cjs/salla-fulfillment-methods.cjs.entry.js +1 -1
- package/dist/cjs/salla-gifting.cjs.entry.js +3 -3
- package/dist/cjs/salla-hook.cjs.entry.js +2 -2
- package/dist/cjs/salla-infinite-scroll.cjs.entry.js +1 -1
- package/dist/cjs/salla-installment.cjs.entry.js +1 -1
- package/dist/cjs/salla-list-tile.cjs.entry.js +2 -2
- package/dist/cjs/salla-localization-modal.cjs.entry.js +2 -2
- package/dist/cjs/salla-login-modal.cjs.entry.js +1 -1
- package/dist/cjs/salla-loyalty-banner.cjs.entry.js +2 -2
- package/dist/cjs/salla-loyalty-hero_2.cjs.entry.js +9 -9
- package/dist/cjs/salla-loyalty-panel.cjs.entry.js +3 -3
- package/dist/cjs/salla-loyalty-points-banner.cjs.entry.js +1 -1
- package/dist/cjs/salla-loyalty-points-history.cjs.entry.js +2 -2
- package/dist/cjs/salla-loyalty-prize-item.cjs.entry.js +2 -2
- package/dist/cjs/salla-loyalty-program.cjs.entry.js +3 -3
- package/dist/cjs/salla-loyalty-reward.cjs.entry.js +4 -4
- package/dist/cjs/salla-loyalty.cjs.entry.js +1 -1
- package/dist/cjs/salla-maintenance-alert.cjs.entry.js +2 -2
- package/dist/cjs/{salla-map.cjs.entry.js → salla-map_2.cjs.entry.js} +70 -4
- package/dist/cjs/salla-menu.cjs.entry.js +1 -1
- package/dist/cjs/salla-metadata.cjs.entry.js +1 -1
- package/dist/cjs/salla-multiple-bundle-product-cart_2.cjs.entry.js +4 -4
- package/dist/cjs/salla-multiple-bundle-product-options-modal_2.cjs.entry.js +6 -6
- package/dist/cjs/salla-multiple-bundle-product.cjs.entry.js +2 -2
- package/dist/cjs/salla-next-order-coupon.cjs.entry.js +1 -1
- package/dist/cjs/salla-notification-item.cjs.entry.js +2 -2
- package/dist/cjs/salla-notifications.cjs.entry.js +1 -1
- package/dist/cjs/salla-offer-modal.cjs.entry.js +2 -2
- package/dist/cjs/salla-offer.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-branch.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-details-multiple-bundle-product.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-details-options.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-details.cjs.entry.js +2 -2
- package/dist/cjs/salla-order-edit-item.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-edit-product-card.cjs.entry.js +2 -2
- package/dist/cjs/salla-order-edit.cjs.entry.js +1 -1
- package/dist/cjs/{salla-product-card_2.cjs.entry.js → salla-order-options-modal_3.cjs.entry.js} +209 -6
- package/dist/cjs/salla-order-summary.cjs.entry.js +2 -2
- package/dist/cjs/salla-order-totals-card.cjs.entry.js +1 -1
- package/dist/cjs/salla-orders.cjs.entry.js +1 -1
- package/dist/cjs/salla-payments.cjs.entry.js +3 -3
- package/dist/cjs/salla-placeholder.cjs.entry.js +2 -2
- package/dist/cjs/salla-price-range.cjs.entry.js +3 -3
- package/dist/cjs/salla-product-card-embed.cjs.entry.js +2 -2
- package/dist/cjs/salla-product-size-guide.cjs.entry.js +3 -3
- package/dist/cjs/salla-products-list.cjs.entry.js +1 -1
- package/dist/cjs/salla-quick-order.cjs.entry.js +1 -1
- package/dist/cjs/salla-rating-modal.cjs.entry.js +1 -1
- package/dist/cjs/salla-reward-action_4.cjs.entry.js +10 -10
- package/dist/cjs/salla-scopes.cjs.entry.js +2 -2
- package/dist/cjs/salla-search.cjs.entry.js +6 -6
- package/dist/cjs/salla-skeleton.cjs.entry.js +2 -2
- package/dist/cjs/salla-slider.cjs.entry.js +1 -1
- package/dist/cjs/salla-social-share.cjs.entry.js +2 -2
- package/dist/cjs/salla-social.cjs.entry.js +2 -2
- package/dist/cjs/salla-tab-content_3.cjs.entry.js +4 -4
- package/dist/cjs/salla-tiered-offer.cjs.entry.js +1 -1
- package/dist/cjs/salla-tooltip.cjs.entry.js +2 -2
- package/dist/cjs/salla-trust-badges.cjs.entry.js +1 -1
- package/dist/cjs/salla-user-menu.cjs.entry.js +1 -1
- package/dist/cjs/salla-user-profile.cjs.entry.js +1 -1
- package/dist/cjs/salla-user-settings.cjs.entry.js +2 -2
- package/dist/cjs/salla-verify.cjs.entry.js +1 -1
- package/dist/cjs/salla-wallet.cjs.entry.js +1 -1
- package/dist/cjs/salla-wishlist-actions.cjs.entry.js +2 -2
- package/dist/cjs/{tracked-promise-D-gQXgPZ.js → tracked-promise-B-bFT1y-.js} +1 -1
- package/dist/cjs/twilight.cjs.js +2 -2
- package/dist/cjs/{vanilla-picker-CZ_8m6i_.js → vanilla-picker-CP29RTHf.js} +1 -1
- package/dist/collection/collection-manifest.json +1 -0
- package/dist/collection/components/salla-accordion/salla-accordion-body.js +1 -1
- package/dist/collection/components/salla-accordion/salla-accordion-head.js +2 -2
- package/dist/collection/components/salla-accordion/salla-accordion.js +1 -1
- package/dist/collection/components/salla-add-product-button/salla-add-product-button.js +10 -0
- package/dist/collection/components/salla-alert/salla-alert.js +1 -1
- package/dist/collection/components/salla-badge/salla-badge.js +1 -1
- package/dist/collection/components/salla-booking-field/salla-booking-field.js +1 -1
- package/dist/collection/components/salla-bottom-alert/salla-bottom-alert.js +2 -2
- package/dist/collection/components/salla-breadcrumb/salla-breadcrumb.js +21 -5
- package/dist/collection/components/salla-cart-coupons/salla-cart-coupons.js +1 -1
- package/dist/collection/components/salla-cart-summary/salla-cart-summary.js +1 -1
- package/dist/collection/components/salla-color-picker/salla-color-picker.js +1 -1
- package/dist/collection/components/salla-comment-form/salla-comment-form.js +1 -1
- package/dist/collection/components/salla-conditional-fields/salla-conditional-fields.js +1 -1
- package/dist/collection/components/salla-count-down/salla-count-down.js +1 -1
- package/dist/collection/components/salla-datetime-picker/salla-datetime-picker.js +1 -1
- package/dist/collection/components/salla-file-upload/salla-file-upload.js +2 -2
- package/dist/collection/components/salla-filters/salla-filters.js +1 -1
- package/dist/collection/components/salla-filters-widget/salla-filters-widget.js +2 -2
- package/dist/collection/components/salla-gifting/salla-gifting.js +2 -2
- package/dist/collection/components/salla-hook/salla-hook.js +1 -1
- package/dist/collection/components/salla-list-tile/salla-list-tile.js +1 -1
- package/dist/collection/components/salla-loading/salla-loading.js +1 -1
- package/dist/collection/components/salla-localization-modal/salla-localization-modal.js +1 -1
- package/dist/collection/components/salla-loyalty/salla-loyalty-prize-item.js +1 -1
- package/dist/collection/components/salla-loyalty-points-history/salla-loyalty-points-history.js +1 -1
- package/dist/collection/components/salla-loyalty-program/salla-loyalty-hero.js +3 -3
- package/dist/collection/components/salla-loyalty-program/salla-loyalty-point.js +4 -4
- package/dist/collection/components/salla-loyalty-program/salla-loyalty-reward.js +2 -2
- package/dist/collection/components/salla-loyalty-program/salla-reward-card.js +1 -1
- package/dist/collection/components/salla-loyalty-program/salla-reward-details.js +3 -3
- package/dist/collection/components/salla-loyalty-program/salla-reward-exchange.js +3 -3
- package/dist/collection/components/salla-maintenance-alert/salla-maintenance-alert.js +1 -1
- package/dist/collection/components/salla-map/salla-map.js +3 -3
- package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-cart.js +1 -1
- package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-details.js +2 -2
- package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-options-modal.js +4 -4
- package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-slider.js +1 -1
- package/dist/collection/components/salla-multiple-bundle-product/salla-multiple-bundle-product.js +1 -1
- package/dist/collection/components/salla-notifications/salla-notification-item.js +1 -1
- package/dist/collection/components/salla-offer-modal/salla-offer-modal.js +1 -1
- package/dist/collection/components/salla-order-details/salla-order-details.js +1 -1
- package/dist/collection/components/salla-order-edit/salla-order-edit-product-card.js +1 -1
- package/dist/collection/components/salla-order-options-modal/apple-pay-order-options.js +84 -0
- package/dist/collection/components/salla-order-options-modal/order-options-gate.js +136 -0
- package/dist/collection/components/salla-order-options-modal/salla-order-options-modal.css +35 -0
- package/dist/collection/components/salla-order-options-modal/salla-order-options-modal.js +282 -0
- package/dist/collection/components/salla-order-summary/salla-order-summary.js +1 -1
- package/dist/collection/components/salla-payments/salla-payments.js +2 -2
- package/dist/collection/components/salla-placeholder/salla-placeholder.js +1 -1
- package/dist/collection/components/salla-price-range/salla-price-range.js +2 -2
- package/dist/collection/components/salla-product-availability/salla-product-availability.js +1 -1
- package/dist/collection/components/salla-product-card/salla-product-card.js +5 -5
- package/dist/collection/components/salla-product-card-embed/salla-product-card-embed.js +1 -1
- package/dist/collection/components/salla-product-options/availability-utils.js +54 -0
- package/dist/collection/components/salla-product-options/salla-product-options.js +105 -31
- package/dist/collection/components/salla-product-size-guide/salla-product-size-guide.js +2 -2
- package/dist/collection/components/salla-quantity-input/salla-quantity-input.js +1 -1
- package/dist/collection/components/salla-quick-buy/salla-quick-buy.js +70 -16
- package/dist/collection/components/salla-review-card/salla-review-card.js +1 -1
- package/dist/collection/components/salla-reviews/salla-reviews.js +1 -1
- package/dist/collection/components/salla-reviews-page/salla-reviews-page.js +1 -1
- package/dist/collection/components/salla-scopes/salla-scopes.js +1 -1
- package/dist/collection/components/salla-search/salla-search.js +5 -5
- package/dist/collection/components/salla-searchable-dropdown/salla-searchable-dropdown.js +4 -4
- package/dist/collection/components/salla-skeleton/salla-skeleton.js +1 -1
- package/dist/collection/components/salla-social/salla-social.js +1 -1
- package/dist/collection/components/salla-social-share/salla-social-share.js +1 -1
- package/dist/collection/components/salla-tabs/salla-tab-content.js +1 -1
- package/dist/collection/components/salla-tabs/salla-tab-header.js +1 -1
- package/dist/collection/components/salla-tabs/salla-tabs.js +1 -1
- package/dist/collection/components/salla-tel-input/salla-tel-input.js +1 -1
- package/dist/collection/components/salla-tooltip/salla-tooltip.js +1 -1
- package/dist/collection/components/salla-user-settings/salla-user-settings.js +1 -1
- package/dist/collection/components/salla-wishlist-actions/salla-wishlist-actions.js +1 -1
- package/dist/components/index.js +2 -2
- package/dist/components/index2.js +2540 -1699
- package/dist/components/index3.js +1699 -2540
- package/dist/components/location.js +2 -2
- package/dist/components/salla-accordion-body2.js +1 -1
- package/dist/components/salla-accordion-head2.js +2 -2
- package/dist/components/salla-accordion2.js +1 -1
- package/dist/components/salla-add-product-button2.js +205 -8
- package/dist/components/salla-alert.js +1 -1
- package/dist/components/salla-badge2.js +1 -1
- package/dist/components/salla-booking-field2.js +1 -1
- package/dist/components/salla-bottom-alert.js +2 -2
- package/dist/components/salla-breadcrumb.js +21 -5
- package/dist/components/salla-bullet-delivery.js +3 -3
- package/dist/components/salla-cart-coupons.js +1 -1
- package/dist/components/salla-cart-summary.js +1 -1
- package/dist/components/salla-color-picker2.js +1 -1
- package/dist/components/salla-comment-form2.js +1 -1
- package/dist/components/salla-conditional-fields2.js +1 -1
- package/dist/components/salla-count-down2.js +1 -1
- package/dist/components/salla-datetime-picker2.js +2 -2
- package/dist/components/salla-file-upload2.js +2 -2
- package/dist/components/salla-filters-widget2.js +2 -2
- package/dist/components/salla-filters.js +1 -1
- package/dist/components/salla-gifting.js +2 -2
- package/dist/components/salla-hook.js +1 -1
- package/dist/components/salla-list-tile2.js +1 -1
- package/dist/components/salla-loading2.js +1 -1
- package/dist/components/salla-localization-modal.js +1 -1
- package/dist/components/salla-loyalty-hero2.js +3 -3
- package/dist/components/salla-loyalty-panel.js +66 -18
- package/dist/components/salla-loyalty-point2.js +6 -6
- package/dist/components/salla-loyalty-points-history.js +1 -1
- package/dist/components/salla-loyalty-prize-item.js +1 -1
- package/dist/components/salla-loyalty-program.js +68 -20
- package/dist/components/salla-loyalty-reward.js +2 -2
- package/dist/components/salla-maintenance-alert.js +1 -1
- package/dist/components/salla-map2.js +4 -4
- package/dist/components/salla-multiple-bundle-product-cart2.js +1 -1
- package/dist/components/salla-multiple-bundle-product-details2.js +2 -2
- package/dist/components/salla-multiple-bundle-product-options-modal2.js +4 -4
- package/dist/components/salla-multiple-bundle-product-slider2.js +1 -1
- package/dist/components/salla-multiple-bundle-product.js +1 -1
- package/dist/components/salla-notification-item2.js +1 -1
- package/dist/components/salla-offer-modal.js +65 -17
- package/dist/components/salla-order-details.js +1 -1
- package/dist/components/salla-order-edit-product-card.js +1 -1
- package/dist/components/salla-order-options-modal.d.ts +11 -0
- package/dist/components/salla-order-options-modal.js +9 -0
- package/dist/components/salla-order-options-modal2.js +303 -0
- package/dist/components/salla-order-summary.js +1 -1
- package/dist/components/salla-payments.js +2 -2
- package/dist/components/salla-placeholder2.js +1 -1
- package/dist/components/salla-price-range2.js +2 -2
- package/dist/components/salla-product-availability2.js +1 -1
- package/dist/components/salla-product-card-embed.js +1 -1
- package/dist/components/salla-product-card2.js +65 -17
- package/dist/components/salla-product-options2.js +120 -30
- package/dist/components/salla-product-size-guide.js +2 -2
- package/dist/components/salla-products-slider2.js +62 -14
- package/dist/components/salla-quantity-input2.js +1 -1
- package/dist/components/salla-quick-buy2.js +233 -18
- package/dist/components/salla-review-card2.js +1 -1
- package/dist/components/salla-reviews-page.js +1 -1
- package/dist/components/salla-reviews.js +1 -1
- package/dist/components/salla-reward-card2.js +1 -1
- package/dist/components/salla-reward-details2.js +67 -19
- package/dist/components/salla-reward-exchange2.js +3 -3
- package/dist/components/salla-scopes.js +1 -1
- package/dist/components/salla-search.js +5 -5
- package/dist/components/salla-searchable-dropdown2.js +4 -4
- package/dist/components/salla-skeleton2.js +1 -1
- package/dist/components/salla-social-share2.js +1 -1
- package/dist/components/salla-social.js +1 -1
- package/dist/components/salla-tab-content2.js +1 -1
- package/dist/components/salla-tab-header2.js +1 -1
- package/dist/components/salla-tabs2.js +1 -1
- package/dist/components/salla-tel-input2.js +2 -2
- package/dist/components/salla-tooltip2.js +1 -1
- package/dist/components/salla-user-settings.js +1 -1
- package/dist/components/salla-wishlist-actions.js +1 -1
- package/dist/esm/{filepond-DLJR7kqO.js → filepond-BOdFx-k4.js} +1 -1
- package/dist/esm/{filepond-plugin-file-poster-BPPxfj_a.js → filepond-plugin-file-poster-B0plGjbP.js} +1 -1
- package/dist/esm/{filepond-plugin-file-validate-size-CCqZAz2o.js → filepond-plugin-file-validate-size-BFnLP4vL.js} +1 -1
- package/dist/esm/{filepond-plugin-file-validate-type-YEjyqpU3.js → filepond-plugin-file-validate-type-CKf0Z8YX.js} +1 -1
- package/dist/esm/{filepond-plugin-image-edit-tiyoM7iJ.js → filepond-plugin-image-edit-lPLGnaWD.js} +1 -1
- package/dist/esm/{filepond-plugin-image-exif-orientation-CESSG4q3.js → filepond-plugin-image-exif-orientation-ad7mrSt5.js} +1 -1
- package/dist/esm/{filepond-plugin-image-preview-CTrGLHaX.js → filepond-plugin-image-preview-D5dtrQjv.js} +1 -1
- package/dist/esm/{functions-iGPmc3ui.js → functions-nnPBSJY6.js} +1 -1
- package/dist/esm/{index-pj-XyI3U.js → index-BtIvUNme.js} +1 -1
- package/dist/esm/{index-Dckjjczv.js → index-CjnbnAFU.js} +10 -14
- package/dist/esm/loader.js +3 -3
- package/dist/esm/salla-accordion-body_2.entry.js +4 -4
- package/dist/esm/salla-accordion_6.entry.js +24 -8
- package/dist/esm/salla-add-product-button_5.entry.js +422 -49
- package/dist/esm/salla-advertisement.entry.js +1 -1
- package/dist/esm/salla-alert_2.entry.js +4 -4
- package/dist/esm/salla-app-install-alert.entry.js +1 -1
- package/dist/esm/salla-apps-icons.entry.js +1 -1
- package/dist/esm/salla-badge.entry.js +2 -2
- package/dist/esm/salla-booking-field_7.entry.js +18 -18
- package/dist/esm/salla-bullet-delivery_2.entry.js +5 -5
- package/dist/esm/salla-cart-coupons.entry.js +2 -2
- package/dist/esm/salla-cart-item-offers_2.entry.js +2 -2
- package/dist/esm/salla-cashback-banner.entry.js +1 -1
- package/dist/esm/salla-comment-form_8.entry.js +5 -5
- package/dist/esm/salla-conditional-offer.entry.js +1 -1
- package/dist/esm/salla-contacts.entry.js +1 -1
- package/dist/esm/salla-cookies-bar.entry.js +1 -1
- package/dist/esm/salla-count-down.entry.js +2 -2
- package/dist/esm/salla-custom-fields.entry.js +1 -1
- package/dist/esm/salla-delivery-promise.entry.js +1 -1
- package/dist/esm/salla-edit-order-button.entry.js +1 -1
- package/dist/esm/salla-filters-widget.entry.js +3 -3
- package/dist/esm/salla-filters.entry.js +2 -2
- package/dist/esm/salla-fulfillment-methods.entry.js +1 -1
- package/dist/esm/salla-gifting.entry.js +3 -3
- package/dist/esm/salla-hook.entry.js +2 -2
- package/dist/esm/salla-infinite-scroll.entry.js +1 -1
- package/dist/esm/salla-installment.entry.js +1 -1
- package/dist/esm/salla-list-tile.entry.js +2 -2
- package/dist/esm/salla-localization-modal.entry.js +2 -2
- package/dist/esm/salla-login-modal.entry.js +1 -1
- package/dist/esm/salla-loyalty-banner.entry.js +2 -2
- package/dist/esm/salla-loyalty-hero_2.entry.js +9 -9
- package/dist/esm/salla-loyalty-panel.entry.js +3 -3
- package/dist/esm/salla-loyalty-points-banner.entry.js +1 -1
- package/dist/esm/salla-loyalty-points-history.entry.js +2 -2
- package/dist/esm/salla-loyalty-prize-item.entry.js +2 -2
- package/dist/esm/salla-loyalty-program.entry.js +3 -3
- package/dist/esm/salla-loyalty-reward.entry.js +4 -4
- package/dist/esm/salla-loyalty.entry.js +1 -1
- package/dist/esm/salla-maintenance-alert.entry.js +2 -2
- package/dist/esm/{salla-map.entry.js → salla-map_2.entry.js} +70 -5
- package/dist/esm/salla-menu.entry.js +1 -1
- package/dist/esm/salla-metadata.entry.js +1 -1
- package/dist/esm/salla-multiple-bundle-product-cart_2.entry.js +4 -4
- package/dist/esm/salla-multiple-bundle-product-options-modal_2.entry.js +6 -6
- package/dist/esm/salla-multiple-bundle-product.entry.js +2 -2
- package/dist/esm/salla-next-order-coupon.entry.js +1 -1
- package/dist/esm/salla-notification-item.entry.js +2 -2
- package/dist/esm/salla-notifications.entry.js +1 -1
- package/dist/esm/salla-offer-modal.entry.js +2 -2
- package/dist/esm/salla-offer.entry.js +1 -1
- package/dist/esm/salla-order-branch.entry.js +1 -1
- package/dist/esm/salla-order-details-multiple-bundle-product.entry.js +1 -1
- package/dist/esm/salla-order-details-options.entry.js +1 -1
- package/dist/esm/salla-order-details.entry.js +2 -2
- package/dist/esm/salla-order-edit-item.entry.js +1 -1
- package/dist/esm/salla-order-edit-product-card.entry.js +2 -2
- package/dist/esm/salla-order-edit.entry.js +1 -1
- package/dist/esm/{salla-product-card_2.entry.js → salla-order-options-modal_3.entry.js} +209 -7
- package/dist/esm/salla-order-summary.entry.js +2 -2
- package/dist/esm/salla-order-totals-card.entry.js +1 -1
- package/dist/esm/salla-orders.entry.js +1 -1
- package/dist/esm/salla-payments.entry.js +3 -3
- package/dist/esm/salla-placeholder.entry.js +2 -2
- package/dist/esm/salla-price-range.entry.js +3 -3
- package/dist/esm/salla-product-card-embed.entry.js +2 -2
- package/dist/esm/salla-product-size-guide.entry.js +3 -3
- package/dist/esm/salla-products-list.entry.js +1 -1
- package/dist/esm/salla-quick-order.entry.js +1 -1
- package/dist/esm/salla-rating-modal.entry.js +1 -1
- package/dist/esm/salla-reward-action_4.entry.js +10 -10
- package/dist/esm/salla-scopes.entry.js +2 -2
- package/dist/esm/salla-search.entry.js +6 -6
- package/dist/esm/salla-skeleton.entry.js +2 -2
- package/dist/esm/salla-slider.entry.js +1 -1
- package/dist/esm/salla-social-share.entry.js +2 -2
- package/dist/esm/salla-social.entry.js +2 -2
- package/dist/esm/salla-tab-content_3.entry.js +4 -4
- package/dist/esm/salla-tiered-offer.entry.js +1 -1
- package/dist/esm/salla-tooltip.entry.js +2 -2
- package/dist/esm/salla-trust-badges.entry.js +1 -1
- package/dist/esm/salla-user-menu.entry.js +1 -1
- package/dist/esm/salla-user-profile.entry.js +1 -1
- package/dist/esm/salla-user-settings.entry.js +2 -2
- package/dist/esm/salla-verify.entry.js +1 -1
- package/dist/esm/salla-wallet.entry.js +1 -1
- package/dist/esm/salla-wishlist-actions.entry.js +2 -2
- package/dist/esm/{tracked-promise-CfOFv_ZQ.js → tracked-promise-DxK5ancc.js} +1 -1
- package/dist/esm/twilight.js +3 -3
- package/dist/esm/{vanilla-picker-BwAhzkb2.js → vanilla-picker-BNKvceoq.js} +1 -1
- package/dist/twilight/{p-193f4672.entry.js → p-01995780.entry.js} +1 -1
- package/dist/twilight/{p-46b75509.entry.js → p-02822e9f.entry.js} +1 -1
- package/dist/twilight/p-080444bb.entry.js +4 -0
- package/dist/twilight/{p-e573c23d.entry.js → p-0d01c327.entry.js} +1 -1
- package/dist/twilight/{p-9ac3d874.entry.js → p-0dcb8111.entry.js} +1 -1
- package/dist/twilight/p-129c20ed.entry.js +4 -0
- package/dist/twilight/{p-e2e38f7d.entry.js → p-15541ca3.entry.js} +1 -1
- package/dist/twilight/p-155d4693.entry.js +4 -0
- package/dist/twilight/{p-85d1767d.entry.js → p-1982cd13.entry.js} +1 -1
- package/dist/twilight/{p-b1d439e7.entry.js → p-1b8c59cf.entry.js} +1 -1
- package/dist/twilight/{p-3100186f.entry.js → p-1dc58168.entry.js} +1 -1
- package/dist/twilight/{p-768b4a83.entry.js → p-1f3480ba.entry.js} +1 -1
- package/dist/twilight/p-241b94a6.entry.js +4 -0
- package/dist/twilight/{p-69e7eb15.entry.js → p-2b75426a.entry.js} +1 -1
- package/dist/twilight/{p-6e2c05e8.entry.js → p-2dc46abc.entry.js} +1 -1
- package/dist/twilight/p-2eaf114e.entry.js +4 -0
- package/dist/twilight/{p-780abf03.entry.js → p-304f3de9.entry.js} +1 -1
- package/dist/twilight/p-35f30553.entry.js +4 -0
- package/dist/twilight/{p-d059046e.entry.js → p-3adacc75.entry.js} +1 -1
- package/dist/twilight/p-3e9f8d3c.entry.js +4 -0
- package/dist/twilight/{p-6543c5eb.entry.js → p-407a0c14.entry.js} +1 -1
- package/dist/twilight/{p-61bcbf9a.entry.js → p-43affbdd.entry.js} +1 -1
- package/dist/twilight/{p-a8a9b151.entry.js → p-456cfec5.entry.js} +1 -1
- package/dist/twilight/{p-3995c76e.entry.js → p-46c8b2d4.entry.js} +1 -1
- package/dist/twilight/{p-badfd153.entry.js → p-474b22b8.entry.js} +1 -1
- package/dist/twilight/{p-9f8a065c.entry.js → p-49c42118.entry.js} +1 -1
- package/dist/twilight/p-5089b72f.entry.js +4 -0
- package/dist/twilight/{p-c907509d.entry.js → p-5229c8aa.entry.js} +1 -1
- package/dist/twilight/{p-5f989a35.entry.js → p-550a91fe.entry.js} +1 -1
- package/dist/twilight/{p-463cf5ea.entry.js → p-594694e9.entry.js} +1 -1
- package/dist/twilight/{p-6ee5c24d.entry.js → p-5a18c6cc.entry.js} +1 -1
- package/dist/twilight/{p-38b5829a.entry.js → p-5aa08192.entry.js} +1 -1
- package/dist/twilight/p-5bda616b.entry.js +4 -0
- package/dist/twilight/p-5d9b57c8.entry.js +4 -0
- package/dist/twilight/{p-c4c3e16f.entry.js → p-6030f1fd.entry.js} +1 -1
- package/dist/twilight/{p-a756b0a4.entry.js → p-62010e29.entry.js} +1 -1
- package/dist/twilight/{p-df72e6a9.entry.js → p-63f1acc7.entry.js} +1 -1
- package/dist/twilight/p-6790943b.entry.js +4 -0
- package/dist/twilight/{p-fe2a4d07.entry.js → p-67d41cbb.entry.js} +1 -1
- package/dist/twilight/{p-9668a8aa.entry.js → p-6c39606a.entry.js} +1 -1
- package/dist/twilight/{p-fca82074.entry.js → p-6d6184c0.entry.js} +1 -1
- package/dist/twilight/{p-f145dc81.entry.js → p-6eab2444.entry.js} +1 -1
- package/dist/twilight/{p-dcc34752.entry.js → p-72a1b702.entry.js} +1 -1
- package/dist/twilight/{p-30fe7a02.entry.js → p-7442c41a.entry.js} +1 -1
- package/dist/twilight/{p-51b4ab80.entry.js → p-7f4d4e3c.entry.js} +1 -1
- package/dist/twilight/{p-be077285.entry.js → p-7fdeec2b.entry.js} +1 -1
- package/dist/twilight/{p-f4f47286.entry.js → p-83cb6915.entry.js} +1 -1
- package/dist/twilight/{p-017500f8.entry.js → p-88bed460.entry.js} +1 -1
- package/dist/twilight/{p-623b0c48.entry.js → p-8d1c4f93.entry.js} +1 -1
- package/dist/twilight/{p-4d2f0573.entry.js → p-8d427c53.entry.js} +1 -1
- package/dist/twilight/p-929e5aed.entry.js +4 -0
- package/dist/twilight/p-956d6683.entry.js +4 -0
- package/dist/twilight/{p-BPasfwVf.js → p-BKKN_hn3.js} +1 -1
- package/dist/twilight/{p-DVCS8qoq.js → p-BT5S72c8.js} +1 -1
- package/dist/twilight/{p-D2W2ygY1.js → p-ByL3FHQ6.js} +1 -1
- package/dist/twilight/p-CBwG3dWv.js +9 -0
- package/dist/twilight/{p-Dckjjczv.js → p-CjnbnAFU.js} +1 -1
- package/dist/twilight/{p-DNU1AEuR.js → p-ClNJhnhN.js} +1 -1
- package/dist/twilight/{p-DzHsJ03K.js → p-Cq2cbPYZ.js} +1 -1
- package/dist/twilight/p-Czf4a8gg.js +9 -0
- package/dist/twilight/{p--Jfvyk1f.js → p-D6Z2cDb0.js} +1 -1
- package/dist/twilight/{p-BgFqaLNN.js → p-DBxZFsVz.js} +1 -1
- package/dist/twilight/{p-BxhAwisc.js → p-DXVmi29t.js} +1 -1
- package/dist/twilight/{p-CHsBLTlN.js → p-DY6O-SiT.js} +1 -1
- package/dist/twilight/{p-1fa5c385.entry.js → p-a1e520d5.entry.js} +1 -1
- package/dist/twilight/{p-0052df8e.entry.js → p-a26fe1e5.entry.js} +1 -1
- package/dist/twilight/{p-0fa958a8.entry.js → p-a30cfade.entry.js} +1 -1
- package/dist/twilight/{p-eaf8f509.entry.js → p-a9090afd.entry.js} +1 -1
- package/dist/twilight/{p-89dae763.entry.js → p-ae2c963f.entry.js} +1 -1
- package/dist/twilight/{p-0a8fdddc.entry.js → p-b18a446a.entry.js} +1 -1
- package/dist/twilight/{p-9196d137.entry.js → p-b1c97472.entry.js} +1 -1
- package/dist/twilight/{p-bc1725dd.entry.js → p-bc6c4c1c.entry.js} +1 -1
- package/dist/twilight/{p-31fca96b.entry.js → p-be10a9c3.entry.js} +1 -1
- package/dist/twilight/p-c26cf3fa.entry.js +4 -0
- package/dist/twilight/{p-092318cc.entry.js → p-c4655810.entry.js} +1 -1
- package/dist/twilight/{p-ba55e58f.entry.js → p-c5211eca.entry.js} +1 -1
- package/dist/twilight/{p-6ce0ab6e.entry.js → p-cbd793c8.entry.js} +1 -1
- package/dist/twilight/{p-052922a0.entry.js → p-cfb9665f.entry.js} +2 -2
- package/dist/twilight/p-d46fb24a.entry.js +4 -0
- package/dist/twilight/{p-a2ff9abd.entry.js → p-d6cb423a.entry.js} +1 -1
- package/dist/twilight/{p-721ae2c4.entry.js → p-d7a2e982.entry.js} +1 -1
- package/dist/twilight/{p-77db23d2.entry.js → p-d9868f07.entry.js} +1 -1
- package/dist/twilight/{p-ba5d1170.entry.js → p-dbe3a5bb.entry.js} +1 -1
- package/dist/twilight/{p-66d2b9e3.entry.js → p-e041fe56.entry.js} +1 -1
- package/dist/twilight/{p-37299c40.entry.js → p-e058b62c.entry.js} +1 -1
- package/dist/twilight/{p-6f63f391.entry.js → p-e07c9a85.entry.js} +1 -1
- package/dist/twilight/{p-ddbffad3.entry.js → p-e1275bf7.entry.js} +1 -1
- package/dist/twilight/{p-7a75c505.entry.js → p-e5d5a6b3.entry.js} +1 -1
- package/dist/twilight/p-e5e6ea75.entry.js +4 -0
- package/dist/twilight/{p-9a6ea758.entry.js → p-e7a255a3.entry.js} +1 -1
- package/dist/twilight/{p-de70e0f6.entry.js → p-ebebcd55.entry.js} +1 -1
- package/dist/twilight/{p-6f86922a.entry.js → p-f0d7247d.entry.js} +1 -1
- package/dist/twilight/{p-3d65f310.entry.js → p-f222bf9f.entry.js} +1 -1
- package/dist/twilight/{p-1da95f6f.entry.js → p-f2594407.entry.js} +1 -1
- package/dist/twilight/{p-21e43f89.entry.js → p-f4235325.entry.js} +1 -1
- package/dist/twilight/p-fafdeea7.entry.js +4 -0
- package/dist/twilight/{p-ef26e3be.entry.js → p-fb7de7c4.entry.js} +1 -1
- package/dist/twilight/{p-1eadcac5.entry.js → p-fc1e3854.entry.js} +1 -1
- package/dist/twilight/{p-7288ff02.entry.js → p-fc72b631.entry.js} +1 -1
- package/dist/twilight/{p-681a053f.entry.js → p-fce2579c.entry.js} +1 -1
- package/dist/twilight/twilight.esm.js +1 -1
- package/dist/types/components/salla-add-product-button/salla-add-product-button.d.ts +2 -0
- package/dist/types/components/salla-breadcrumb/salla-breadcrumb.d.ts +1 -0
- package/dist/types/components/salla-order-options-modal/apple-pay-order-options.d.ts +26 -0
- package/dist/types/components/salla-order-options-modal/order-options-gate.d.ts +23 -0
- package/dist/types/components/salla-order-options-modal/salla-order-options-modal.d.ts +66 -0
- package/dist/types/components/salla-product-options/availability-utils.d.ts +19 -0
- package/dist/types/components/salla-product-options/salla-product-options.d.ts +14 -0
- package/dist/types/components/salla-quick-buy/salla-quick-buy.d.ts +14 -0
- package/dist/types/components.d.ts +62 -0
- package/package.json +5 -5
- package/dist/cjs/salla-progress-bar.cjs.entry.js +0 -73
- package/dist/esm/salla-progress-bar.entry.js +0 -71
- package/dist/twilight/p-05ffde56.entry.js +0 -4
- package/dist/twilight/p-0bf6b9ad.entry.js +0 -4
- package/dist/twilight/p-294a3248.entry.js +0 -4
- package/dist/twilight/p-2b2af618.entry.js +0 -4
- package/dist/twilight/p-45a786cd.entry.js +0 -4
- package/dist/twilight/p-476463ea.entry.js +0 -4
- package/dist/twilight/p-56f4d005.entry.js +0 -4
- package/dist/twilight/p-58bcae28.entry.js +0 -4
- package/dist/twilight/p-5d19859e.entry.js +0 -4
- package/dist/twilight/p-63f20aa0.entry.js +0 -4
- package/dist/twilight/p-83222f33.entry.js +0 -4
- package/dist/twilight/p-84dc489a.entry.js +0 -4
- package/dist/twilight/p-869773d3.entry.js +0 -4
- package/dist/twilight/p-97b74b76.entry.js +0 -4
- package/dist/twilight/p-9dca7f59.entry.js +0 -4
- package/dist/twilight/p-BFEfBkEW.js +0 -9
- package/dist/twilight/p-DWcI2hUr.js +0 -9
- package/dist/twilight/p-ad60969e.entry.js +0 -4
- package/dist/twilight/p-dc9b7a8e.entry.js +0 -4
- package/dist/twilight/p-fc7a1f2f.entry.js +0 -4
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
'use strict';
|
|
5
5
|
|
|
6
|
-
var index = require('./index-
|
|
6
|
+
var index = require('./index-BLZPuy15.js');
|
|
7
7
|
var cart = require('./cart-s-x1Fshk.js');
|
|
8
8
|
var Helper = require('./Helper-CgGR9Qf8.js');
|
|
9
9
|
var bellRing = require('./bell-ring-BfKPinNo.js');
|
|
@@ -19,6 +19,140 @@ var WalletIcon = `<!-- Generated by IcoMoon.io -->
|
|
|
19
19
|
</svg>
|
|
20
20
|
`;
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Order-options gate for the fast-checkout widget — keeps <salla-add-product-button> thin.
|
|
24
|
+
* Intercepts the widget click → runs the order-options modal → injects the result → re-fires the click.
|
|
25
|
+
*/
|
|
26
|
+
const PRODUCT_FORM_SELECTOR = 'form.product-form';
|
|
27
|
+
class OrderOptionsGate {
|
|
28
|
+
constructor(host, productId) {
|
|
29
|
+
this.host = host;
|
|
30
|
+
this.productId = productId;
|
|
31
|
+
/** True on the re-fired click so it passes through instead of re-gating. */
|
|
32
|
+
this.collected = false;
|
|
33
|
+
/** Live PDP price (one onPriceUpdated subscription per widget). */
|
|
34
|
+
this.livePrice = 0;
|
|
35
|
+
}
|
|
36
|
+
/** Attach once to the widget. Returns false when there's no widget (e.g. product cards) so the caller retries. */
|
|
37
|
+
static attach(host, productId) {
|
|
38
|
+
const widget = host.querySelector('salla-mini-checkout-widget');
|
|
39
|
+
if (!widget)
|
|
40
|
+
return false;
|
|
41
|
+
const gate = new OrderOptionsGate(host, String(productId));
|
|
42
|
+
// One subscription per widget (PDP only) — no per-card leak.
|
|
43
|
+
salla.product?.event?.onPriceUpdated?.((response) => {
|
|
44
|
+
gate.livePrice = Number(response?.data?.price) || gate.livePrice;
|
|
45
|
+
});
|
|
46
|
+
widget.addEventListener('click', (event) => gate.handleWidgetClick(event, widget), true);
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
/** Quantity from the same form the widget submits (PRODUCT_FORM_SELECTOR), not the button's nearest form. */
|
|
50
|
+
getSelectedQuantity() {
|
|
51
|
+
try {
|
|
52
|
+
const form = document.querySelector(PRODUCT_FORM_SELECTOR);
|
|
53
|
+
const data = form?.getElementSallaData?.();
|
|
54
|
+
const qty = Number(data instanceof FormData ? data.get('quantity') : data?.quantity);
|
|
55
|
+
if (Number.isFinite(qty) && qty > 0)
|
|
56
|
+
return qty;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// fall through to the attribute
|
|
60
|
+
}
|
|
61
|
+
return Number(this.host.getAttribute('quantity')) || 1;
|
|
62
|
+
}
|
|
63
|
+
async handleWidgetClick(event, widget) {
|
|
64
|
+
if (this.collected) {
|
|
65
|
+
this.collected = false;
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
event.preventDefault();
|
|
69
|
+
event.stopImmediatePropagation();
|
|
70
|
+
if (!await this.validatePdpOptions())
|
|
71
|
+
return;
|
|
72
|
+
if (salla.config.isGuest()) {
|
|
73
|
+
salla.api.auth.requireLoginThen('salla-add-product-button::oo.after-login', () => this.handleWidgetClick(event, widget));
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
widget.classList.add('s-add-product-button-busy');
|
|
77
|
+
let resp;
|
|
78
|
+
try {
|
|
79
|
+
resp = await salla.api.withoutNotifier(() => salla.product.api.getOrderOptions([{ id: this.productId, quantity: this.getSelectedQuantity() }]));
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
salla?.logger?.warn?.('order-options: fetch failed', error);
|
|
83
|
+
widget.classList.remove('s-add-product-button-busy');
|
|
84
|
+
this.resumeWidget(widget);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
widget.classList.remove('s-add-product-button-busy');
|
|
88
|
+
const items = resp?.data?.order_options || [];
|
|
89
|
+
if (!items.length) {
|
|
90
|
+
this.resumeWidget(widget);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const basePrice = this.livePrice > 0
|
|
94
|
+
? this.livePrice
|
|
95
|
+
: Number(resp?.data?.products?.[0]?.price?.amount) || 0;
|
|
96
|
+
const modal = this.ensureModal();
|
|
97
|
+
try {
|
|
98
|
+
const result = await modal.open({ orderOptions: items, basePrice });
|
|
99
|
+
this.injectIntoMini(result?.orderOptions || []);
|
|
100
|
+
this.resumeWidget(widget);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// user dismissed — widget stays blocked, they re-click to retry.
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
async validatePdpOptions() {
|
|
107
|
+
const optionsEl = document.querySelector(`salla-product-options[product-id="${this.productId}"]`);
|
|
108
|
+
if (!optionsEl)
|
|
109
|
+
return true;
|
|
110
|
+
if (typeof optionsEl.validateAndScroll === 'function') {
|
|
111
|
+
return await optionsEl.validateAndScroll();
|
|
112
|
+
}
|
|
113
|
+
if (typeof optionsEl.reportValidity === 'function') {
|
|
114
|
+
return await optionsEl.reportValidity();
|
|
115
|
+
}
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
/** Inject order_options into the next cart-add payload via `cart::before.add.item` (one-shot, scoped to productId). */
|
|
119
|
+
injectIntoMini(orderOptions) {
|
|
120
|
+
if (!orderOptions.length)
|
|
121
|
+
return;
|
|
122
|
+
const productId = this.productId;
|
|
123
|
+
const onceHandler = (eventData) => {
|
|
124
|
+
if (String(eventData?.id) !== String(productId))
|
|
125
|
+
return;
|
|
126
|
+
try {
|
|
127
|
+
eventData?.payload?.set?.('order_options', orderOptions);
|
|
128
|
+
}
|
|
129
|
+
finally {
|
|
130
|
+
salla.event.off('cart::before.add.item', onceHandler);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
salla.event.on('cart::before.add.item', onceHandler);
|
|
134
|
+
}
|
|
135
|
+
ensureModal() {
|
|
136
|
+
let modal = document.querySelector('salla-order-options-modal');
|
|
137
|
+
if (!modal) {
|
|
138
|
+
modal = document.createElement('salla-order-options-modal');
|
|
139
|
+
document.body.appendChild(modal);
|
|
140
|
+
}
|
|
141
|
+
return modal;
|
|
142
|
+
}
|
|
143
|
+
resumeWidget(widget) {
|
|
144
|
+
this.collected = true;
|
|
145
|
+
// Real click target lives in the widget's shadow DOM.
|
|
146
|
+
const innerBtn = widget.shadowRoot?.querySelector?.('.s-fast-checkout-button');
|
|
147
|
+
if (innerBtn) {
|
|
148
|
+
innerBtn.click();
|
|
149
|
+
}
|
|
150
|
+
else if (typeof widget.click === 'function') {
|
|
151
|
+
widget.click();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
22
156
|
const sallaAddProductButtonCss = ":host{display:block}salla-add-product-button[width=wide]{width:100%}";
|
|
23
157
|
|
|
24
158
|
const SallaAddProductButton = class {
|
|
@@ -44,6 +178,8 @@ const SallaAddProductButton = class {
|
|
|
44
178
|
/** Use matchMedia instead of window.innerWidth to avoid forced reflow (Lighthouse/PageSpeed) */
|
|
45
179
|
this.isDesktopViewport = typeof window !== 'undefined' ? window.matchMedia('(min-width: 768px)').matches : true;
|
|
46
180
|
this.viewportMediaQuery = null;
|
|
181
|
+
/** Guards one-time attachment of the order-options gate to the mini-checkout widget. */
|
|
182
|
+
this.orderOptionsGateAttached = false;
|
|
47
183
|
this.onViewportChange = (e) => {
|
|
48
184
|
this.isDesktopViewport = e.matches;
|
|
49
185
|
this.btn?.setText((e.matches && !!this.passedLabel) ? this.passedLabel : this.getLabel());
|
|
@@ -231,6 +367,13 @@ const SallaAddProductButton = class {
|
|
|
231
367
|
});
|
|
232
368
|
}
|
|
233
369
|
componentDidRender() {
|
|
370
|
+
// Wire the order-options gate to the fast-checkout widget once it renders (logic lives in OrderOptionsGate).
|
|
371
|
+
// Only when the merchant enabled order options; otherwise the widget runs the normal fast-checkout flow.
|
|
372
|
+
if (!this.orderOptionsGateAttached && this.productId
|
|
373
|
+
&& salla.config.get('store.settings.order_options.mandatory', false)
|
|
374
|
+
&& OrderOptionsGate.attach(this.host, this.productId)) {
|
|
375
|
+
this.orderOptionsGateAttached = true;
|
|
376
|
+
}
|
|
234
377
|
//if label not passed, get label
|
|
235
378
|
if (!!this.passedLabel && (!this.supportStickyBar || this.isDesktopViewport)) {
|
|
236
379
|
// if passed label, set it
|
|
@@ -576,7 +719,7 @@ const SallaProductAvailability = class {
|
|
|
576
719
|
field.nextElementSibling['innerText'] = '* ' + errorMsg;
|
|
577
720
|
}
|
|
578
721
|
render() {
|
|
579
|
-
return (index.h(index.Host, { key: '
|
|
722
|
+
return (index.h(index.Host, { key: '0779c3aef2637bfcd30ecf110d0cd31d819a82a5', class: "s-product-availability-wrap" }, this.isSubscribedToProduct
|
|
580
723
|
? index.h("div", { class: "s-product-availability-subscribed" }, index.h("span", { innerHTML: bellRing.BellRing, class: "s-product-availability-subs-icon" }), salla.lang.get('pages.products.notify_availability_success'))
|
|
581
724
|
:
|
|
582
725
|
index.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()));
|
|
@@ -598,6 +741,58 @@ const SallaProductAvailability = class {
|
|
|
598
741
|
};
|
|
599
742
|
SallaProductAvailability.style = sallaProductAvailabilityCss;
|
|
600
743
|
|
|
744
|
+
/**
|
|
745
|
+
* Builds a per-detail availability map from SKU-level data.
|
|
746
|
+
*
|
|
747
|
+
* Exported as a pure function so it can be unit-tested independently of the
|
|
748
|
+
* Stencil component (the @State availabilityMap backing-store is not accessible
|
|
749
|
+
* via page.rootInstance in the Stencil mock-doc test environment).
|
|
750
|
+
*
|
|
751
|
+
* Status values:
|
|
752
|
+
* 'available' – at least one in-stock SKU for this detail + current selections
|
|
753
|
+
* 'out_of_stock' – all matching SKUs are out of stock
|
|
754
|
+
* 'impossible' – no SKU intersection exists for this combination
|
|
755
|
+
*
|
|
756
|
+
* skus_availability is always the authoritative source when present; is_out is
|
|
757
|
+
* consulted only as a last resort when a detail has no SKU data at all.
|
|
758
|
+
*/
|
|
759
|
+
function computeAvailabilityMap(optionsData, selectedOptions) {
|
|
760
|
+
const map = {};
|
|
761
|
+
if (!optionsData?.length)
|
|
762
|
+
return map;
|
|
763
|
+
const variantGroups = optionsData.filter(opt => opt.details?.some(d => d.skus_availability && Object.keys(d.skus_availability).length > 0));
|
|
764
|
+
const isSingleGroup = variantGroups.length <= 1;
|
|
765
|
+
for (const optionGroup of variantGroups) {
|
|
766
|
+
const otherSelected = selectedOptions.filter(s => s.option_id !== optionGroup.id);
|
|
767
|
+
for (const detail of optionGroup.details) {
|
|
768
|
+
const skusAvail = detail.skus_availability;
|
|
769
|
+
// No skus_availability data — fall back to is_out as last resort only.
|
|
770
|
+
if (!skusAvail || !Object.keys(skusAvail).length) {
|
|
771
|
+
map[detail.id] = detail.is_out ? 'out_of_stock' : 'available';
|
|
772
|
+
continue;
|
|
773
|
+
}
|
|
774
|
+
const detailSkus = Object.keys(skusAvail).map(Number);
|
|
775
|
+
// No cross-group context yet — evaluate this detail's own SKUs directly.
|
|
776
|
+
if (isSingleGroup || otherSelected.length === 0) {
|
|
777
|
+
map[detail.id] = detailSkus.some(sku => skusAvail[sku]) ? 'available' : 'out_of_stock';
|
|
778
|
+
continue;
|
|
779
|
+
}
|
|
780
|
+
// Intersect this detail's SKUs with those of each other selected detail.
|
|
781
|
+
let candidates = detailSkus;
|
|
782
|
+
for (const other of otherSelected) {
|
|
783
|
+
const otherSkus = new Set(Object.keys(other.skus_availability || {}).map(Number));
|
|
784
|
+
candidates = candidates.filter(sku => otherSkus.has(sku));
|
|
785
|
+
}
|
|
786
|
+
if (!candidates.length) {
|
|
787
|
+
map[detail.id] = 'impossible';
|
|
788
|
+
continue;
|
|
789
|
+
}
|
|
790
|
+
map[detail.id] = candidates.some(sku => skusAvail[sku]) ? 'available' : 'out_of_stock';
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
return map;
|
|
794
|
+
}
|
|
795
|
+
|
|
601
796
|
var FileIcon = `<!-- Generated by IcoMoon.io -->
|
|
602
797
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
|
603
798
|
<title>file-upload</title>
|
|
@@ -630,6 +825,7 @@ const SallaProductOptions = class {
|
|
|
630
825
|
this.availableDigitalCardValues = [];
|
|
631
826
|
this.userInitiatedValidation = false;
|
|
632
827
|
this.isCartMode = false;
|
|
828
|
+
this.availabilityMap = {};
|
|
633
829
|
this.outSkus = [];
|
|
634
830
|
/**
|
|
635
831
|
* Avoid selection of previous default or selected card value option
|
|
@@ -640,6 +836,11 @@ const SallaProductOptions = class {
|
|
|
640
836
|
* The id of the product to which the options are going to be fetched for.
|
|
641
837
|
*/
|
|
642
838
|
this.productId = salla.config.get('page.id');
|
|
839
|
+
/**
|
|
840
|
+
* Strip the wrapper's padding (keeps the background, rounded corners, margin).
|
|
841
|
+
* Used by callers that need the options to sit flush inside their own surface.
|
|
842
|
+
*/
|
|
843
|
+
this.noPadding = false;
|
|
643
844
|
this.handleDonationOptions = (event, detail, type, _option) => {
|
|
644
845
|
// Donating-amount input only: onInput updates price and dispatches native change for form price watcher.
|
|
645
846
|
if (detail === 'custom' && type === 'input') {
|
|
@@ -720,12 +921,14 @@ const SallaProductOptions = class {
|
|
|
720
921
|
*/
|
|
721
922
|
async setOptionsData(optionsData) {
|
|
722
923
|
this.optionsData = optionsData;
|
|
723
|
-
|
|
724
|
-
this.optionsData[0]?.details?.forEach(
|
|
924
|
+
this.outSkus = [];
|
|
925
|
+
this.optionsData[0]?.details?.forEach(detail => {
|
|
725
926
|
Object.entries(detail.skus_availability || {})
|
|
726
|
-
.filter(
|
|
727
|
-
.
|
|
927
|
+
.filter(([, available]) => !available)
|
|
928
|
+
.forEach(([sku]) => this.outSkus.push(Number(sku)));
|
|
728
929
|
});
|
|
930
|
+
this.fillSelectedOptions();
|
|
931
|
+
this.computeAvailability();
|
|
729
932
|
}
|
|
730
933
|
/**
|
|
731
934
|
* Get the current options state, including selected values/details.
|
|
@@ -911,8 +1114,9 @@ const SallaProductOptions = class {
|
|
|
911
1114
|
*/
|
|
912
1115
|
setSelectedSkus() {
|
|
913
1116
|
this.selectedSkus = this.selectedOptions.map(detail => Object.keys(detail.skus_availability || {}))
|
|
914
|
-
.reduce((p, c) => p.filter(e => c.includes(e)), [])
|
|
1117
|
+
.reduce((p, c) => p.filter(e => c.includes(e)), [])
|
|
915
1118
|
.map(sku => Number(sku));
|
|
1119
|
+
this.computeAvailability();
|
|
916
1120
|
}
|
|
917
1121
|
handleRequiredMultipleOptions(option) {
|
|
918
1122
|
if (option.type !== interfaces.DisplayType.MULTIPLE_OPTIONS || !option.required) {
|
|
@@ -1116,7 +1320,7 @@ const SallaProductOptions = class {
|
|
|
1116
1320
|
if (this.optionsData?.length === 0) {
|
|
1117
1321
|
return;
|
|
1118
1322
|
}
|
|
1119
|
-
return (index.h(index.Host, { class:
|
|
1323
|
+
return (index.h(index.Host, { class: { 's-product-options-wrapper': true, 's-product-options-no-padding': this.noPadding } }, index.h("salla-conditional-fields", null, this.optionsData.map((option) => index.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' ?
|
|
1120
1324
|
this.splitterOption()
|
|
1121
1325
|
: index.h("div", { class: { "s-product-options-option": true, "s-product-options-option-booking": option.type === interfaces.DisplayType.BOOKING && salla.url.is_page("cart") }, "data-option-type": option.type, "data-option-required": `${option.required}` }, index.h("label", { htmlFor: this.generateInputId(option.id), class: `s-product-options-option-label ${this.hideLabel(option) ? 's-product-options-option-label-hidden' : ''}` }, index.h("b", null, option.name, option.required && index.h("span", null, " * "), " "), index.h("small", null, option.placeholder)), index.h("div", { class: `s-product-options-option-content ${this.hideLabel(option) || (option.type === interfaces.DisplayType.BOOKING && salla.url.is_page("cart")) ? 's-product-options-option-content-full-width' : ''}` }, this.getDisplayForType(option))))))));
|
|
1122
1326
|
}
|
|
@@ -1171,7 +1375,9 @@ const SallaProductOptions = class {
|
|
|
1171
1375
|
}
|
|
1172
1376
|
fillSelectedOptions() {
|
|
1173
1377
|
this.selectedOptions = this.optionsData.reduce((acc, opt) => {
|
|
1174
|
-
|
|
1378
|
+
// `details` is optional on the Option interface — input-type options
|
|
1379
|
+
// (text/number/date/file) carry no choice list, so guard before filtering.
|
|
1380
|
+
const selectedDetails = (opt.details ?? []).filter(detail => detail.is_selected);
|
|
1175
1381
|
const mappedDetails = selectedDetails.map(detail => ({
|
|
1176
1382
|
...detail,
|
|
1177
1383
|
option_id: opt.id
|
|
@@ -1179,6 +1385,25 @@ const SallaProductOptions = class {
|
|
|
1179
1385
|
return acc.concat(mappedDetails);
|
|
1180
1386
|
}, []);
|
|
1181
1387
|
}
|
|
1388
|
+
/**
|
|
1389
|
+
* Seed `selectedOptions` from API defaults (`is_selected: true`).
|
|
1390
|
+
* componentWillLoad does this only on the cart page; non-cart callers
|
|
1391
|
+
* (e.g. order-options modal) call this after mount to avoid the first
|
|
1392
|
+
* multi-select toggle wiping the pre-selected defaults.
|
|
1393
|
+
* */
|
|
1394
|
+
async seedSelectedOptions() {
|
|
1395
|
+
this.fillSelectedOptions();
|
|
1396
|
+
// A required multi-select renders every checkbox `required`; handleRequiredMultipleOptions
|
|
1397
|
+
// clears that once one is checked, but it only fires on user `change`. After seeding a
|
|
1398
|
+
// pre-selected default we run it for the initial DOM so a defaulted-but-untouched required
|
|
1399
|
+
// multi-select doesn't fail validation and block checkout. Defer to rAF so the seeded
|
|
1400
|
+
// `checked` state is painted before we count it (matches the change-handler pattern above).
|
|
1401
|
+
requestAnimationFrame(() => {
|
|
1402
|
+
this.optionsData
|
|
1403
|
+
?.filter(o => o.type === interfaces.DisplayType.MULTIPLE_OPTIONS && o.required)
|
|
1404
|
+
.forEach(o => this.handleRequiredMultipleOptions(o));
|
|
1405
|
+
});
|
|
1406
|
+
}
|
|
1182
1407
|
async componentDidLoad() {
|
|
1183
1408
|
if (!this.optionsData?.length) {
|
|
1184
1409
|
return;
|
|
@@ -1241,6 +1466,7 @@ const SallaProductOptions = class {
|
|
|
1241
1466
|
this.disableCardValue = false;
|
|
1242
1467
|
this.canDisabled = true;
|
|
1243
1468
|
this.fillSelectedOptions();
|
|
1469
|
+
this.computeAvailability();
|
|
1244
1470
|
}
|
|
1245
1471
|
/**
|
|
1246
1472
|
* Enable user-initiated validation mode so invalid fields will scroll into view
|
|
@@ -1351,22 +1577,14 @@ const SallaProductOptions = class {
|
|
|
1351
1577
|
//and because we are using this inside select option, we need to replace the html currency symbol with the store currency symbol
|
|
1352
1578
|
return detailName.replace('<i class=sicon-sar></i>', salla.config.currency()?.symbol || 'ر.س');
|
|
1353
1579
|
}
|
|
1580
|
+
computeAvailability() {
|
|
1581
|
+
this.availabilityMap = computeAvailabilityMap(this.optionsData || [], this.selectedOptions || []);
|
|
1582
|
+
}
|
|
1354
1583
|
isOptionDetailOut(detail) {
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
//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
|
|
1360
|
-
if (isDetailSelected && this.selectedOptions.length === 1) {
|
|
1361
|
-
return false;
|
|
1362
|
-
}
|
|
1363
|
-
//if current details has sku in the possible outSkus it's out for sure
|
|
1364
|
-
if (isDetailSelected) {
|
|
1365
|
-
//here we will get the possible outSkus for current selected options
|
|
1366
|
-
const outSelectableSkus = this.selectedSkus.filter(sku => this.outSkus.includes(sku));
|
|
1367
|
-
return Object.keys(detail.skus_availability).some(sku => outSelectableSkus.includes(Number(sku)));
|
|
1368
|
-
}
|
|
1369
|
-
return this.selectedOptions.some(option => option.is_out && option.option_id !== detail.option_id);
|
|
1584
|
+
const status = this.availabilityMap[detail.id];
|
|
1585
|
+
// !!detail.is_out guards against TypeScript optimising away `?? false`
|
|
1586
|
+
// for the non-nullable `is_out: boolean` field when the value is actually undefined at runtime.
|
|
1587
|
+
return status !== undefined ? status !== 'available' : !!detail.is_out;
|
|
1370
1588
|
}
|
|
1371
1589
|
/**
|
|
1372
1590
|
* Renders a single input element (radio or checkbox) for an option detail.
|
|
@@ -1379,10 +1597,14 @@ const SallaProductOptions = class {
|
|
|
1379
1597
|
*/
|
|
1380
1598
|
renderInput(type, detail, option, isRequired, name, buttonStyle) {
|
|
1381
1599
|
const id = this.generateUniqueKey(`${type}-${option.id}-${detail.id}`);
|
|
1382
|
-
const
|
|
1600
|
+
const isOutOfStock = this.isOptionDetailOut(detail);
|
|
1383
1601
|
return (index.h("label", { class: {
|
|
1384
|
-
"s-product-options-disabled":
|
|
1385
|
-
|
|
1602
|
+
"s-product-options-disabled": this.canDisabled && isOutOfStock,
|
|
1603
|
+
"s-product-options-option-stock-out": isOutOfStock,
|
|
1604
|
+
} }, index.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) }), index.h("div", { class: {
|
|
1605
|
+
"s-product-options-grid-mode-span": buttonStyle,
|
|
1606
|
+
"s-product-options-disabled": this.canDisabled && isOutOfStock,
|
|
1607
|
+
} }, this.getOptionDetailName(detail))));
|
|
1386
1608
|
}
|
|
1387
1609
|
/**
|
|
1388
1610
|
* Renders a collection of input elements for all details of an option.
|
|
@@ -1455,15 +1677,22 @@ const SallaProductOptions = class {
|
|
|
1455
1677
|
}
|
|
1456
1678
|
//@ts-ignore
|
|
1457
1679
|
colorOption(option) {
|
|
1458
|
-
return (index.h("fieldset", { class: "s-product-options-colors-wrapper" }, option?.details.map((detail) =>
|
|
1680
|
+
return (index.h("fieldset", { class: "s-product-options-colors-wrapper" }, option?.details.map((detail) => {
|
|
1681
|
+
const isOutOfStock = this.isOptionDetailOut(detail);
|
|
1682
|
+
return (index.h("div", { class: {
|
|
1683
|
+
"s-product-options-colors-item": true,
|
|
1684
|
+
"s-product-options-option-stock-out": isOutOfStock,
|
|
1685
|
+
}, key: detail.id }, index.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 }), index.h("label", { htmlFor: this.generateUniqueKey(`color-${this.productId}-${option.id}-${detail.id}`), "data-img-id": detail.option_value }, index.h("span", { style: { backgroundColor: detail.color } }), index.h("div", { innerHTML: this.getOptionDetailName(detail, true, option.type) }))));
|
|
1686
|
+
})));
|
|
1459
1687
|
}
|
|
1460
1688
|
//@ts-ignore
|
|
1461
1689
|
thumbnailOption(option) {
|
|
1462
1690
|
return index.h("div", { class: "s-product-options-thumbnails-wrapper" }, option.details.map((detail) => {
|
|
1463
|
-
|
|
1691
|
+
const isOutOfStock = this.isOptionDetailOut(detail);
|
|
1692
|
+
return index.h("div", { key: detail.id, class: { "s-product-options-option-stock-out": isOutOfStock } }, index.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) }), index.h("label", { htmlFor: this.generateUniqueKey(`option_${this.productId}-${option.id}_${detail.id}`), "data-img-id": detail.option_value, class: "go-to-slide" }, index.h("img", { "data-src": detail.image, src: detail.image, title: detail.name, alt: detail.name }), index.h("span", { innerHTML: check.SICheck, class: "s-product-options-thumbnails-icon" }), isOutOfStock ?
|
|
1464
1693
|
[
|
|
1465
|
-
index.h("small", { key: detail.id
|
|
1466
|
-
this.canDisabled ? index.h("div", { key: detail.id
|
|
1694
|
+
index.h("small", { key: `badge-${detail.id}`, class: "s-product-options-thumbnails-stock-badge" }, this.outOfStockText),
|
|
1695
|
+
this.canDisabled ? index.h("div", { key: `overlay-${detail.id}`, class: "s-product-options-thumbnails-badge-overlay" }) : '',
|
|
1467
1696
|
]
|
|
1468
1697
|
: ''), index.h("p", null, this.getOptionDetailName(detail, false), " "));
|
|
1469
1698
|
}));
|
|
@@ -1478,7 +1707,8 @@ const SallaProductOptions = class {
|
|
|
1478
1707
|
}
|
|
1479
1708
|
countryOption(option) {
|
|
1480
1709
|
return index.h("div", { class: "s-product-options-digital-card-wrapper" }, option.details.map((detail) => {
|
|
1481
|
-
|
|
1710
|
+
const isOutOfStock = this.isOptionDetailOut(detail);
|
|
1711
|
+
return index.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 } }, index.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 } : {}) }), index.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 => {
|
|
1482
1712
|
e.currentTarget.onerror = null;
|
|
1483
1713
|
e.currentTarget.src =
|
|
1484
1714
|
salla.url.cdn('images/globe.svg');
|
|
@@ -2000,7 +2230,15 @@ window.SallaApplePay = {
|
|
|
2000
2230
|
SallaApplePay.session.oncouponcodechanged = SallaApplePay.onCouponCodeChanged;
|
|
2001
2231
|
SallaApplePay.session.onpaymentmethodselected = SallaApplePay.onPaymentMethodSelected;
|
|
2002
2232
|
|
|
2003
|
-
|
|
2233
|
+
// Hook between session creation and begin(). Return truthy to skip
|
|
2234
|
+
// begin() (caller handles it later, e.g. after async work).
|
|
2235
|
+
let skipBegin;
|
|
2236
|
+
if (typeof SallaApplePay.detail.onStartedSession === 'function') {
|
|
2237
|
+
skipBegin = SallaApplePay.detail.onStartedSession(SallaApplePay.session);
|
|
2238
|
+
}
|
|
2239
|
+
if (!skipBegin) {
|
|
2240
|
+
SallaApplePay.session.begin();
|
|
2241
|
+
}
|
|
2004
2242
|
},
|
|
2005
2243
|
onPaymentMethodSelected: async (event) => {
|
|
2006
2244
|
salla.logger.log('🍏 Pay: onPaymentMethodSelected', event);
|
|
@@ -2418,6 +2656,88 @@ if (window.ApplePaySession?.canMakePayments()) {
|
|
|
2418
2656
|
document.querySelectorAll('data-show-if-apple-pay-supported').forEach(element => element.style.display = 'none');
|
|
2419
2657
|
}
|
|
2420
2658
|
|
|
2659
|
+
/**
|
|
2660
|
+
* Order-options helpers for the Apple Pay quick-buy flow — keeps <salla-quick-buy> to thin AP wiring.
|
|
2661
|
+
* Apple Pay resolves options inside the session-started hook (single gesture), so the caller owns
|
|
2662
|
+
* the ApplePaySession and drives it via callbacks.
|
|
2663
|
+
*/
|
|
2664
|
+
/** Get-or-create the singleton order-options modal on <body>. */
|
|
2665
|
+
function ensureOrderOptionsModal() {
|
|
2666
|
+
let modal = document.querySelector('salla-order-options-modal');
|
|
2667
|
+
if (!modal) {
|
|
2668
|
+
modal = document.createElement('salla-order-options-modal');
|
|
2669
|
+
document.body.appendChild(modal);
|
|
2670
|
+
}
|
|
2671
|
+
return modal;
|
|
2672
|
+
}
|
|
2673
|
+
/** Sync PDP-option validity (an `await` would consume the Apple Pay gesture). Skips hidden/disabled inputs. */
|
|
2674
|
+
function reportProductOptionsValiditySync(productId) {
|
|
2675
|
+
const optionsElement = document.querySelector(`salla-product-options[product-id="${productId}"]`);
|
|
2676
|
+
if (!optionsElement)
|
|
2677
|
+
return true;
|
|
2678
|
+
const requiredInputs = optionsElement.querySelectorAll('[required]');
|
|
2679
|
+
let pass = true;
|
|
2680
|
+
requiredInputs.forEach((input) => {
|
|
2681
|
+
if (input.disabled || input.closest('.hidden'))
|
|
2682
|
+
return;
|
|
2683
|
+
if ('reportValidity' in input && !input.reportValidity())
|
|
2684
|
+
pass = false;
|
|
2685
|
+
});
|
|
2686
|
+
return pass;
|
|
2687
|
+
}
|
|
2688
|
+
/** Merge collected order-options into the quick-purchase payload (FormData or plain object). */
|
|
2689
|
+
function appendOrderOptionsToPayload(data, orderOptions) {
|
|
2690
|
+
if (!orderOptions.length)
|
|
2691
|
+
return;
|
|
2692
|
+
if (data && typeof data.append === 'function') {
|
|
2693
|
+
orderOptions.forEach((entry, i) => {
|
|
2694
|
+
data.append(`order_options[${i}][id]`, String(entry.id));
|
|
2695
|
+
data.append(`order_options[${i}][value]`, String(entry.value));
|
|
2696
|
+
});
|
|
2697
|
+
return;
|
|
2698
|
+
}
|
|
2699
|
+
if (data && typeof data === 'object') {
|
|
2700
|
+
data.order_options = orderOptions;
|
|
2701
|
+
}
|
|
2702
|
+
}
|
|
2703
|
+
/**
|
|
2704
|
+
* Fetch order options and, if any, collect them via the modal (apple-pay mode). Callbacks drive the
|
|
2705
|
+
* caller's pre-created session: `beginPendingSession` (no options), `discardPendingSession` (options
|
|
2706
|
+
* found — the modal's AP button starts a fresh one), `onSubmit` (submitted).
|
|
2707
|
+
*/
|
|
2708
|
+
async function resolveApplePayOrderOptions(opts) {
|
|
2709
|
+
let resp;
|
|
2710
|
+
try {
|
|
2711
|
+
resp = await salla.api.withoutNotifier(() => salla.product.api.getOrderOptions([{ id: opts.productId, quantity: opts.quantity }]));
|
|
2712
|
+
}
|
|
2713
|
+
catch (error) {
|
|
2714
|
+
salla?.logger?.warn?.('order-options: fetch failed', error);
|
|
2715
|
+
opts.beginPendingSession();
|
|
2716
|
+
return;
|
|
2717
|
+
}
|
|
2718
|
+
const items = resp?.data?.order_options || [];
|
|
2719
|
+
if (!items.length) {
|
|
2720
|
+
opts.beginPendingSession(); // begin() doesn't need a fresh gesture
|
|
2721
|
+
return;
|
|
2722
|
+
}
|
|
2723
|
+
opts.discardPendingSession(); // drop the unused session; the modal builds a fresh one
|
|
2724
|
+
const basePrice = Number(opts.amount) > 0
|
|
2725
|
+
? Number(opts.amount)
|
|
2726
|
+
: Number(resp?.data?.products?.[0]?.price?.amount) || 0;
|
|
2727
|
+
const modal = ensureOrderOptionsModal();
|
|
2728
|
+
try {
|
|
2729
|
+
await modal.open({
|
|
2730
|
+
orderOptions: items,
|
|
2731
|
+
basePrice,
|
|
2732
|
+
paymentMode: 'apple-pay',
|
|
2733
|
+
onSubmit: opts.onSubmit,
|
|
2734
|
+
});
|
|
2735
|
+
}
|
|
2736
|
+
catch {
|
|
2737
|
+
// dismissed — no live session
|
|
2738
|
+
}
|
|
2739
|
+
}
|
|
2740
|
+
|
|
2421
2741
|
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}";
|
|
2422
2742
|
|
|
2423
2743
|
const SallaQuickBuy = class {
|
|
@@ -2445,32 +2765,82 @@ const SallaQuickBuy = class {
|
|
|
2445
2765
|
* @default {}
|
|
2446
2766
|
*/
|
|
2447
2767
|
this.options = {};
|
|
2768
|
+
/** Modal selections, merged into the quick-purchase payload. */
|
|
2769
|
+
this.collectedOrderOptions = [];
|
|
2770
|
+
/** Flips true after the first onStartedSession so the second dispatch begins. */
|
|
2771
|
+
this.optionsResolved = false;
|
|
2772
|
+
/** PDP price + selected order-option prices (from the modal). */
|
|
2773
|
+
this.applePayAmount = 0;
|
|
2774
|
+
/** Session from the initial gesture; begun later when there are no order options. */
|
|
2775
|
+
this.pendingApplePaySession = null;
|
|
2448
2776
|
this.quickBuy = salla.lang.get('pages.products.buy_now');
|
|
2777
|
+
/** Apple Pay onStartedSession: first call defers begin() to run the OO check; second (resolved) begins. */
|
|
2778
|
+
this.handleApplePaySessionStarted = (session) => {
|
|
2779
|
+
// Order options disabled → let Apple Pay begin normally, as if the feature didn't exist.
|
|
2780
|
+
if (!salla.config.get('store.settings.order_options.mandatory', false))
|
|
2781
|
+
return false;
|
|
2782
|
+
if (this.optionsResolved)
|
|
2783
|
+
return false;
|
|
2784
|
+
this.optionsResolved = true;
|
|
2785
|
+
this.pendingApplePaySession = session;
|
|
2786
|
+
resolveApplePayOrderOptions({
|
|
2787
|
+
productId: this.productId,
|
|
2788
|
+
amount: Number(this.amount),
|
|
2789
|
+
quantity: this.getSelectedQuantity(),
|
|
2790
|
+
beginPendingSession: () => {
|
|
2791
|
+
this.pendingApplePaySession?.begin();
|
|
2792
|
+
this.pendingApplePaySession = null;
|
|
2793
|
+
},
|
|
2794
|
+
discardPendingSession: () => { this.pendingApplePaySession = null; },
|
|
2795
|
+
onSubmit: (selections, total) => {
|
|
2796
|
+
this.collectedOrderOptions = selections;
|
|
2797
|
+
this.applePayAmount = total;
|
|
2798
|
+
this.settlePayment();
|
|
2799
|
+
},
|
|
2800
|
+
});
|
|
2801
|
+
return true;
|
|
2802
|
+
};
|
|
2449
2803
|
salla.lang.onLoaded(() => {
|
|
2450
2804
|
this.quickBuy = salla.lang.get('pages.products.buy_now');
|
|
2451
2805
|
});
|
|
2452
2806
|
}
|
|
2453
|
-
|
|
2454
|
-
// user guest and guest-checkout not enabled
|
|
2807
|
+
quickBuyHandler() {
|
|
2455
2808
|
if (salla.config.isGuest() && !this.isGuestCheckout()) {
|
|
2456
2809
|
this.requireLogin.emit({ productId: this.productId });
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
salla.event.on(afterLoginEvent, () => this.settlePayment());
|
|
2460
|
-
salla.api.auth.setAfterLoginEvent(afterLoginEvent);
|
|
2461
|
-
return salla.auth.event.dispatch('login::open', { withoutReload: true });
|
|
2810
|
+
salla.api.auth.requireLoginThen('salla-quick-buy::user.logged-in', () => this.quickBuyHandler());
|
|
2811
|
+
return;
|
|
2462
2812
|
}
|
|
2463
|
-
|
|
2813
|
+
// Sync validate — AP needs the gesture preserved for new ApplePaySession().
|
|
2814
|
+
if (!this.validatePdpOptionsSync())
|
|
2815
|
+
return;
|
|
2816
|
+
this.optionsResolved = false;
|
|
2817
|
+
this.collectedOrderOptions = [];
|
|
2818
|
+
this.applePayAmount = 0;
|
|
2819
|
+
this.settlePayment();
|
|
2820
|
+
}
|
|
2821
|
+
/** Sync PDP-option validity (preserves the AP gesture); emits + notifies on failure. */
|
|
2822
|
+
validatePdpOptionsSync() {
|
|
2823
|
+
if (reportProductOptionsValiditySync(this.productId))
|
|
2824
|
+
return true;
|
|
2825
|
+
this.validationFailed.emit({ productId: this.productId });
|
|
2826
|
+
salla.error(salla.lang.get('common.messages.required_fields'));
|
|
2827
|
+
return false;
|
|
2464
2828
|
}
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
return
|
|
2829
|
+
/** Read the live PDP quantity from the form so order-options match the real cart line. */
|
|
2830
|
+
getSelectedQuantity() {
|
|
2831
|
+
try {
|
|
2832
|
+
const data = this.host.getElementSallaData?.();
|
|
2833
|
+
const qty = Number(data instanceof FormData ? data.get('quantity') : data?.quantity);
|
|
2834
|
+
return Number.isFinite(qty) && qty > 0 ? qty : 1;
|
|
2471
2835
|
}
|
|
2836
|
+
catch {
|
|
2837
|
+
return 1;
|
|
2838
|
+
}
|
|
2839
|
+
}
|
|
2840
|
+
async settlePayment() {
|
|
2472
2841
|
//use this way to get quantity too
|
|
2473
2842
|
let data = this.host.getElementSallaData();
|
|
2843
|
+
appendOrderOptionsToPayload(data, this.collectedOrderOptions);
|
|
2474
2844
|
// if the store doesn't have Apple Pay , just create a cart and then redirect to check out page
|
|
2475
2845
|
if (!this.isApplePayActive) {
|
|
2476
2846
|
// return salla.product.buyNow(this.productId, data);
|
|
@@ -2488,13 +2858,16 @@ const SallaQuickBuy = class {
|
|
|
2488
2858
|
}
|
|
2489
2859
|
// noinspection TypeScriptValidateJSTypes
|
|
2490
2860
|
salla.event.dispatch('payments::apple-pay.start-transaction', {
|
|
2491
|
-
|
|
2861
|
+
// Prefer the modal's collected total (PDP price + selected OO additional_prices).
|
|
2862
|
+
// Falls back to PDP live amount when no OO modal ran.
|
|
2863
|
+
amount: this.applePayAmount > 0 ? this.applePayAmount : this.amount,
|
|
2492
2864
|
currency: this.currency || 'SAR', // SAR
|
|
2493
2865
|
requiredShippingContactFields: this.getRequiredShippingContactFields(),
|
|
2494
2866
|
shippingMethods: this.isRequireShipping ? [] : undefined,
|
|
2495
2867
|
supportedNetworks: salla.config.get('store.settings.buy_now.networks'),
|
|
2496
2868
|
supportedCountries: salla.config.get('store.settings.buy_now.countries'),
|
|
2497
2869
|
countryCode: salla.config.get('store.store_country') || 'SA',
|
|
2870
|
+
onStartedSession: this.handleApplePaySessionStarted,
|
|
2498
2871
|
validateMerchant: {
|
|
2499
2872
|
url: this.validateHost ? `${this.validateHost}/checkout/applepay/validate` : salla.url.get('checkout/applepay/validate'),
|
|
2500
2873
|
onSuccess: (response) => {
|
|
@@ -2625,7 +2998,7 @@ const SallaQuickBuy = class {
|
|
|
2625
2998
|
});
|
|
2626
2999
|
}
|
|
2627
3000
|
render() {
|
|
2628
|
-
return index.h(index.Host, { key: '
|
|
3001
|
+
return index.h(index.Host, { key: 'fb1bdf862d9b9cea58df14862f7ec9c4be388585' }, this.quickBuyButton());
|
|
2629
3002
|
}
|
|
2630
3003
|
quickBuyButton() {
|
|
2631
3004
|
return index.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 });
|