@vtex/faststore 0.0.10 → 0.0.11
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/CHANGELOG.md +42 -0
- package/README.md +0 -1
- package/dist/actions.json +6 -1
- package/dist/catalog.json +789 -1701
- package/dist/cli/index.d.ts +66 -28
- package/dist/cli/index.js +7371 -512
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/server-runtime.js +41 -60
- package/dist/cli/server-runtime.js.map +1 -1
- package/dist/client.d.ts +3 -3
- package/dist/client.js +2 -2
- package/dist/components.d.ts +63 -57
- package/dist/components.js +60 -54
- package/dist/content-types.json +5785 -754
- package/dist/core/dist/define-component.d.ts +1 -1
- package/dist/core/dist/define-content-type.d.ts +50 -2
- package/dist/core/dist/define-content-type.js +107 -3
- package/dist/core/dist/define-content-type.js.map +1 -1
- package/dist/core/dist/index.d.ts +2 -2
- package/dist/docs/access-code-field.md +1 -1
- package/dist/docs/access-code-sign-in.md +126 -77
- package/dist/docs/account-address-book.md +210 -95
- package/dist/docs/account-menu.md +14 -15
- package/dist/docs/account-saved-cards.md +44 -39
- package/dist/docs/alert-dialog.md +3 -1
- package/dist/docs/avatar.md +4 -2
- package/dist/docs/billing-address.md +99 -30
- package/dist/docs/binding-switcher.md +5 -2
- package/dist/docs/buy-button.md +7 -8
- package/dist/docs/card-entry.md +39 -26
- package/dist/docs/card-summary.md +18 -8
- package/dist/docs/cardholder-document.md +5 -3
- package/dist/docs/carousel.md +5 -4
- package/dist/docs/cart-destination.md +39 -26
- package/dist/docs/cart-item.md +29 -14
- package/dist/docs/cart-totalizer.md +7 -5
- package/dist/docs/cart.md +135 -41
- package/dist/docs/challenge-return.md +135 -0
- package/dist/docs/client-preferences-fieldset.md +10 -5
- package/dist/docs/client-preferences.md +31 -8
- package/dist/docs/client-profile-fieldset.md +20 -6
- package/dist/docs/client-profile.md +12 -3
- package/dist/docs/copy-text.md +9 -7
- package/dist/docs/document-field.md +1 -1
- package/dist/docs/email-field.md +2 -1
- package/dist/docs/email-identification.md +12 -2
- package/dist/docs/footer-copyright.md +4 -2
- package/dist/docs/form.md +54 -18
- package/dist/docs/free-shipping-progress.md +6 -5
- package/dist/docs/identity-edit.md +8 -2
- package/dist/docs/identity-summary.md +18 -5
- package/dist/docs/installments.md +46 -32
- package/dist/docs/my-account-profile.md +16 -11
- package/dist/docs/navigation-link.md +5 -3
- package/dist/docs/order-cancel.md +3 -1
- package/dist/docs/order-delivery-address.md +7 -5
- package/dist/docs/order-delivery-group.md +1 -3
- package/dist/docs/order-details-back.md +1 -1
- package/dist/docs/order-details-header.md +1 -4
- package/dist/docs/order-invoice-download.md +60 -0
- package/dist/docs/order-list-row.md +1 -1
- package/dist/docs/order-list-search.md +13 -20
- package/dist/docs/order-list-views.md +11 -17
- package/dist/docs/order-list.md +12 -5
- package/dist/docs/order-payment.md +9 -7
- package/dist/docs/order-placed-date.md +1 -1
- package/dist/docs/order-placed-payment-summary.md +28 -15
- package/dist/docs/order-placed.md +49 -14
- package/dist/docs/order-progress.md +1 -1
- package/dist/docs/order-status-badge.md +20 -9
- package/dist/docs/order-summary.md +2 -2
- package/dist/docs/order-tracking-link.md +58 -0
- package/dist/docs/payment-method-badges.md +30 -4
- package/dist/docs/payment-methods.md +1 -1
- package/dist/docs/payment.md +36 -17
- package/dist/docs/phone-field.md +4 -4
- package/dist/docs/place-order.md +84 -36
- package/dist/docs/postal-code-field.md +3 -1
- package/dist/docs/pricing.md +21 -23
- package/dist/docs/product-gallery.md +19 -20
- package/dist/docs/product-information.md +13 -9
- package/dist/docs/product-list.md +7 -6
- package/dist/docs/product-shelf.md +0 -1
- package/dist/docs/promotion.md +4 -2
- package/dist/docs/region.md +23 -15
- package/dist/docs/save-card.md +7 -6
- package/dist/docs/saved-cards.md +65 -36
- package/dist/docs/shipping-address.md +57 -21
- package/dist/docs/shipping-simulator.md +53 -15
- package/dist/docs/sign-in-disclosure.md +176 -0
- package/dist/docs/sign-in-form.md +78 -47
- package/dist/docs/sign-in-redirect.md +4 -2
- package/dist/docs/sign-in.md +173 -0
- package/dist/docs/toast.md +15 -4
- package/dist/docs/variant-selector.md +15 -11
- package/dist/graphql/types.d.ts +4 -14
- package/dist/index.d.ts +2 -2
- package/dist/internal/client.d.ts +1 -3
- package/dist/internal/client.js +1 -1
- package/dist/internal/server.d.ts +7 -4
- package/dist/internal/server.js +7 -4
- package/dist/matter/access-code-sign-in/access-code-sign-in.d.ts +250 -66
- package/dist/matter/access-code-sign-in/access-code-sign-in.js +459 -188
- package/dist/matter/access-code-sign-in/access-code-sign-in.js.map +1 -1
- package/dist/matter/account-address-book/account-address-book-delete.d.ts +78 -40
- package/dist/matter/account-address-book/account-address-book-delete.js +86 -50
- package/dist/matter/account-address-book/account-address-book-delete.js.map +1 -1
- package/dist/matter/account-address-book/account-address-book-deliverability.d.ts +21 -4
- package/dist/matter/account-address-book/account-address-book-deliverability.js +45 -17
- package/dist/matter/account-address-book/account-address-book-deliverability.js.map +1 -1
- package/dist/matter/account-address-book/account-address-book-form-parts.d.ts +74 -19
- package/dist/matter/account-address-book/account-address-book-form-parts.js +77 -26
- package/dist/matter/account-address-book/account-address-book-form-parts.js.map +1 -1
- package/dist/matter/account-address-book/account-address-book-profile-notice.d.ts +27 -6
- package/dist/matter/account-address-book/account-address-book-profile-notice.js +55 -28
- package/dist/matter/account-address-book/account-address-book-profile-notice.js.map +1 -1
- package/dist/matter/account-address-book/account-address-book.d.ts +67 -14
- package/dist/matter/account-address-book/account-address-book.js +74 -33
- package/dist/matter/account-address-book/account-address-book.js.map +1 -1
- package/dist/matter/account-address-book/account-address-country-switch.js +3 -3
- package/dist/matter/account-address-book/account-address-country-switch.js.map +1 -1
- package/dist/matter/account-address-book/account-address-country.d.ts +66 -20
- package/dist/matter/account-address-book/account-address-country.js +83 -49
- package/dist/matter/account-address-book/account-address-country.js.map +1 -1
- package/dist/matter/account-address-book/account-address-form-context.d.ts +8 -4
- package/dist/matter/account-address-book/account-address-form-context.js.map +1 -1
- package/dist/matter/account-address-book/account-address-form.d.ts +468 -45
- package/dist/matter/account-address-book/account-address-form.js +518 -155
- package/dist/matter/account-address-book/account-address-form.js.map +1 -1
- package/dist/matter/account-address-book/account-address-record.d.ts +27 -6
- package/dist/matter/account-address-book/account-address-record.js +32 -17
- package/dist/matter/account-address-book/account-address-record.js.map +1 -1
- package/dist/matter/account-menu/account-menu.d.ts +34 -17
- package/dist/matter/account-menu/account-menu.js +46 -54
- package/dist/matter/account-menu/account-menu.js.map +1 -1
- package/dist/matter/account-menu-identity/account-menu-identity.js +1 -1
- package/dist/matter/account-saved-cards/account-saved-cards.d.ts +108 -28
- package/dist/matter/account-saved-cards/account-saved-cards.js +177 -122
- package/dist/matter/account-saved-cards/account-saved-cards.js.map +1 -1
- package/dist/matter/billing-address/billing-address.d.ts +156 -74
- package/dist/matter/billing-address/billing-address.js +227 -156
- package/dist/matter/billing-address/billing-address.js.map +1 -1
- package/dist/matter/breadcrumb/breadcrumb.d.ts +21 -3
- package/dist/matter/breadcrumb/breadcrumb.js +24 -9
- package/dist/matter/breadcrumb/breadcrumb.js.map +1 -1
- package/dist/matter/buy-button/buy-button.d.ts +8 -11
- package/dist/matter/buy-button/buy-button.js +10 -19
- package/dist/matter/buy-button/buy-button.js.map +1 -1
- package/dist/matter/card-entry/card-capture.js +12 -4
- package/dist/matter/card-entry/card-capture.js.map +1 -1
- package/dist/matter/card-entry/card-entry.d.ts +123 -32
- package/dist/matter/card-entry/card-entry.js +348 -221
- package/dist/matter/card-entry/card-entry.js.map +1 -1
- package/dist/matter/cart/cart-namespace.d.ts +7 -1
- package/dist/matter/cart/cart-namespace.js +7 -1
- package/dist/matter/cart/cart-namespace.js.map +1 -1
- package/dist/matter/cart/cart.d.ts +402 -61
- package/dist/matter/cart/cart.js +624 -153
- package/dist/matter/cart/cart.js.map +1 -1
- package/dist/matter/cart-destination/cart-destination.d.ts +30 -19
- package/dist/matter/cart-destination/cart-destination.js +160 -70
- package/dist/matter/cart-destination/cart-destination.js.map +1 -1
- package/dist/matter/cart-item/cart-item.d.ts +144 -17
- package/dist/matter/cart-item/cart-item.js +166 -49
- package/dist/matter/cart-item/cart-item.js.map +1 -1
- package/dist/matter/cart-item-compositions/cart-item-compositions.js +1 -1
- package/dist/matter/cart-item-compositions/cart-item-compositions.js.map +1 -1
- package/dist/matter/cart-item-customizations/cart-item-customizations.js +1 -1
- package/dist/matter/cart-item-customizations/cart-item-customizations.js.map +1 -1
- package/dist/matter/cart-item-discounts/cart-item-discounts.js +1 -1
- package/dist/matter/cart-item-discounts/cart-item-discounts.js.map +1 -1
- package/dist/matter/cart-item-seller-info/cart-item-seller-info.js +1 -1
- package/dist/matter/cart-item-seller-info/cart-item-seller-info.js.map +1 -1
- package/dist/matter/cart-item-variations/cart-item-variations.js +1 -1
- package/dist/matter/cart-item-variations/cart-item-variations.js.map +1 -1
- package/dist/matter/cart-totalizer/cart-totalizer.d.ts +43 -9
- package/dist/matter/cart-totalizer/cart-totalizer.js +46 -17
- package/dist/matter/cart-totalizer/cart-totalizer.js.map +1 -1
- package/dist/matter/challenge-return/challenge-return.d.ts +62 -0
- package/dist/matter/challenge-return/challenge-return.js +241 -0
- package/dist/matter/challenge-return/challenge-return.js.map +1 -0
- package/dist/matter/client-preferences/client-preferences-fieldset.d.ts +86 -17
- package/dist/matter/client-preferences/client-preferences-fieldset.js +126 -54
- package/dist/matter/client-preferences/client-preferences-fieldset.js.map +1 -1
- package/dist/matter/client-preferences/client-preferences.d.ts +50 -7
- package/dist/matter/client-preferences/client-preferences.js +84 -15
- package/dist/matter/client-preferences/client-preferences.js.map +1 -1
- package/dist/matter/client-profile/client-profile.d.ts +44 -9
- package/dist/matter/client-profile/client-profile.js +64 -24
- package/dist/matter/client-profile/client-profile.js.map +1 -1
- package/dist/matter/client-profile-form/client-profile-fieldset.d.ts +119 -22
- package/dist/matter/client-profile-form/client-profile-fieldset.js +161 -73
- package/dist/matter/client-profile-form/client-profile-fieldset.js.map +1 -1
- package/dist/matter/delivery-options/delivery-options-accordion.d.ts +49 -4
- package/dist/matter/delivery-options/delivery-options-accordion.js +67 -14
- package/dist/matter/delivery-options/delivery-options-accordion.js.map +1 -1
- package/dist/matter/delivery-options/delivery-options-controller.d.ts +69 -9
- package/dist/matter/delivery-options/delivery-options-controller.js +80 -14
- package/dist/matter/delivery-options/delivery-options-controller.js.map +1 -1
- package/dist/matter/delivery-options/delivery-options.d.ts +37 -2
- package/dist/matter/delivery-options/delivery-options.js +75 -12
- package/dist/matter/delivery-options/delivery-options.js.map +1 -1
- package/dist/matter/delivery-options/use-delivery-option-selection.d.ts +1 -0
- package/dist/matter/delivery-options/use-delivery-option-selection.js +1 -1
- package/dist/matter/delivery-options/use-delivery-option-selection.js.map +1 -1
- package/dist/matter/email-identification/email-identification.d.ts +25 -3
- package/dist/matter/email-identification/email-identification.js +49 -12
- package/dist/matter/email-identification/email-identification.js.map +1 -1
- package/dist/matter/free-shipping-progress/free-shipping-progress.d.ts +79 -7
- package/dist/matter/free-shipping-progress/free-shipping-progress.js +77 -20
- package/dist/matter/free-shipping-progress/free-shipping-progress.js.map +1 -1
- package/dist/matter/identity-edit/identity-edit.d.ts +52 -10
- package/dist/matter/identity-edit/identity-edit.js +47 -19
- package/dist/matter/identity-edit/identity-edit.js.map +1 -1
- package/dist/matter/identity-summary/identity-summary.d.ts +76 -22
- package/dist/matter/identity-summary/identity-summary.js +95 -45
- package/dist/matter/identity-summary/identity-summary.js.map +1 -1
- package/dist/matter/installments/installments-select.d.ts +98 -16
- package/dist/matter/installments/installments-select.js +156 -48
- package/dist/matter/installments/installments-select.js.map +1 -1
- package/dist/matter/installments/installments.d.ts +96 -16
- package/dist/matter/installments/installments.js +115 -40
- package/dist/matter/installments/installments.js.map +1 -1
- package/dist/matter/installments/use-installments-selection.d.ts +1 -0
- package/dist/matter/installments/use-installments-selection.js +8 -3
- package/dist/matter/installments/use-installments-selection.js.map +1 -1
- package/dist/matter/my-account-profile/my-account-profile.d.ts +358 -103
- package/dist/matter/my-account-profile/my-account-profile.js +370 -174
- package/dist/matter/my-account-profile/my-account-profile.js.map +1 -1
- package/dist/matter/order-cancel/order-cancel.d.ts +65 -19
- package/dist/matter/order-cancel/order-cancel.js +118 -51
- package/dist/matter/order-cancel/order-cancel.js.map +1 -1
- package/dist/matter/order-delivery-address/order-delivery-address.d.ts +8 -18
- package/dist/matter/order-delivery-address/order-delivery-address.js +14 -23
- package/dist/matter/order-delivery-address/order-delivery-address.js.map +1 -1
- package/dist/matter/order-delivery-group/order-delivery-group.d.ts +40 -24
- package/dist/matter/order-delivery-group/order-delivery-group.js +64 -74
- package/dist/matter/order-delivery-group/order-delivery-group.js.map +1 -1
- package/dist/matter/order-details-header/order-details-header.d.ts +32 -15
- package/dist/matter/order-details-header/order-details-header.js +66 -58
- package/dist/matter/order-details-header/order-details-header.js.map +1 -1
- package/dist/matter/order-invoice-download/order-invoice-download.d.ts +78 -0
- package/dist/matter/order-invoice-download/order-invoice-download.js +173 -0
- package/dist/matter/order-invoice-download/order-invoice-download.js.map +1 -0
- package/dist/matter/order-list/order-list.d.ts +164 -19
- package/dist/matter/order-list/order-list.js +229 -87
- package/dist/matter/order-list/order-list.js.map +1 -1
- package/dist/matter/order-list-row/order-list-row.d.ts +6 -1
- package/dist/matter/order-list-row/order-list-row.js +3 -2
- package/dist/matter/order-list-row/order-list-row.js.map +1 -1
- package/dist/matter/order-list-search/order-list-search.d.ts +18 -26
- package/dist/matter/order-list-search/order-list-search.js +30 -69
- package/dist/matter/order-list-search/order-list-search.js.map +1 -1
- package/dist/matter/order-list-views/order-list-views.d.ts +15 -22
- package/dist/matter/order-list-views/order-list-views.js +22 -68
- package/dist/matter/order-list-views/order-list-views.js.map +1 -1
- package/dist/matter/order-payment/order-payment.d.ts +33 -10
- package/dist/matter/order-payment/order-payment.js +44 -39
- package/dist/matter/order-payment/order-payment.js.map +1 -1
- package/dist/matter/order-placed/order-placed-deliveries.d.ts +144 -12
- package/dist/matter/order-placed/order-placed-deliveries.js +115 -40
- package/dist/matter/order-placed/order-placed-deliveries.js.map +1 -1
- package/dist/matter/order-placed/order-placed.d.ts +198 -31
- package/dist/matter/order-placed/order-placed.js +230 -139
- package/dist/matter/order-placed/order-placed.js.map +1 -1
- package/dist/matter/order-placed-date/order-placed-date.d.ts +5 -8
- package/dist/matter/order-placed-date/order-placed-date.js +7 -8
- package/dist/matter/order-placed-date/order-placed-date.js.map +1 -1
- package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.d.ts +90 -17
- package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js +93 -117
- package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js.map +1 -1
- package/dist/matter/order-progress/order-progress.d.ts +19 -8
- package/dist/matter/order-progress/order-progress.js +37 -45
- package/dist/matter/order-progress/order-progress.js.map +1 -1
- package/dist/matter/order-summary/order-summary.d.ts +19 -9
- package/dist/matter/order-summary/order-summary.js +38 -44
- package/dist/matter/order-summary/order-summary.js.map +1 -1
- package/dist/matter/order-tracking-link/order-tracking-link.d.ts +43 -0
- package/dist/matter/order-tracking-link/order-tracking-link.js +107 -0
- package/dist/matter/order-tracking-link/order-tracking-link.js.map +1 -0
- package/dist/matter/payment/payment-card-capture.js +17 -10
- package/dist/matter/payment/payment-card-capture.js.map +1 -1
- package/dist/matter/payment/payment-controller.d.ts +4 -2
- package/dist/matter/payment/payment-controller.js +30 -9
- package/dist/matter/payment/payment-controller.js.map +1 -1
- package/dist/matter/payment/payment-method-badges.js +1 -1
- package/dist/matter/payment/payment.d.ts +69 -19
- package/dist/matter/payment/payment.js +101 -35
- package/dist/matter/payment/payment.js.map +1 -1
- package/dist/matter/payment/use-payment-method-selection.d.ts +25 -4
- package/dist/matter/payment/use-payment-method-selection.js +94 -32
- package/dist/matter/payment/use-payment-method-selection.js.map +1 -1
- package/dist/matter/payment/use-payment-submit-gate.d.ts +14 -3
- package/dist/matter/payment/use-payment-submit-gate.js +47 -8
- package/dist/matter/payment/use-payment-submit-gate.js.map +1 -1
- package/dist/matter/place-order/place-order.d.ts +171 -57
- package/dist/matter/place-order/place-order.js +376 -185
- package/dist/matter/place-order/place-order.js.map +1 -1
- package/dist/matter/pricing/pricing.d.ts +152 -13
- package/dist/matter/pricing/pricing.js +153 -52
- package/dist/matter/pricing/pricing.js.map +1 -1
- package/dist/matter/product-information/product-information.d.ts +27 -4
- package/dist/matter/product-information/product-information.js +32 -15
- package/dist/matter/product-information/product-information.js.map +1 -1
- package/dist/matter/product-list/product-list.d.ts +24 -6
- package/dist/matter/product-list/product-list.js +32 -26
- package/dist/matter/product-list/product-list.js.map +1 -1
- package/dist/matter/product-shelf/product-shelf.d.ts +1 -3
- package/dist/matter/product-shelf/product-shelf.js +2 -15
- package/dist/matter/product-shelf/product-shelf.js.map +1 -1
- package/dist/matter/region/region.d.ts +33 -16
- package/dist/matter/region/region.js +59 -52
- package/dist/matter/region/region.js.map +1 -1
- package/dist/matter/save-card/save-card.d.ts +43 -8
- package/dist/matter/save-card/save-card.js +61 -23
- package/dist/matter/save-card/save-card.js.map +1 -1
- package/dist/matter/saved-cards/saved-cards.d.ts +113 -21
- package/dist/matter/saved-cards/saved-cards.js +349 -77
- package/dist/matter/saved-cards/saved-cards.js.map +1 -1
- package/dist/matter/shipping-address/address-payload.js +25 -0
- package/dist/matter/shipping-address/address-payload.js.map +1 -0
- package/dist/matter/shipping-address/country-descriptors.js +71 -71
- package/dist/matter/shipping-address/country-descriptors.js.map +1 -1
- package/dist/matter/shipping-address/library-country-descriptors.js +136 -0
- package/dist/matter/shipping-address/library-country-descriptors.js.map +1 -0
- package/dist/matter/shipping-address/shipping-address.d.ts +312 -45
- package/dist/matter/shipping-address/shipping-address.js +443 -188
- package/dist/matter/shipping-address/shipping-address.js.map +1 -1
- package/dist/matter/shipping-simulator/shipping-simulator.d.ts +250 -24
- package/dist/matter/shipping-simulator/shipping-simulator.js +257 -51
- package/dist/matter/shipping-simulator/shipping-simulator.js.map +1 -1
- package/dist/matter/sign-in/sign-in.d.ts +108 -0
- package/dist/matter/sign-in/sign-in.js +285 -0
- package/dist/matter/sign-in/sign-in.js.map +1 -0
- package/dist/matter/sign-in-disclosure/sign-in-disclosure.d.ts +81 -0
- package/dist/matter/sign-in-disclosure/sign-in-disclosure.js +232 -0
- package/dist/matter/sign-in-disclosure/sign-in-disclosure.js.map +1 -0
- package/dist/matter/sign-in-form/sign-in-form.d.ts +93 -62
- package/dist/matter/sign-in-form/sign-in-form.js +134 -144
- package/dist/matter/sign-in-form/sign-in-form.js.map +1 -1
- package/dist/particles/binding-switcher/binding-switcher.d.ts +29 -8
- package/dist/particles/binding-switcher/binding-switcher.js +37 -26
- package/dist/particles/binding-switcher/binding-switcher.js.map +1 -1
- package/dist/particles/card-summary/card-summary.d.ts +38 -8
- package/dist/particles/card-summary/card-summary.js +55 -22
- package/dist/particles/card-summary/card-summary.js.map +1 -1
- package/dist/particles/carousel/carousel.d.ts +99 -11
- package/dist/particles/carousel/carousel.js +103 -35
- package/dist/particles/carousel/carousel.js.map +1 -1
- package/dist/particles/copy-text/copy-text.js +5 -15
- package/dist/particles/copy-text/copy-text.js.map +1 -1
- package/dist/particles/dialog/dialog.d.ts +14 -6
- package/dist/particles/dialog/dialog.js +6 -3
- package/dist/particles/dialog/dialog.js.map +1 -1
- package/dist/particles/drawer/drawer.js +1 -1
- package/dist/particles/drawer/drawer.js.map +1 -1
- package/dist/particles/email-field/email-field.d.ts +2 -1
- package/dist/particles/email-field/email-field.js +2 -1
- package/dist/particles/email-field/email-field.js.map +1 -1
- package/dist/particles/footer-link-group/footer-link-group.js +1 -0
- package/dist/particles/footer-link-group/footer-link-group.js.map +1 -1
- package/dist/particles/form/form.d.ts +85 -13
- package/dist/particles/form/form.js +91 -42
- package/dist/particles/form/form.js.map +1 -1
- package/dist/particles/gallery/gallery.d.ts +129 -12
- package/dist/particles/gallery/gallery.js +121 -34
- package/dist/particles/gallery/gallery.js.map +1 -1
- package/dist/particles/order-details-back/order-details-back.d.ts +5 -3
- package/dist/particles/order-details-back/order-details-back.js +8 -10
- package/dist/particles/order-details-back/order-details-back.js.map +1 -1
- package/dist/particles/order-status-badge/order-status-badge.d.ts +3 -3
- package/dist/particles/order-status-badge/order-status-badge.js +4 -20
- package/dist/particles/order-status-badge/order-status-badge.js.map +1 -1
- package/dist/particles/password-field/password-field.d.ts +1 -1
- package/dist/particles/password-field/password-field.js +2 -4
- package/dist/particles/password-field/password-field.js.map +1 -1
- package/dist/particles/phone-field/phone-field.d.ts +4 -4
- package/dist/particles/phone-field/phone-field.js +8 -11
- package/dist/particles/phone-field/phone-field.js.map +1 -1
- package/dist/particles/spinner/spinner.d.ts +24 -4
- package/dist/particles/spinner/spinner.js +25 -9
- package/dist/particles/spinner/spinner.js.map +1 -1
- package/dist/particles/switch/switch.d.ts +4 -1
- package/dist/particles/switch/switch.js +3 -1
- package/dist/particles/switch/switch.js.map +1 -1
- package/dist/particles/toast/toast.d.ts +29 -3
- package/dist/particles/toast/toast.js +34 -10
- package/dist/particles/toast/toast.js.map +1 -1
- package/dist/schema.graphql +164 -56
- package/dist/sdk/address/address-fields.js +4 -4
- package/dist/sdk/address/address-fields.js.map +1 -1
- package/dist/sdk/address/constants.js +1 -6
- package/dist/sdk/address/constants.js.map +1 -1
- package/dist/sdk/address/messages.js +44 -44
- package/dist/sdk/address/messages.js.map +1 -1
- package/dist/sdk/address/postal-code.js +15 -2
- package/dist/sdk/address/postal-code.js.map +1 -1
- package/dist/sdk/address/types.d.ts +5 -3
- package/dist/sdk/address/validate-address.js +3 -3
- package/dist/sdk/address/validate-address.js.map +1 -1
- package/dist/sdk/analytics/use-analytics-actions.d.ts +1 -1
- package/dist/sdk/analytics/use-analytics-actions.js.map +1 -1
- package/dist/sdk/cart/use-cart-actions.js.map +1 -1
- package/dist/sdk/data/index.js +2 -2
- package/dist/sdk/data/reactive-list-item-data-provider.js +2 -2
- package/dist/sdk/generated/gql.js +1 -1
- package/dist/sdk/generated/gql.js.map +1 -1
- package/dist/sdk/generated/graphql.d.ts +20 -5
- package/dist/sdk/generated/graphql.js +6 -0
- package/dist/sdk/generated/graphql.js.map +1 -1
- package/dist/sdk/i18n/format-error-code.js +23 -0
- package/dist/sdk/i18n/format-error-code.js.map +1 -0
- package/dist/sdk/i18n/message-formatter.d.ts +22 -0
- package/dist/sdk/i18n/message-formatter.js +140 -0
- package/dist/sdk/i18n/message-formatter.js.map +1 -0
- package/dist/sdk/i18n/use-message-formatter.d.ts +8 -0
- package/dist/sdk/i18n/use-message-formatter.js +18 -0
- package/dist/sdk/i18n/use-message-formatter.js.map +1 -0
- package/dist/sdk/identity/use-identity-actions.js.map +1 -1
- package/dist/sdk/navigation/redirect.d.ts +2 -0
- package/dist/sdk/navigation/redirect.js +19 -1
- package/dist/sdk/navigation/redirect.js.map +1 -1
- package/dist/sdk/navigation/types.d.ts +13 -0
- package/dist/sdk/payment/bin-format.js +20 -0
- package/dist/sdk/payment/bin-format.js.map +1 -0
- package/dist/sdk/payment/challenge-return.js +37 -0
- package/dist/sdk/payment/challenge-return.js.map +1 -0
- package/dist/sdk/payment/confirmation-last-four.js +39 -0
- package/dist/sdk/payment/confirmation-last-four.js.map +1 -0
- package/dist/sdk/payment/gateway.d.ts +1 -1
- package/dist/sdk/payment/gateway.js +8 -2
- package/dist/sdk/payment/gateway.js.map +1 -1
- package/dist/sdk/payment/operations.d.ts +1 -0
- package/dist/sdk/payment/operations.js +28 -6
- package/dist/sdk/payment/operations.js.map +1 -1
- package/dist/sdk/payment/resumed-purchase.d.ts +1 -0
- package/dist/sdk/payment/resumed-purchase.js +119 -0
- package/dist/sdk/payment/resumed-purchase.js.map +1 -0
- package/dist/sdk/payment/security-code-mask.js +16 -23
- package/dist/sdk/payment/security-code-mask.js.map +1 -1
- package/dist/sdk/payment/submission-registry.js +6 -2
- package/dist/sdk/payment/submission-registry.js.map +1 -1
- package/dist/sdk/payment/use-payment-actions.d.ts +18 -3
- package/dist/sdk/payment/use-payment-actions.js +23 -3
- package/dist/sdk/payment/use-payment-actions.js.map +1 -1
- package/dist/sdk/payment/use-place-order.d.ts +10 -2
- package/dist/sdk/payment/use-place-order.js +138 -76
- package/dist/sdk/payment/use-place-order.js.map +1 -1
- package/dist/sdk/provider/storefront-provider.d.ts +1 -7
- package/dist/sdk/provider/storefront-provider.js +4 -11
- package/dist/sdk/provider/storefront-provider.js.map +1 -1
- package/dist/sdk/seo/entity-landing.d.ts +24 -0
- package/dist/sdk/seo/entity-landing.js +30 -0
- package/dist/sdk/seo/entity-landing.js.map +1 -0
- package/dist/sdk/seo/page-alternates.d.ts +3 -2
- package/dist/sdk/seo/page-alternates.js +4 -2
- package/dist/sdk/seo/page-alternates.js.map +1 -1
- package/dist/sdk/seo/search-landing.d.ts +42 -0
- package/dist/sdk/seo/search-landing.js +85 -0
- package/dist/sdk/seo/search-landing.js.map +1 -0
- package/dist/sdk/session/mock-session.d.ts +9 -0
- package/dist/sdk/session/mock-session.js +31 -0
- package/dist/sdk/session/mock-session.js.map +1 -0
- package/dist/sdk/session/read-server-session.d.ts +3 -0
- package/dist/sdk/session/read-server-session.js +5 -0
- package/dist/sdk/session/read-server-session.js.map +1 -1
- package/dist/sdk/session/return-path-segment.d.ts +10 -0
- package/dist/sdk/session/return-path-segment.js +15 -0
- package/dist/sdk/session/return-path-segment.js.map +1 -0
- package/dist/sdk/session/use-session-actions.js.map +1 -1
- package/dist/sdk/shipping/use-cart-shipping-simulation.js.map +1 -1
- package/dist/sdk/shipping/use-shipping-actions.js.map +1 -1
- package/dist/sdk/shipping/use-shipping-simulation.js.map +1 -1
- package/dist/utils/safe-href.d.ts +2 -0
- package/package.json +4 -3
- package/skills/storefront-asset/SKILL.md +2 -2
- package/skills/storefront-asset/references/api-side.md +27 -14
- package/skills/storefront-asset/references/findings.md +5 -2
- package/src/styles/tailwind.css +8 -0
- package/dist/matter/shipping-address/country-descriptors.d.ts +0 -1
- package/dist/message-locales.json +0 -7
- package/dist/sdk/i18n/client.d.ts +0 -4
- package/dist/sdk/i18n/client.js +0 -4
- package/dist/sdk/i18n/locales.d.ts +0 -8
- package/dist/sdk/i18n/locales.js +0 -57
- package/dist/sdk/i18n/locales.js.map +0 -1
- package/dist/sdk/i18n/messages/en-US.js +0 -183
- package/dist/sdk/i18n/messages/en-US.js.map +0 -1
- package/dist/sdk/i18n/messages/en-US.json +0 -178
- package/dist/sdk/i18n/messages/en-US.json.d.ts +0 -182
- package/dist/sdk/i18n/messages/es-ES.js +0 -183
- package/dist/sdk/i18n/messages/es-ES.js.map +0 -1
- package/dist/sdk/i18n/messages/es-ES.json +0 -178
- package/dist/sdk/i18n/messages/pt-BR.js +0 -183
- package/dist/sdk/i18n/messages/pt-BR.js.map +0 -1
- package/dist/sdk/i18n/messages/pt-BR.json +0 -178
- package/dist/sdk/i18n/provider.d.ts +0 -1
- package/dist/sdk/i18n/provider.js +0 -30
- package/dist/sdk/i18n/provider.js.map +0 -1
- package/dist/sdk/i18n/server.d.ts +0 -28
- package/dist/sdk/i18n/server.js +0 -59
- package/dist/sdk/i18n/server.js.map +0 -1
- package/dist/utils/resolve-authored-copy.js +0 -18
- package/dist/utils/resolve-authored-copy.js.map +0 -1
- package/dist/utils/substitute-template.js +0 -33
- package/dist/utils/substitute-template.js.map +0 -1
|
@@ -50,8 +50,8 @@ CartTotalizerRoot ← reactive data provider (totalizers + total)
|
|
|
50
50
|
|---|---|---|
|
|
51
51
|
| `CartTotalizerRoot` | `$data` | Provides `CartTotalizerContext` and `CartTotalValueContext`; lines format from the active storefront context |
|
|
52
52
|
| `CartTotalizerLine` | `totalizerId`, `label?`, `variant?`, `zeroLabel?` | `variant="discount"` auto-hides when the amount is numerically zero, whatever its wire form (`0`, `"0.00"`, `"-0.00"`); in any variant the line renders nothing when the amount is not a finite number |
|
|
53
|
-
| `CartDiscountLine` | `
|
|
54
|
-
| `CartMarkdownLine` | `
|
|
53
|
+
| `CartDiscountLine` | `$content.otherLabel` | Itemized discount breakdown: one line per promotion/coupon plus the residual. Self-hides when empty. Owns its own `Cart.discounts` slice |
|
|
54
|
+
| `CartMarkdownLine` | `$content.label` | Aggregate item-level catalog markdown (`Σ listPrice − price`): a single negative line, self-hides at zero. Distinct money from the `Discounts` totalizer / `CartDiscountLine` — may be shown alongside them. Owns its own `Cart.itemMarkdownTotal` slice |
|
|
55
55
|
| `CartTotal` | `label?` | The single root-agnostic grand total; reads `CartTotalValueContext` provided by either root. Set `label` to render a labeled total row (e.g. "Total") |
|
|
56
56
|
|
|
57
57
|
---
|
|
@@ -75,8 +75,9 @@ storefront context wherever it renders.
|
|
|
75
75
|
single "Discounts" figure is enough.
|
|
76
76
|
|
|
77
77
|
The `name` a promotion or coupon carries comes from the platform; the API leaves the residual (and any
|
|
78
|
-
unnamed promotion) without a name, so `otherLabel`
|
|
79
|
-
|
|
78
|
+
unnamed promotion) without a name, so the `otherLabel` message (content type `cart-discount-line`)
|
|
79
|
+
supplies the label for those. It reads only from `$content`: an unauthored message renders empty and logs
|
|
80
|
+
`message.missing`. A store without CMS authors it on the element, as below.
|
|
80
81
|
|
|
81
82
|
Style hooks: `data-fs-cart-discount-lines` on the group, and per row
|
|
82
83
|
`data-fs-cart-discount-line` (with `data-fs-cart-discount-line-kind` = `promotion` / `coupon` / `other`),
|
|
@@ -125,7 +126,8 @@ from the running total. What you must not do is interleave it as a plain negativ
|
|
|
125
126
|
subtotal and the total, because it is not part of that sum. The `ItemMarkdown` story shows the
|
|
126
127
|
list-price framing.
|
|
127
128
|
|
|
128
|
-
The `label`
|
|
129
|
+
The `label` message (content type `cart-markdown-line`) words the row. It reads only from `$content`: an
|
|
130
|
+
unauthored message renders empty and logs `message.missing`.
|
|
129
131
|
|
|
130
132
|
Style hooks: `data-fs-cart-markdown-line` on the row (also `data-fs-text`), with
|
|
131
133
|
`data-fs-cart-markdown-line-label` and `data-fs-cart-markdown-line-value`.
|
package/dist/docs/cart.md
CHANGED
|
@@ -55,7 +55,7 @@ Layout
|
|
|
55
55
|
|
|
56
56
|
Cart **read** particles (`CartCount`, `CartTotal`, `CartList`, and the `CartItem*` line-item particles) read from `CartRoot` via the `useCart()` hook and throw at render time if no `CartRoot` ancestor exists. The layout's instance satisfies that requirement for every page it hosts — a provider declared on the layout satisfies a consumer declared on the page.
|
|
57
57
|
|
|
58
|
-
Cart **write** consumers (`BuyButtonButton`, `ProductCardAddToCart`, `CartItemQuantity`, `CartItemRemove`) declare `actions: { cart: [...] }` and dispatch via `$actions.cart.*`. They need no `CartRoot` ancestor; the compiler wraps each one with a provider that supplies the handlers. `CartError` surfaces cart write errors from a module-level reactive var, so it too works without reading the cart context.
|
|
58
|
+
Cart **write** consumers (`BuyButtonButton`, `ProductCardAddToCart`, `CartItemQuantity`, `CartItemRemove`) declare `actions: { cart: [...] }` and dispatch via `$actions.cart.*`. They need no `CartRoot` ancestor; the compiler wraps each one with a provider that supplies the handlers. `CartError` surfaces cart write errors from a module-level reactive var, so it too works without reading the cart context. It words the first error by its code from the `$content` of `cart-error`: `invalidQuantityMessage` (`INVALID_QUANTITY`), `itemNotFoundMessage` (`ITEM_NOT_FOUND`), and `genericErrorMessage` for `NETWORK_ERROR` and every refusal the shopper cannot act on (`MISSING_CART_CONTEXT`, `CART_NOT_FOUND`, `INVALID_VARIANT_ID`, `INVALID_SELLER_ID`, `NO_LINE_IDS_PROVIDED`, `UPSTREAM_ERROR`). A code it does not know (one a newer server added) shows `genericErrorMessage` and logs `message.unknown-code`; composed `children` replace the message.
|
|
59
59
|
|
|
60
60
|
---
|
|
61
61
|
|
|
@@ -107,39 +107,60 @@ locale and currency), not from props — there is nothing to author here.
|
|
|
107
107
|
|
|
108
108
|
### CartItemDiscountPercentage
|
|
109
109
|
|
|
110
|
-
Per-line discount badge. Renders the integer discount percentage of the current cart line — the `listPrice`-vs-`sellingPrice` difference (e.g. `-20%`) — so a shopper sees how deep each line's promotion is. It reads the line from the
|
|
110
|
+
Per-line discount badge. Renders the integer discount percentage of the current cart line — the `listPrice`-vs-`sellingPrice` difference (e.g. `-20%`) — so a shopper sees how deep each line's promotion is. It reads the line from the line context that `CartItemRoot` provides and **renders null when the line has no discount** (`sellingPrice >= listPrice`), so it only ever appears on promotional lines. Place it alongside `CartItemPrice` and `CartItemListPrice` in the line-item template. Must be inside `CartItemRoot`, which can sit under `CartList`, `CartAvailableItems` or `CartUnavailableItems`.
|
|
111
111
|
|
|
112
112
|
The percentage matches the PDP `PricingDiscount` badge for the same product — both round with `Math.round` — so a 19.5% discount shows `-20%` on both surfaces.
|
|
113
113
|
|
|
114
|
-
|
|
|
115
|
-
|
|
116
|
-
| `template` |
|
|
114
|
+
| `$content` field | Notes |
|
|
115
|
+
|------------------|-------|
|
|
116
|
+
| `template` | ICU message; the `percentage` argument is the integer percent (e.g. `"-{percentage}%"` or `"{percentage}% OFF"`) |
|
|
117
117
|
|
|
118
118
|
---
|
|
119
119
|
|
|
120
120
|
### CartEmptyMessage
|
|
121
121
|
|
|
122
|
-
The empty-cart message, rendered as a paragraph (`data-fs-cart-empty-message`, plus the `data-fs-text` identity). Place it inside `CartEmpty`. The
|
|
122
|
+
The empty-cart message, rendered as a paragraph (`data-fs-cart-empty-message`, plus the `data-fs-text` identity). Place it inside `CartEmpty`. The text comes from the `$content` field `text` of the `cart-empty-message` content model; a blank or missing message renders nothing (a missing one also logs `message.missing`). It carries **no layout** — group and space it with `Container`.
|
|
123
|
+
|
|
124
|
+
| `$content` field | Notes |
|
|
125
|
+
|------------------|-------|
|
|
126
|
+
| `text` | ICU message, e.g. `"Your cart is empty"` |
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
### CartUnavailableLabel
|
|
131
|
+
|
|
132
|
+
The heading of the unavailable section, rendered as a paragraph (`data-fs-cart-unavailable-label`, plus the `data-fs-text` identity). Compose one inside `CartUnavailableSection` as its header; group it with an `Icon` in a `Container` when the header carries an icon. The text comes from the `$content` field `text` of the `cart-unavailable-label` content model; a blank or missing message renders nothing (a missing one also logs `message.missing`). It also hides itself when no line is unavailable, wherever it is placed.
|
|
133
|
+
|
|
134
|
+
| `$content` field | Notes |
|
|
135
|
+
|------------------|-------|
|
|
136
|
+
| `text` | ICU message, e.g. `"Unavailable"` |
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
### CartAllUnavailableMessage
|
|
141
|
+
|
|
142
|
+
The warning that nothing in the cart can be bought. Its root is a `div` with `role="alert"` (`data-fs-cart-all-unavailable-message`) holding a paragraph with the copy (`data-fs-cart-all-unavailable-message-text`, plus `data-fs-text`) and, when configured, one link after it (`data-fs-cart-all-unavailable-message-link`). Compose it inside `CartAllUnavailable`. The copy is the `$content` field `text` of the `cart-all-unavailable-message` content model; a blank or missing message renders nothing, link included (a missing one also logs `message.missing`). Its `CartAllUnavailable` then hides too. It also hides itself whenever the cart still has something to buy, wherever it is placed.
|
|
123
143
|
|
|
124
144
|
| Prop | Type | Default | Notes |
|
|
125
145
|
|------|------|---------|-------|
|
|
126
|
-
| `
|
|
146
|
+
| `linkText` | string | none | Link label. A non-blank CMS `linkText` wins over it |
|
|
147
|
+
| `linkHref` | link | none | Link destination, a page reference in a store schema. A non-blank CMS `linkHref` wins over it |
|
|
127
148
|
|
|
128
|
-
**Content:** declares the `cart-
|
|
149
|
+
**Content:** declares the `cart-all-unavailable-message` content model: the message field `text`, and the optional editorial `linkText` and `linkHref`. The link fields are not messages: the link is optional, and a missing message field is an error.
|
|
129
150
|
|
|
130
151
|
---
|
|
131
152
|
|
|
132
153
|
### CartContinueShopping
|
|
133
154
|
|
|
134
|
-
The control that returns the shopper to browsing, rendered as a button (`data-fs-cart-continue-shopping`, alongside `data-fs-drawer-close` and `data-fs-button`). It **dismisses the overlay and dispatches no cart write**. Composed children
|
|
155
|
+
The control that returns the shopper to browsing, rendered as a button (`data-fs-cart-continue-shopping`, alongside `data-fs-drawer-close` and `data-fs-button`). It **dismisses the overlay and dispatches no cart write**. Composed children are the button content, which is how an icon goes inside the button; without them the text is the `$content` field `label`.
|
|
135
156
|
|
|
136
157
|
It is the drawer's own close control, so it **requires a `DrawerRoot` ancestor** — on a cart page with no drawer, compose a `NavigationLink` back to browsing instead. Placing it outside a drawer fails the render rather than degrading.
|
|
137
158
|
|
|
138
|
-
|
|
|
139
|
-
|
|
140
|
-
| `label` |
|
|
159
|
+
| `$content` field | Notes |
|
|
160
|
+
|------------------|-------|
|
|
161
|
+
| `label` | ICU message, e.g. `"Continue shopping"`. Formatted only when no children are composed; blank renders nothing |
|
|
141
162
|
|
|
142
|
-
**Content:** declares the `cart-continue-shopping` content model (one `label`
|
|
163
|
+
**Content:** declares the `cart-continue-shopping` content model (one `label` field). Authored independently of the message, so publishing one does not require restating the other.
|
|
143
164
|
|
|
144
165
|
---
|
|
145
166
|
|
|
@@ -151,17 +172,17 @@ The applied coupons are a **list of chips (1..N)**, not a single-coupon slot —
|
|
|
151
172
|
|
|
152
173
|
| Component | Element | Purpose | Notes |
|
|
153
174
|
|-----------|---------|---------|-------|
|
|
154
|
-
| `CartCouponForm` | `form` | Coupon code input + apply button | Dispatches `$actions.cart.applyCoupon`. Disables input + button and exposes `data-fs-cart-coupon-pending` while an apply is in flight; clears the input on success. Raises one success toast titled `appliedMessage`
|
|
155
|
-
| `CartAppliedCoupons` | `div` | Renders one chip per applied coupon | Reads `cart.appliedCoupons`; renders nothing when empty (no container). Each chip shows the `code` inline and a `CartCouponRemove
|
|
175
|
+
| `CartCouponForm` | `form` | Coupon code input + apply button | Dispatches `$actions.cart.applyCoupon`. Disables input + button and exposes `data-fs-cart-coupon-pending` while an apply is in flight; clears the input on success. Its `$content` (`cart-coupon-form`) carries `placeholder` (also the input's accessible name), `applyLabel` and `appliedMessage`; composed children replace the input and button. Raises one success toast titled `appliedMessage` only when the apply returns no errors and the submitted code comes back matched (compared ignoring case); an unmatched code, an error or a blank or missing `appliedMessage` raises none. The toast still shows when `CartCouponEmpty` removes the form, and nothing shows without a `ToastProvider` (the apply still works). |
|
|
176
|
+
| `CartAppliedCoupons` | `div` | Renders one chip per applied coupon | Reads `cart.appliedCoupons`; renders nothing when empty (no container). Each chip shows the `code` inline and a `CartCouponRemove`; the built-in one is named by the `$content` field `removeLabel` (`cart-applied-coupons`, an ICU message with a `code` argument, e.g. `"Remove coupon {code}"`). An applied-but-no-discount coupon (`isUnmatchedCondition`) is exposed via the `data-fs-cart-coupon-unmatched` hook for the store to style/label (no baked copy); compose `CartCouponUnmatched` in the chip template for a text notice. A chip template replaces the built-in remove control, so one that composes the notice must also compose `CartCouponRemove`. |
|
|
156
177
|
| `CartCouponRemove` | `button` | The per-chip remove control (the X) | Dispatches `$actions.cart.removeCoupon` for the chip's code. Use inside a `CartAppliedCoupons` chip, which supplies the code via context. |
|
|
157
|
-
| `CartCouponError` | `div` (`role="alert"`) | Inline coupon error banner | Reads a **dedicated** coupon error channel, separate from `CartError` (which carries item-write errors). Renders the first error, or nothing when there are none. |
|
|
178
|
+
| `CartCouponError` | `div` (`role="alert"`) | Inline coupon error banner | Reads a **dedicated** coupon error channel, separate from `CartError` (which carries item-write errors). Renders the first error, or nothing when there are none, worded by its code from the `$content` of `cart-coupon-error`: `couponNotFoundMessage` (`COUPON_NOT_FOUND`), `couponExpiredMessage` (`COUPON_EXPIRED`), `couponNotCombinedMessage` (`COUPON_NOT_COMBINED`), and `genericErrorMessage` for `NETWORK_ERROR`, `MISSING_CART_CONTEXT` and `CART_NOT_FOUND`. A code it does not know (one a newer server added) shows `genericErrorMessage` and logs `message.unknown-code`; composed `children` replace the message. |
|
|
158
179
|
| `CartCouponEmpty` | `div` | Coupon entry gate | Renders its children only while the resolved cart has no applied coupon; renders nothing while the cart loads or once any coupon (matched or not) is applied. Copy-free, no schema props. Wrap the coupon entry in it for a single-coupon store; omit it for a multi-coupon store. |
|
|
159
|
-
| `CartCouponUnmatched` | `output` | Per-chip notice for an unmatched coupon | Reads the chip's coupon from context; renders the `message`
|
|
160
|
-
| `CartCouponSavings` | `span` | Per-chip amount a fixed-amount coupon took off | Reads the chip's coupon from context and sums the `COUPON` entries of `cart.discounts` named after its code; renders the amount with the currency's own minus sign (`-R$ 20,00`), and nothing for an unmatched, free-shipping or percentage coupon (the API attributes no amount to them), outside a chip, or when the sum is not above zero. `template` words the text
|
|
180
|
+
| `CartCouponUnmatched` | `output` | Per-chip notice for an unmatched coupon | Reads the chip's coupon from context; renders the `$content` field `message` (`cart-coupon-unmatched`) only while that coupon has `isUnmatchedCondition`, and nothing when it matches, outside a chip, or when the message is blank or missing. `children` render instead of the message. Never removes the coupon. Not part of the built-in chip: compose it next to `CartCouponRemove`. |
|
|
181
|
+
| `CartCouponSavings` | `span` | Per-chip amount a fixed-amount coupon took off | Reads the chip's coupon from context and sums the `COUPON` entries of `cart.discounts` named after its code; renders the amount with the currency's own minus sign (`-R$ 20,00`), and nothing for an unmatched, free-shipping or percentage coupon (the API attributes no amount to them), outside a chip, or when the sum is not above zero. The `$content` field `template` (`cart-coupon-savings`) words the text as an ICU message whose one argument, `{amount}`, is the formatted saving (e.g. `{amount}` or `Economia de {amount}`); an unknown argument renders the message as authored and logs an error, and a blank or missing message renders empty and logs `message.missing`. The chip already shows the code before its children. Not part of the built-in chip: compose it next to `CartCouponRemove`. |
|
|
161
182
|
|
|
162
183
|
`CartAppliedCoupons` repeats its `children` once per applied coupon (like `CartList` repeats per item): place the chip template — an optional code element plus a `CartCouponRemove` — as its children, and it is cloned per coupon with the coupon supplied via context. Omit `children` to get a built-in chip (code inline + a remove X). A template that composes `CartCouponUnmatched` or `CartCouponSavings` must also compose `CartCouponRemove`, because composed children replace the built-in remove control.
|
|
163
184
|
|
|
164
|
-
**Errors:** coupon apply/remove `userErrors` (e.g. `COUPON_NOT_FOUND`, `COUPON_EXPIRED`) publish to a dedicated reactive var that only `CartCouponError` reads, so coupon feedback never collides with item-write errors shown by `CartError`. A code rejected while another coupon is applied returns `COUPON_NOT_COMBINED` (whatever the account allows)
|
|
185
|
+
**Errors:** coupon apply/remove `userErrors` (e.g. `COUPON_NOT_FOUND`, `COUPON_EXPIRED`) publish to a dedicated reactive var that only `CartCouponError` reads, so coupon feedback never collides with item-write errors shown by `CartError`. A code rejected while another coupon is applied returns `COUPON_NOT_COMBINED` (whatever the account allows), and the applied coupons stay; `couponNotCombinedMessage` words it, so write it without claiming the code is unknown or cannot be combined. `cartCouponErrorsVar` is cleared when a coupon write starts (item writes and `validate` leave it alone) and when a CartRoot mounts, never on re-render, so a rejected code from a layout mini-cart form does not show under the Cart page's coupon form. Two cases stay:
|
|
165
186
|
|
|
166
187
|
- A coupon apply still in flight when a CartRoot mounts shows its failure after the clear, for example from a layout mini-cart form (known limitation).
|
|
167
188
|
- An error from the Cart page's form stays visible in a persistent `CartCouponError` after the shopper leaves (known limitation).
|
|
@@ -281,8 +302,8 @@ This is pure composition with three mutually-exclusive self-hide branches — `C
|
|
|
281
302
|
|
|
282
303
|
The empty panel's copy lives in two leaves, one string each, so the panel is a composition rather than a configured block:
|
|
283
304
|
|
|
284
|
-
- **`CartEmptyMessage`** renders the message as a paragraph (`data-fs-cart-empty-message`). The
|
|
285
|
-
- **`CartContinueShopping`** renders the control that returns the shopper to browsing (`data-fs-cart-continue-shopping`). Its
|
|
305
|
+
- **`CartEmptyMessage`** renders the message as a paragraph (`data-fs-cart-empty-message`). The text is the `$content` field `text`; a blank or missing message renders nothing.
|
|
306
|
+
- **`CartContinueShopping`** renders the control that returns the shopper to browsing (`data-fs-cart-continue-shopping`). Its text is the `$content` field `label`, and composed children replace it when you want an icon inside the button.
|
|
286
307
|
|
|
287
308
|
Neither leaf renders a wrapper or carries spacing, so **order, grouping, and any illustration are yours**: put an `Icon` above the message, wrap the pair in a `Container`, pin the control to a footer `Container`. Both self-hide independently, so composing only one is valid.
|
|
288
309
|
|
|
@@ -303,7 +324,7 @@ CartRoot (layout)
|
|
|
303
324
|
│ └── CartGoCheckout
|
|
304
325
|
└── CartEmpty ← only when the cart resolved to 0 items
|
|
305
326
|
├── Icon ← optional illustration (any particle, any position)
|
|
306
|
-
├── CartEmptyMessage ← "sua cesta está vazia" (
|
|
327
|
+
├── CartEmptyMessage ← "sua cesta está vazia" ($content message)
|
|
307
328
|
└── Container ← the store's footer grouping
|
|
308
329
|
└── CartContinueShopping ← "continuar comprando" (closes the drawer; no cart action)
|
|
309
330
|
```
|
|
@@ -338,7 +359,7 @@ On a cart/checkout page there is no drawer to close, so the empty branch keeps `
|
|
|
338
359
|
}
|
|
339
360
|
```
|
|
340
361
|
|
|
341
|
-
|
|
362
|
+
`text` and `label` are message fields: the generator delivers what the schema authors under those names as `$content`. The two elements are authored independently, so publishing the message does not force you to restate the label.
|
|
342
363
|
|
|
343
364
|
---
|
|
344
365
|
|
|
@@ -355,7 +376,7 @@ The `text` and `label` props are the non-CMS fallback. When the store publishes
|
|
|
355
376
|
- **Putting the empty message inside `CartEmpty` as a component prop.** `CartEmpty` is copy-free; the copy belongs to the `CartEmptyMessage` leaf composed inside it.
|
|
356
377
|
- **Placing `CartContinueShopping` outside a drawer.** It is the drawer's close control, so a cart page without a `DrawerRoot` ancestor fails to render — compose a `NavigationLink` there instead.
|
|
357
378
|
- **Wrapping the empty copy to get spacing you expect the leaves to provide.** Neither leaf ships layout by design; use `Container` and swatches.
|
|
358
|
-
- **Hard-coding the checkout wording when a CMS is bound.** `
|
|
379
|
+
- **Hard-coding the checkout wording when a CMS is bound.** Authored `children` render before the `cart-checkout-label` message, so a CTA labelled through `children` ignores what content editors write. Author the `label` field instead.
|
|
359
380
|
- **Expecting a CMS entry to change where checkout goes.** The content channel is the label alone. `href` stays an authored prop.
|
|
360
381
|
|
|
361
382
|
---
|
|
@@ -366,23 +387,22 @@ The mini-cart drawer (the layout composition described on `CartRoot`) ends in a
|
|
|
366
387
|
|
|
367
388
|
- **`CartCheckoutGuard`** is the outer wrapper. It reads cart availability and, while any line item is not `AVAILABLE`, makes its whole subtree non-interactive (`inert` + `aria-disabled`) and exposes `data-fs-cart-checkout-blocked` for styling the disabled state. The shopper cannot proceed with an undeliverable item. It updates reactively from cache — no refetch, no reload — so the block clears the moment the offending line is removed or becomes available.
|
|
368
389
|
- **`CartTotal`** sits inside the guard, on or next to the button, so the grand total the shopper is about to pay is visible at the CTA. It reads the nearest `CartRoot`/`CartTotalizerRoot` and reformats reactively on every cart change.
|
|
369
|
-
- **`CartGoCheckout`** is the link to checkout (default `href` the checkout page, `{ "standard": "checkout" }`). During a **client-side** route transition it surfaces a loading state on its content wrapper — `aria-busy` plus `data-fs-cart-go-checkout-pending` — so the shopper sees the click registered. There is **no built-in spinner**: opt into one by styling that attribute (or composing a `Spinner` on it). For an **external or hard** checkout navigation (a non-Next route, a different origin, or a full page load — common for the real VTEX checkout) there is no client-side transition window, so the loading state simply does not show. That is the documented, graceful no-op, not a bug.
|
|
390
|
+
- **`CartGoCheckout`** is the link to checkout (default `href` the checkout page, `{ "standard": "checkout" }`). During a **client-side** route transition it surfaces a loading state on its content wrapper — `aria-busy` plus `data-fs-cart-go-checkout-pending` — so the shopper sees the click registered. There is **no built-in spinner**: opt into one by styling that attribute (or composing a `Spinner` on it). For an **external or hard** checkout navigation (a non-Next route, a different origin, or a full page load — common for the real VTEX checkout) there is no client-side transition window, so the loading state simply does not show. That is the documented, graceful no-op, not a bug. When it leaves for the checkout it also closes the mini-cart drawer it sits in, so the shopper sees the checkout and not a drawer over it: with a wired stock check, right before the navigation, so a navigation the stock check cancelled, a modifier click (new tab or window) and a click another `onClick` cancelled leave the drawer open; without one, on the click itself. Do not wrap it in `DrawerClose`. Because the drawer closes with the click, the pending state is visible only briefly on that native path (it never shows on the validated one).
|
|
370
391
|
|
|
371
|
-
**The button wording is
|
|
392
|
+
**The button wording is a message.** Composed `children` render first, as for every other cart leaf; without them the button shows the `$content` field `label` of the `cart-checkout-label` content model, so a merchant rewords the CTA — `"Finalizar compra"`, `"Ir para o pagamento"` — with a CMS save and no deployment. A blank or whitespace-only string child counts as unset and the message fills the slot. A missing message renders empty and logs `message.missing`. Non-compiler hosts (Storybook, tests) pass a typed `$content` fixture directly.
|
|
372
393
|
|
|
373
394
|
**The destination is not content-editable.** `href` is an authored prop only. The content channel carries the label alone, so a content editor can change what the button says but never where it goes.
|
|
374
395
|
|
|
375
396
|
| Prop | Type | Required | Notes |
|
|
376
397
|
|-------|------|----------|-------|
|
|
377
398
|
| `href` | page reference or string | no | Checkout destination, default `{ "standard": "checkout" }`. A string is a logical path or an off-site URL. Never content-editable |
|
|
378
|
-
| `
|
|
379
|
-
| `children` | node | no | Legacy label channel, still honoured. Element children are replaced when an entry supplies a label |
|
|
399
|
+
| `children` | node | no | Button content; renders instead of the message |
|
|
380
400
|
|
|
381
|
-
Content model (`cart-checkout-label`) fields
|
|
401
|
+
Content model (`cart-checkout-label`) fields:
|
|
382
402
|
|
|
383
|
-
| Field | Type |
|
|
384
|
-
|
|
385
|
-
| `label` |
|
|
403
|
+
| Field | Type | Notes |
|
|
404
|
+
|-------|------|-------|
|
|
405
|
+
| `label` | ICU message | The button wording, e.g. `"Checkout"` |
|
|
386
406
|
|
|
387
407
|
Schema shape (inside the `DrawerPopup` footer `Container`):
|
|
388
408
|
|
|
@@ -405,22 +425,21 @@ Everything stays a layout composition: the guard, total, and link are independen
|
|
|
405
425
|
|
|
406
426
|
`CartCount` renders `<span data-fs-cart-count>` with the number of units in the cart: the sum of `quantity` over the non-gift lines (two lines of 1 read 2; one line of 3 reads 3; a gift-only cart reads 0). Must be inside `CartRoot`.
|
|
407
427
|
|
|
408
|
-
- `template` — the
|
|
409
|
-
- `templateOne` — the output format used **only when the count is exactly 1**. It has no default: when unset, or blank, `template` is used at 1 as well. **0 uses `template`**, never `templateOne`, because the selector is the literal count and not a locale plural rule (in `pt-BR` the plural rule would call 0 singular).
|
|
428
|
+
- `template` — the `$content` field (`cart-count`) that words the count, an ICU message with a `count` argument, e.g. `'{count}'`. A plain `{count}` is formatted in the locale (`1.000` in `pt-BR`). Word the count with a plural: `=1` selects exactly 1, while `one` follows the locale's plural rule (in `pt-BR` it also covers 0). Children override the text; a missing message renders empty and logs `message.missing`.
|
|
410
429
|
- A count that is not a finite number renders **nothing**. A non-gift line whose `quantity` is missing, `null`, `NaN`, infinite or a string makes the count unreliable, so the span is not rendered, even with `children`; a partial sum would undercount. 0 is finite: an empty or gift-only cart still renders `0`.
|
|
411
430
|
|
|
412
|
-
`CartUnavailableCount`
|
|
431
|
+
`CartUnavailableCount` has the same `template` field (see [below](#unavailable-item-recovery)), counted on the number of unavailable lines.
|
|
413
432
|
|
|
414
433
|
```json
|
|
415
434
|
{
|
|
416
435
|
"cart-title-count": {
|
|
417
436
|
"type": "CartCount",
|
|
418
|
-
"props": { "template": "{count
|
|
437
|
+
"props": { "template": "{count, plural, =1 {# item} other {# itens}}" }
|
|
419
438
|
}
|
|
420
439
|
}
|
|
421
440
|
```
|
|
422
441
|
|
|
423
|
-
|
|
442
|
+
An invalid message renders as authored and logs an error.
|
|
424
443
|
|
|
425
444
|
---
|
|
426
445
|
|
|
@@ -428,8 +447,8 @@ Only the first `{count}` in a template is replaced.
|
|
|
428
447
|
|
|
429
448
|
`CartCheckoutGuard` blocks checkout while any line is not `AVAILABLE`; the recovery affordances let the shopper resolve the block from inside the cart. Three pieces, all reading the availability already on the cart:
|
|
430
449
|
|
|
431
|
-
- **`CartUnavailableCount`** — cart-level summary of how many lines are unavailable (e.g. "2 items unavailable"). Renders a `<span data-fs-cart-unavailable-count>` with
|
|
432
|
-
- **`CartRemoveUnavailable`** — the bulk "remove all unavailable" button (`<button data-fs-cart-remove-unavailable>`). On click it dispatches **one** `$actions.cart.removeItems({ ids })` call carrying every unavailable line id: one mutation, one upstream write, one cache update — no per-line flicker. **Self-hides** when there is nothing to remove. Children are the label (
|
|
450
|
+
- **`CartUnavailableCount`** — cart-level summary of how many lines are unavailable (e.g. "2 items unavailable"). Renders a `<span data-fs-cart-unavailable-count>` with the `$content` field `template` (`cart-unavailable-count`, an ICU message with a `count` argument, e.g. `'{count, plural, one {# item unavailable} other {# items unavailable}}'`; children override the text). **Self-hides** (`null`) when every line is available — including while the cart is still loading — so it never shows a false "0 items unavailable". Must be inside `CartRoot`.
|
|
451
|
+
- **`CartRemoveUnavailable`** — the bulk "remove all unavailable" button (`<button data-fs-cart-remove-unavailable>`). On click it dispatches **one** `$actions.cart.removeItems({ ids })` call carrying every unavailable line id: one mutation, one upstream write, one cache update — no per-line flicker. **Self-hides** when there is nothing to remove. Children are the label; without them it is the `$content` field `label` (`cart-remove-unavailable`, e.g. "Remove unavailable items"). Must be inside `CartRoot` (it reads the cart for the ids; the write itself is context-free).
|
|
433
452
|
- **Per-item remove-on-alert** — a `CartItemRemove` nested inside `CartItemUnavailable` in the line-item template, so each unavailable alert carries its own remove control. Composition only, no new component — see `cart-item.md` (including the label-vs-children nuance: children replace the built-in label).
|
|
434
453
|
|
|
435
454
|
Both cart-level components update reactively: removing the last unavailable line hides them and clears the `CartCheckoutGuard` block with no refetch. Mutation errors surface through the existing `CartError` banner.
|
|
@@ -447,9 +466,84 @@ Schema shape (mini-cart footer, above the checkout CTA):
|
|
|
447
466
|
|
|
448
467
|
---
|
|
449
468
|
|
|
469
|
+
## Separating purchasable and unavailable lines
|
|
470
|
+
|
|
471
|
+
`CartList` renders every line in one run. A store that wants the lines the shopper can buy apart from the ones it cannot replaces `CartList` with a pair of lists and a labelled section:
|
|
472
|
+
|
|
473
|
+
- **`CartAvailableItems`** renders its children once per line whose availability is `AVAILABLE`, in cart order. While the cart is loading it renders `skeletonCount` (default 3) skeletons; it renders nothing when no line is purchasable.
|
|
474
|
+
- **`CartUnavailableItems`** renders its children once per line whose availability is anything else (`OUT_OF_STOCK`, `UNAVAILABLE`, `UNKNOWN`), in cart order. It renders nothing when no line is unavailable, and while loading. It uses the same predicate as `CartCheckoutGuard`, `CartUnavailableCount` and `CartRemoveUnavailable`, so the two lists partition the cart exactly.
|
|
475
|
+
- **`CartUnavailableSection`** is a gate: it renders a `div` around its children only while at least one line is unavailable, so the card, its header and the list disappear together. It carries no copy.
|
|
476
|
+
- **`CartUnavailableLabel`** is the section's heading copy (see Components).
|
|
477
|
+
|
|
478
|
+
Both lists provide the `cart-item` context, so `CartItemRoot` and the other per-line components compose inside either one. Gift lines follow their availability like any other line; an unavailable gift line has no per-line remove (`CartItemRemove` renders nothing on a gift), and `CartRemoveUnavailable` removes it. Unavailable lines still count in the order total until removed.
|
|
479
|
+
|
|
480
|
+
Replace `CartList`, do not compose both: with `CartList` beside the pair every line would render twice.
|
|
481
|
+
|
|
482
|
+
```json
|
|
483
|
+
{
|
|
484
|
+
"page-body": { "type": "CartFilled", "children": ["cart-items-list", "unavailable-section"] },
|
|
485
|
+
"cart-items-list": { "type": "CartAvailableItems", "children": ["cart-item-root"] },
|
|
486
|
+
"cart-item-root": { "type": "CartItemRoot", "children": ["item-name"] },
|
|
487
|
+
"item-name": { "type": "CartItemName" },
|
|
488
|
+
"unavailable-section": {
|
|
489
|
+
"type": "CartUnavailableSection",
|
|
490
|
+
"children": ["unavailable-section-header", "unavailable-section-divider", "unavailable-items-list"]
|
|
491
|
+
},
|
|
492
|
+
"unavailable-section-header": {
|
|
493
|
+
"type": "Container",
|
|
494
|
+
"style": ["flex", "items-center", "gap-2"],
|
|
495
|
+
"children": ["unavailable-section-icon", "unavailable-section-title"]
|
|
496
|
+
},
|
|
497
|
+
"unavailable-section-icon": { "type": "Icon", "props": { "name": "lucide:package-x" } },
|
|
498
|
+
"unavailable-section-title": { "type": "CartUnavailableLabel", "props": { "text": "Unavailable" } },
|
|
499
|
+
"unavailable-section-divider": { "type": "Separator", "props": { "orientation": "horizontal" } },
|
|
500
|
+
"unavailable-items-list": { "type": "CartUnavailableItems", "children": ["unavailable-item-root"] },
|
|
501
|
+
"unavailable-item-root": { "type": "CartItemRoot", "children": ["unavailable-item-name", "unavailable-item-remove"] },
|
|
502
|
+
"unavailable-item-name": { "type": "CartItemName" },
|
|
503
|
+
"unavailable-item-remove": { "type": "CartItemRemove", "children": ["unavailable-item-remove-icon"] },
|
|
504
|
+
"unavailable-item-remove-icon": { "type": "Icon", "props": { "name": "trash" } }
|
|
505
|
+
}
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
---
|
|
509
|
+
|
|
510
|
+
## Nothing left to buy
|
|
511
|
+
|
|
512
|
+
When every line the shopper added is unavailable, the order cannot be placed, and `CartCheckoutGuard` already makes the checkout CTA inert. `CartAllUnavailable` and `CartAllUnavailableMessage` say so in words.
|
|
513
|
+
|
|
514
|
+
- **`CartAllUnavailable`** is a gate: it renders a `div` around its children only while the cart has at least one shopper-added line and every shopper-added line is unavailable (a line counts as unavailable by the same per-line test as `CartUnavailableSection`, so `UNKNOWN` counts; the gate differs from the section, which shows when any line is unavailable, because it needs every shopper-added line to be). It carries no copy and no role. While it holds no rendered `CartAllUnavailableMessage` (blank copy, or no message composed), the store stylesheet hides it (`display: none !important`, through `:has`), so put the box on the gate, not on a wrapper around it: blank copy leaves no empty box, and a `display` class on the gate cannot show it. Browsers without `:has` show the gate as before.
|
|
515
|
+
- **Gift lines are ignored.** A promotional gift is not something the shopper can buy, so a cart whose only available line is a gift still shows the warning, and a cart holding only gift lines never does.
|
|
516
|
+
- **Not `CartEmpty`.** `CartEmpty` owns the cart with zero lines; `CartAllUnavailable` needs at least one shopper-added line, so the two never render together. It renders nothing while the cart is loading or the query failed.
|
|
517
|
+
- **`CartAllUnavailableMessage`** is the copy (see Components). It is an alert region (`role="alert"`), so a screen reader announces it when it appears, for example after the shopper removes the last purchasable line.
|
|
518
|
+
- **The link is optional.** It renders after the text only when both `linkText` and `linkHref` resolve; one without the other renders no link and no anchor. There is no default destination and no default text. A CMS field wins over its prop field by field, so a CMS store authors no link props. A destination that is not a page reference or an http, https, mailto, tel or site-relative URL is dropped.
|
|
519
|
+
|
|
520
|
+
Place the gate under `CartFilled`, beside the lists:
|
|
521
|
+
|
|
522
|
+
```json
|
|
523
|
+
{
|
|
524
|
+
"page-body": { "type": "CartFilled", "children": ["all-unavailable", "cart-items-list", "unavailable-section"] },
|
|
525
|
+
"cart-items-list": { "type": "CartAvailableItems", "children": ["cart-item-root"] },
|
|
526
|
+
"cart-item-root": { "type": "CartItemRoot" },
|
|
527
|
+
"unavailable-section": { "type": "CartUnavailableSection", "children": ["unavailable-items-list"] },
|
|
528
|
+
"unavailable-items-list": { "type": "CartUnavailableItems", "children": ["unavailable-item-root"] },
|
|
529
|
+
"unavailable-item-root": { "type": "CartItemRoot" },
|
|
530
|
+
"all-unavailable": { "type": "CartAllUnavailable", "children": ["all-unavailable-message"] },
|
|
531
|
+
"all-unavailable-message": {
|
|
532
|
+
"type": "CartAllUnavailableMessage",
|
|
533
|
+
"props": {
|
|
534
|
+
"text": "No items are available for purchase right now",
|
|
535
|
+
"linkText": "Review your selection",
|
|
536
|
+
"linkHref": { "page": "<page name>" }
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
---
|
|
543
|
+
|
|
450
544
|
## Clearing the cart
|
|
451
545
|
|
|
452
|
-
`ClearCartButton` empties the cart in one click (`<button data-fs-clear-cart-button>`). It reads every line id from the cart and dispatches **one** `$actions.cart.removeItems({ ids })` call: every line goes, gift and unavailable lines included, in cart order. No confirmation dialog and no toast. Children are the label (
|
|
546
|
+
`ClearCartButton` empties the cart in one click (`<button data-fs-clear-cart-button>`). It reads every line id from the cart and dispatches **one** `$actions.cart.removeItems({ ids })` call: every line goes, gift and unavailable lines included, in cart order. No confirmation dialog and no toast. Children are the label; without them it is the `$content` field `label` (`clear-cart-button`, e.g. "Clear cart"). Must be inside `CartRoot`.
|
|
453
547
|
|
|
454
548
|
- **Self-hides** (`null`) when the cart has no lines or has not resolved, as `CartRemoveUnavailable` does.
|
|
455
549
|
- **Disabled while pending.** The button carries the native `disabled` attribute plus `data-fs-clear-cart-button-pending` until the call settles, and a second click in the same tick is swallowed, so one click is one mutation. Style the pending look with `disabled:` classes or the pending hook. A caller `disabled` prop also disables it.
|
|
@@ -466,7 +560,7 @@ Schema shape (Cart page):
|
|
|
466
560
|
"cart-error": { "type": "CartError" },
|
|
467
561
|
"page-body": { "type": "CartFilled", "children": ["clear-cart-row"] },
|
|
468
562
|
"clear-cart-row": { "type": "Container", "children": ["clear-cart-btn"] },
|
|
469
|
-
"clear-cart-btn": { "type": "ClearCartButton", "props": { "children": "Limpar carrinho" } }
|
|
563
|
+
"clear-cart-btn": { "type": "ClearCartButton", "props": { "label": "Clear cart", "children": "Limpar carrinho" } }
|
|
470
564
|
}
|
|
471
565
|
```
|
|
472
566
|
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# ChallengeReturn
|
|
2
|
+
|
|
3
|
+
**Category:** commerce
|
|
4
|
+
**Purpose:** The whole of the page the bank sends the shopper back to after a 3D Secure challenge. Finishes the order with no click, then replaces the page with the order confirmation; a shopper who returns too late is told the verification expired and offered a link back to the checkout.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Visual cues (how to identify in an image)
|
|
9
|
+
|
|
10
|
+
**None, deliberately.** This component has no visual identity and must never be selected from a screenshot. It is a route's behavior rather than a block on a page: what it draws is a short status line, and only for the moment before the shopper is moved on. A design showing the bank's verification screen is showing the *bank's* page, which this stack does not render, and nothing in that image maps to this component.
|
|
11
|
+
|
|
12
|
+
The image is the source of truth for layout, and this component is not in any layout.
|
|
13
|
+
|
|
14
|
+
## When to use
|
|
15
|
+
|
|
16
|
+
- On the page named by `PlaceOrder`'s `challengeReturnHref`, as its only element, when the store accepts cards whose bank may ask for a 3D Secure challenge.
|
|
17
|
+
|
|
18
|
+
## When NOT to use
|
|
19
|
+
|
|
20
|
+
- For the confirmation page the shopper lands on afterwards → use the order-placed components; this page only finishes the order and leaves.
|
|
21
|
+
- For the place-order button → use [[place-order]], which sends the shopper to the bank. This page is where the bank sends them back.
|
|
22
|
+
- Anywhere a shopper is meant to read the page. Anything composed beside it is replaced as soon as the order is finished.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Composition
|
|
27
|
+
|
|
28
|
+
`ChallengeReturn` is a leaf element in the PageSchema and takes no children. It owns the whole page. It requires no payment root and declares no context and no fragment: it reads the order group from its own URL, calls the gateway callback once, and reads the settled order once.
|
|
29
|
+
|
|
30
|
+
```text
|
|
31
|
+
ChallengeReturn
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The page is an ordinary page of the store (no standard page name fits it), and the store names it from `PlaceOrder`:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"place-order": {
|
|
39
|
+
"type": "PlaceOrder",
|
|
40
|
+
"props": { "challengeReturnHref": { "page": "checkout-challenge-return" } }
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The page itself is a `page.json` named `checkout-challenge-return`, containing one `ChallengeReturn` element. Give it `robots` noindex.
|
|
46
|
+
|
|
47
|
+
## Components
|
|
48
|
+
|
|
49
|
+
### ChallengeReturn
|
|
50
|
+
|
|
51
|
+
| Prop | Type | Default | Notes |
|
|
52
|
+
|------|------|---------|-------|
|
|
53
|
+
| `checkoutHref` | page reference or string | `{ "standard": "checkout" }` | Where that link goes. |
|
|
54
|
+
| `successHref` | page reference or string | `{ "standard": "order-placed" }` | Where the shopper lands once the order is finished. A page reference gets the order's Node id as its `orderId` param. |
|
|
55
|
+
|
|
56
|
+
**Content model** (`challenge-return`), each field read only from `$content` (a missing message renders empty and logs `message.missing`):
|
|
57
|
+
|
|
58
|
+
- `resumingMessage`: status shown while the order is being finished.
|
|
59
|
+
- `lateReturnMessage`: shown in an alert when the gateway callback answered a refusal: the verification lapsed and the order was not placed.
|
|
60
|
+
- `unconfirmedMessage`: shown as a status when the callback gave no answer, answered with no order to show, or when the confirmation page cannot be reached. The payment may still be processing, so there is no link to buy again.
|
|
61
|
+
- `checkoutLabel`: label of the link back to the checkout, inside the late-return alert.
|
|
62
|
+
|
|
63
|
+
**Actions:** declares `actions: { payment: ['gatewayCallback'], analytics: ['track'] }` and nothing else. It never opens a transaction and never posts a card: a return never pays.
|
|
64
|
+
|
|
65
|
+
### What the page does, in order
|
|
66
|
+
|
|
67
|
+
1. Reads the order group from the URL. The query must be exactly one `orderGroup` and `redirect=true`; anything else (a missing or repeated group, a dot segment, a group with a slash, a longer-than-64-character group, `redirect` absent or not `true`) makes no request at all and shows the late-return alert. Any other parameter the bank adds is ignored and never used.
|
|
68
|
+
2. Calls the gateway callback once for that group, asking it to accept the challenge. A repeated mount never calls it twice.
|
|
69
|
+
3. On success, reads the settled order once (within ten seconds), reports one `purchase` analytics event with the order's reference as the transaction id and its total as the value, and replaces the history entry with the confirmation page. The event is skipped for an order the read says is `DENIED`, for one with no total, when the read fails or is not answered in time, and when this browser already reported that order. The shopper still reaches the confirmation page in every one of those cases. The event goes out before the history entry is replaced, and the once-per-order marker is the one `PlaceOrder` uses for its own single-pass and resume paths, so an order is reported once whichever path finished it (see [[place-order]]).
|
|
70
|
+
4. On a refusal the server coded, shows the late-return alert. On no answer, a success with no order to show, or a confirmation page the store cannot reach (or a router that throws), shows the unconfirmed status. Nothing moves the shopper on a timer, and the page never sends the shopper back to the bank.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Canonical schema example
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"challenge-return": {
|
|
79
|
+
"type": "ChallengeReturn",
|
|
80
|
+
"props": {
|
|
81
|
+
"resumingMessage": "Finishing your order...",
|
|
82
|
+
"lateReturnMessage": "3D Secure expired. Go back to the checkout to place your order again.",
|
|
83
|
+
"checkoutLabel": "Back to the checkout"
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Common mistakes
|
|
90
|
+
|
|
91
|
+
- **Composing it beside anything else.** The page is replaced as soon as the order is finished, so copy authored next to it is rarely seen.
|
|
92
|
+
- **Forgetting to author `challengeReturnHref` on `PlaceOrder`.** Without it the store sends no return URL, so a bank challenge cannot be followed and the shopper reads the refusal instead.
|
|
93
|
+
- **Linking the late-return message to a payment page.** The link goes to the checkout, where the shopper places a new order; it never retries the old one.
|
|
94
|
+
- **Selecting it from a screenshot.** It has no visual identity.
|
|
95
|
+
|
|
96
|
+
## Known limitations
|
|
97
|
+
|
|
98
|
+
- **If the transaction cookies do not survive the round trip to the bank, every return reads as expired.** The callback needs the cookies the checkout set; a browser that drops them answers a refusal even when the shopper completed the challenge, and VTEX cancels the order five minutes after it was placed.
|
|
99
|
+
- **A shopper who never returns from the bank triggers nothing.** Neither `PlaceOrder` nor this page sets a timer, listens for the page being left, sends a cancel or void call, or polls the order after the redirect. VTEX's Checkout API asks for the payment to be confirmed within five minutes of placing the order, and VTEX cancels the order it opened after that window. Nothing in this repository observes the cancel. Whether it also releases the authorization held on the card is a question for Payments that the storefront does not answer: it never sends a reversal.
|
|
100
|
+
- **The callback only runs for the order group this browser session started.** `paymentStartTransaction` sets the `HttpOnly` `__Host-fs_order_group` cookie (see [ADR-0023](../../../../../docs/storefront-core/adr-0023-credit-card-guarantees-and-deviations.md)), and `paymentGatewayCallback` checks the transaction cookies first (with them missing the result is `MISSING_TRANSACTION_COOKIES`). Once they are present, it answers `ORDER_GROUP_MISMATCH` before calling VTEX when the group in the URL differs from the cookie or the cookie is missing. This page treats that code like any server-coded refusal and shows the late-return alert, so a link carrying someone else's group finishes nothing and a return in another browser reads as expired. The cookie lives 15 minutes and survives the return, so reloading this page after the order is placed repeats the callback instead of turning into a refusal. With two 3D Secure checkouts pending in one browser the cookie holds the later group, and the first return reads as expired even if its challenge was completed.
|
|
101
|
+
- **A shopper told to buy again may see two holds on the card** until the bank releases the first.
|
|
102
|
+
- **The page undercounts `purchase` in four cases**: the settled-order read fails or takes over ten seconds, the order is `DENIED`, the order has no total, or the shopper's browser blocks storage and the page is reloaded before it leaves. It overcounts only when two different browsers each report the same order once.
|
|
103
|
+
- **The order group is in the return URL**, so it sits in the browser history and, for same-origin requests, the `Referer`. The order's Node id is a reversible base64 of the same group.
|
|
104
|
+
- **Payment-app delivery of 3D Secure is not supported.** Only accounts that deliver the challenge by redirect are.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Styling
|
|
109
|
+
|
|
110
|
+
| Component | What you style | Plausible classes |
|
|
111
|
+
|---|---|---|
|
|
112
|
+
| `ChallengeReturn` (root `div`, `data-fs-challenge-return`) | Layout wrapper for whichever state is showing | `flex min-h-[420px] flex-col items-center justify-center gap-[12px] text-center` |
|
|
113
|
+
| Resuming (`data-fs-challenge-return-resuming`) | The status line while the order is being finished, an `<output>` | `text-[14px] font-medium text-[#6B7280]` |
|
|
114
|
+
| Late return (`data-fs-challenge-return-late`) | The alert, `role="alert"`, holding the message and the link | `flex flex-col items-center gap-[8px] text-[14px] text-[var(--color-feedback-danger)]` |
|
|
115
|
+
| Message (`data-fs-challenge-return-message`) | The late-return sentence inside the alert | `text-[14px]` |
|
|
116
|
+
| Checkout link (`data-fs-challenge-return-checkout-link`) | The real anchor back to the checkout | `text-[14px] font-bold underline text-[#1A1A1A]` |
|
|
117
|
+
| Unconfirmed (`data-fs-challenge-return-unconfirmed`) | The status that says the payment may still be processing, an `<output>` | `text-[14px] text-[var(--color-feedback-warning)]` |
|
|
118
|
+
|
|
119
|
+
```json
|
|
120
|
+
{
|
|
121
|
+
"challenge-return": {
|
|
122
|
+
"type": "ChallengeReturn",
|
|
123
|
+
"style": ["flex", "min-h-[420px]", "flex-col", "items-center", "justify-center", "gap-[12px]", "text-center"]
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The role colors above are the foundation's `visualIdentity` roles (`--color-feedback-danger`, `--color-feedback-warning`), so they follow the store when it changes them.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Related
|
|
133
|
+
|
|
134
|
+
- [[place-order]] — the CTA that sends the shopper to the bank and names this page with `challengeReturnHref`.
|
|
135
|
+
- [[sign-in-redirect]] — the other whole-page handover component, with the same rule: place it alone on its page.
|
|
@@ -59,8 +59,15 @@ SessionRoot (required ancestor; session tri-state
|
|
|
59
59
|
| Prop | Type | Default | Notes |
|
|
60
60
|
|------|------|---------|-------|
|
|
61
61
|
| `skeletonCount` | number | `2` | Placeholder rows drawn while the preferences resolve. Set it to the number of controls composed. |
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
|
|
63
|
+
Content model (`client-preferences-fieldset`), ICU message fields with no package default; an unauthored one renders empty and logs `message.missing`:
|
|
64
|
+
|
|
65
|
+
| Field | Source (English) | Notes |
|
|
66
|
+
|-------|------------------|-------|
|
|
67
|
+
| `loadingLabel` | `Loading your preferences` | Announced politely while the preferences resolve. |
|
|
68
|
+
| `loadedLabel` | `Your preferences are ready` | Announced politely once the controls mount. |
|
|
69
|
+
| `groupLabel` | `Your preferences` | Accessible name of the `<fieldset>` group; unauthored, no `aria-label` is emitted. |
|
|
70
|
+
| `genericErrorMessage` | `Unable to save your preferences. Please try again.` | Shown by `FormError` for every refusal of the write (`MISSING_CART_CONTEXT`, `CART_NOT_FOUND`, `NO_PREFERENCE_PROVIDED`) and for a network failure; none is one the shopper can fix. A code this fieldset does not know shows it too and logs `message.unknown-code`. |
|
|
64
71
|
|
|
65
72
|
Declares `requiresContext: ['form', 'session']` (needs both a `FormRoot` and a `SessionRoot` ancestor), `providesContext: 'client-preferences'`, `actions: { identity: ['clientPreferencesUpdate'] }`, and its own fragment on `Query.clientPreferences`. Renders `Fieldset.Root` with `disabled={readOnly}`; carries `-pending` until its entity resolves, and `-readonly` when the session reports `canEditData: false`.
|
|
66
73
|
|
|
@@ -72,9 +79,7 @@ The definition also declares that same component as its `skeleton`, which is the
|
|
|
72
79
|
|
|
73
80
|
### ClientPreferencesNewsletterControl / ClientPreferencesSavePersonalDataControl
|
|
74
81
|
|
|
75
|
-
|
|
76
|
-
|------|------|---------|-------|
|
|
77
|
-
| `label` | string | `'Email me with news and offers'` / `'Save my information for next time'` | |
|
|
82
|
+
Content models `client-preferences-newsletter` / `client-preferences-save-data`, one ICU message field each with no package default: `label` (source `Email me with news and offers` / `Save my information for next time`).
|
|
78
83
|
|
|
79
84
|
Childless, renders `Field.Root > Field.Label > Field.Checkbox` (with the checkmark icon), the label text following. Composed children replace that default anatomy and still bind to the same field. Defaults to unchecked (opt-in, not opt-out) — a `null` saved value reads as `false`.
|
|
80
85
|
|