@vtex/faststore 0.0.6 → 0.0.8
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 +99 -0
- package/dist/actions.json +152 -1
- package/dist/catalog.json +2541 -1278
- package/dist/cli/UnreachableCaseError-Crd168Vu.js +10 -0
- package/dist/cli/UnreachableCaseError-Crd168Vu.js.map +1 -0
- package/dist/cli/cacheControl-CEojH_TM.js +158 -0
- package/dist/cli/cacheControl-CEojH_TM.js.map +1 -0
- package/dist/cli/cachePolicy-m2vASMRW.js +26 -0
- package/dist/cli/cachePolicy-m2vASMRW.js.map +1 -0
- package/dist/cli/computeCoreSchemaHash-DPJZj-qJ.js +10 -0
- package/dist/cli/computeCoreSchemaHash-DPJZj-qJ.js.map +1 -0
- package/dist/cli/default-BCQHcwbL.js +253 -0
- package/dist/cli/default-BCQHcwbL.js.map +1 -0
- package/dist/cli/disableSuggestions-yO9UqiWn.js +21 -0
- package/dist/cli/disableSuggestions-yO9UqiWn.js.map +1 -0
- package/dist/cli/dist-C1JhdHfo.js +2001 -0
- package/dist/cli/dist-C1JhdHfo.js.map +1 -0
- package/dist/cli/graphql-DG9thCDG.js +14589 -0
- package/dist/cli/graphql-DG9thCDG.js.map +1 -0
- package/dist/cli/index.d.ts +799 -0
- package/dist/cli/index.js +36459 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/index.min-BsIHDfFK.js +613 -0
- package/dist/cli/index.min-BsIHDfFK.js.map +1 -0
- package/dist/cli/inlineTrace-uLgOJ3TH.js +52 -0
- package/dist/cli/inlineTrace-uLgOJ3TH.js.map +1 -0
- package/dist/cli/internalPlugin-DnuwN4_4.js +11 -0
- package/dist/cli/internalPlugin-DnuwN4_4.js.map +1 -0
- package/dist/cli/packageVersion-DQAnIEil.js +6 -0
- package/dist/cli/packageVersion-DQAnIEil.js.map +1 -0
- package/dist/cli/rolldown-runtime-BMI-E3GI.js +44 -0
- package/dist/cli/schemaIsSubgraph-DoGh3OYj.js +17 -0
- package/dist/cli/schemaIsSubgraph-DoGh3OYj.js.map +1 -0
- package/dist/cli/schemaReporting-K-me-3-v.js +199 -0
- package/dist/cli/schemaReporting-K-me-3-v.js.map +1 -0
- package/dist/cli/server-runtime.js +49879 -0
- package/dist/cli/server-runtime.js.map +1 -0
- package/dist/cli/traceTreeBuilder-BIcV2U7b.js +9118 -0
- package/dist/cli/traceTreeBuilder-BIcV2U7b.js.map +1 -0
- package/dist/cli/usageReporting-Bpl8vSZX.js +10201 -0
- package/dist/cli/usageReporting-Bpl8vSZX.js.map +1 -0
- package/dist/cli/v4-CBhFvC49.js +42 -0
- package/dist/cli/v4-CBhFvC49.js.map +1 -0
- package/dist/client.d.ts +5 -1
- package/dist/client.js +5 -1
- package/dist/components.d.ts +38 -9
- package/dist/components.js +42 -13
- package/dist/content-types.json +616 -0
- package/dist/core/dist/define-component.d.ts +43 -1
- package/dist/core/dist/index.d.ts +2 -2
- package/dist/docs/account-access-gate.md +4 -4
- package/dist/docs/account-address-book.md +519 -0
- package/dist/docs/account-entry-point.md +1 -1
- package/dist/docs/account-menu-identity.md +160 -0
- package/dist/docs/account-menu.md +107 -24
- package/dist/docs/alert-dialog.md +2 -2
- package/dist/docs/avatar.md +103 -0
- package/dist/docs/billing-address.md +17 -9
- package/dist/docs/card-entry.md +37 -6
- package/dist/docs/cardholder-document.md +16 -14
- package/dist/docs/cart-item.md +1 -1
- package/dist/docs/cart.md +8 -8
- package/dist/docs/client-profile-fieldset.md +7 -5
- package/dist/docs/copy-text.md +84 -0
- package/dist/docs/document-field.md +8 -8
- package/dist/docs/footer-link-group.md +2 -2
- package/dist/docs/header-root.md +1 -1
- package/dist/docs/incentives.md +2 -2
- package/dist/docs/logo.md +5 -5
- package/dist/docs/my-account-profile.md +5 -5
- package/dist/docs/navigation-link-list.md +2 -2
- package/dist/docs/navigation-link.md +3 -3
- package/dist/docs/order-cancel.md +52 -0
- package/dist/docs/order-delivery-address.md +63 -0
- package/dist/docs/order-delivery-group.md +83 -0
- package/dist/docs/order-details-back.md +41 -0
- package/dist/docs/order-details-header.md +48 -0
- package/dist/docs/order-list-row.md +46 -0
- package/dist/docs/order-list-search.md +101 -0
- package/dist/docs/order-list-views.md +97 -0
- package/dist/docs/order-list.md +94 -0
- package/dist/docs/order-payment.md +94 -0
- package/dist/docs/order-placed-date.md +49 -0
- package/dist/docs/order-placed-payment-summary.md +13 -15
- package/dist/docs/order-placed.md +225 -0
- package/dist/docs/order-progress.md +88 -0
- package/dist/docs/order-status-badge.md +91 -0
- package/dist/docs/order-summary.md +53 -0
- package/dist/docs/payment-method-badges.md +14 -3
- package/dist/docs/place-order.md +13 -9
- package/dist/docs/product-shelf.md +20 -13
- package/dist/docs/saved-cards.md +2 -2
- package/dist/docs/select.md +19 -6
- package/dist/docs/session.md +1 -1
- package/dist/docs/shipping-address.md +1 -1
- package/dist/docs/sign-in-redirect.md +6 -6
- package/dist/docs/toast.md +7 -3
- package/dist/index.d.ts +7 -3
- package/dist/index.js +2 -1
- package/dist/internal/client.d.ts +6 -1
- package/dist/internal/client.js +8 -3
- package/dist/internal/content.d.ts +2 -2
- package/dist/internal/server.d.ts +8 -1
- package/dist/internal/server.js +8 -1
- package/dist/matter/account-access-gate/account-access-gate.d.ts +2 -1
- package/dist/matter/account-access-gate/account-access-gate.js +19 -16
- package/dist/matter/account-access-gate/account-access-gate.js.map +1 -1
- package/dist/matter/account-address-book/account-address-book-delete.d.ts +60 -0
- package/dist/matter/account-address-book/account-address-book-delete.js +184 -0
- package/dist/matter/account-address-book/account-address-book-delete.js.map +1 -0
- package/dist/matter/account-address-book/account-address-book-deliverability.d.ts +19 -0
- package/dist/matter/account-address-book/account-address-book-deliverability.js +50 -0
- package/dist/matter/account-address-book/account-address-book-deliverability.js.map +1 -0
- package/dist/matter/account-address-book/account-address-book-form-parts.d.ts +42 -0
- package/dist/matter/account-address-book/account-address-book-form-parts.js +146 -0
- package/dist/matter/account-address-book/account-address-book-form-parts.js.map +1 -0
- package/dist/matter/account-address-book/account-address-book-profile-notice.d.ts +25 -0
- package/dist/matter/account-address-book/account-address-book-profile-notice.js +72 -0
- package/dist/matter/account-address-book/account-address-book-profile-notice.js.map +1 -0
- package/dist/matter/account-address-book/account-address-book.d.ts +120 -0
- package/dist/matter/account-address-book/account-address-book.js +469 -0
- package/dist/matter/account-address-book/account-address-book.js.map +1 -0
- package/dist/matter/account-address-book/account-address-country-switch.js +59 -0
- package/dist/matter/account-address-book/account-address-country-switch.js.map +1 -0
- package/dist/matter/account-address-book/account-address-country.d.ts +36 -0
- package/dist/matter/account-address-book/account-address-country.js +151 -0
- package/dist/matter/account-address-book/account-address-country.js.map +1 -0
- package/dist/matter/account-address-book/account-address-first-line.js +11 -0
- package/dist/matter/account-address-book/account-address-first-line.js.map +1 -0
- package/dist/matter/account-address-book/account-address-form-context.d.ts +55 -0
- package/dist/matter/account-address-book/account-address-form-context.js +14 -0
- package/dist/matter/account-address-book/account-address-form-context.js.map +1 -0
- package/dist/matter/account-address-book/account-address-form.d.ts +85 -0
- package/dist/matter/account-address-book/account-address-form.js +946 -0
- package/dist/matter/account-address-book/account-address-form.js.map +1 -0
- package/dist/matter/account-address-book/account-address-postal-autofill.js +189 -0
- package/dist/matter/account-address-book/account-address-postal-autofill.js.map +1 -0
- package/dist/matter/account-address-book/account-address-record.d.ts +26 -0
- package/dist/matter/account-address-book/account-address-record.js +138 -0
- package/dist/matter/account-address-book/account-address-record.js.map +1 -0
- package/dist/matter/account-entry-point/account-entry-point.js +11 -11
- package/dist/matter/account-entry-point/account-entry-point.js.map +1 -1
- package/dist/matter/account-menu/account-menu.d.ts +77 -3
- package/dist/matter/account-menu/account-menu.js +252 -19
- package/dist/matter/account-menu/account-menu.js.map +1 -1
- package/dist/matter/account-menu/sign-out-failure.js +50 -0
- package/dist/matter/account-menu/sign-out-failure.js.map +1 -0
- package/dist/matter/account-menu-identity/account-menu-identity.d.ts +21 -0
- package/dist/matter/account-menu-identity/account-menu-identity.js +88 -0
- package/dist/matter/account-menu-identity/account-menu-identity.js.map +1 -0
- package/dist/matter/billing-address/billing-address.d.ts +30 -17
- package/dist/matter/billing-address/billing-address.js +128 -33
- package/dist/matter/billing-address/billing-address.js.map +1 -1
- package/dist/matter/breadcrumb/breadcrumb.js +2 -2
- package/dist/matter/breadcrumb/breadcrumb.js.map +1 -1
- package/dist/matter/card-entry/card-capture.js +4 -3
- package/dist/matter/card-entry/card-capture.js.map +1 -1
- package/dist/matter/card-entry/card-entry.d.ts +5 -3
- package/dist/matter/card-entry/card-entry.js +78 -27
- package/dist/matter/card-entry/card-entry.js.map +1 -1
- package/dist/matter/cardholder-document/cardholder-document.d.ts +10 -9
- package/dist/matter/cardholder-document/cardholder-document.js +36 -16
- package/dist/matter/cardholder-document/cardholder-document.js.map +1 -1
- package/dist/matter/cart/cart.d.ts +7 -2
- package/dist/matter/cart/cart.js +29 -26
- package/dist/matter/cart/cart.js.map +1 -1
- package/dist/matter/cart-item/cart-item.js +2 -2
- package/dist/matter/cart-item/cart-item.js.map +1 -1
- package/dist/matter/client-preferences/client-preferences-fieldset.js +2 -2
- package/dist/matter/client-profile-form/client-profile-fieldset.js +9 -6
- package/dist/matter/client-profile-form/client-profile-fieldset.js.map +1 -1
- package/dist/matter/identity-edit/identity-edit.js +3 -3
- package/dist/matter/identity-edit/identity-edit.js.map +1 -1
- package/dist/matter/identity-summary/identity-summary.js +4 -3
- package/dist/matter/identity-summary/identity-summary.js.map +1 -1
- package/dist/matter/my-account-profile/my-account-profile.d.ts +6 -3
- package/dist/matter/my-account-profile/my-account-profile.js +6 -5
- package/dist/matter/my-account-profile/my-account-profile.js.map +1 -1
- package/dist/matter/order-cancel/order-cancel.d.ts +110 -0
- package/dist/matter/order-cancel/order-cancel.js +344 -0
- package/dist/matter/order-cancel/order-cancel.js.map +1 -0
- package/dist/matter/order-delivery-address/order-delivery-address.d.ts +73 -0
- package/dist/matter/order-delivery-address/order-delivery-address.js +172 -0
- package/dist/matter/order-delivery-address/order-delivery-address.js.map +1 -0
- package/dist/matter/order-delivery-group/order-delivery-group.d.ts +128 -0
- package/dist/matter/order-delivery-group/order-delivery-group.js +408 -0
- package/dist/matter/order-delivery-group/order-delivery-group.js.map +1 -0
- package/dist/matter/order-details-header/order-details-header.d.ts +104 -0
- package/dist/matter/order-details-header/order-details-header.js +190 -0
- package/dist/matter/order-details-header/order-details-header.js.map +1 -0
- package/dist/matter/order-list/customer-orders-filter.d.ts +12 -0
- package/dist/matter/order-list/customer-orders-filter.js +30 -0
- package/dist/matter/order-list/customer-orders-filter.js.map +1 -0
- package/dist/matter/order-list/order-list.d.ts +121 -0
- package/dist/matter/order-list/order-list.js +395 -0
- package/dist/matter/order-list/order-list.js.map +1 -0
- package/dist/matter/order-list-row/order-list-row.d.ts +44 -0
- package/dist/matter/order-list-row/order-list-row.js +127 -0
- package/dist/matter/order-list-row/order-list-row.js.map +1 -0
- package/dist/matter/order-list-search/order-list-search.d.ts +72 -0
- package/dist/matter/order-list-search/order-list-search.js +296 -0
- package/dist/matter/order-list-search/order-list-search.js.map +1 -0
- package/dist/matter/order-list-views/order-list-views.d.ts +65 -0
- package/dist/matter/order-list-views/order-list-views.js +154 -0
- package/dist/matter/order-list-views/order-list-views.js.map +1 -0
- package/dist/matter/order-payment/order-payment.d.ts +83 -0
- package/dist/matter/order-payment/order-payment.js +258 -0
- package/dist/matter/order-payment/order-payment.js.map +1 -0
- package/dist/matter/order-placed/order-placed-deliveries.d.ts +145 -0
- package/dist/matter/order-placed/order-placed-deliveries.js +380 -0
- package/dist/matter/order-placed/order-placed-deliveries.js.map +1 -0
- package/dist/matter/order-placed/order-placed.d.ts +122 -0
- package/dist/matter/order-placed/order-placed.js +452 -0
- package/dist/matter/order-placed/order-placed.js.map +1 -0
- package/dist/matter/order-placed-date/order-placed-date.d.ts +45 -0
- package/dist/matter/order-placed-date/order-placed-date.js +92 -0
- package/dist/matter/order-placed-date/order-placed-date.js.map +1 -0
- package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.d.ts +5 -8
- package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js +29 -81
- package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js.map +1 -1
- package/dist/matter/order-progress/order-progress.d.ts +85 -0
- package/dist/matter/order-progress/order-progress.js +203 -0
- package/dist/matter/order-progress/order-progress.js.map +1 -0
- package/dist/matter/order-summary/order-summary.d.ts +81 -0
- package/dist/matter/order-summary/order-summary.js +192 -0
- package/dist/matter/order-summary/order-summary.js.map +1 -0
- package/dist/matter/payment/cardholder-document-rule.d.ts +35 -0
- package/dist/matter/payment/cardholder-document-rule.js +35 -0
- package/dist/matter/payment/cardholder-document-rule.js.map +1 -0
- package/dist/matter/payment/payment-card-capture.js +38 -23
- package/dist/matter/payment/payment-card-capture.js.map +1 -1
- package/dist/matter/payment/payment-controller.js +12 -0
- package/dist/matter/payment/payment-controller.js.map +1 -1
- package/dist/matter/payment/payment-method-badges.js +4 -2
- package/dist/matter/payment/payment-method-badges.js.map +1 -1
- package/dist/matter/payment/payment.js +12 -0
- package/dist/matter/payment/payment.js.map +1 -1
- package/dist/matter/payment/use-payment-method-selection.d.ts +39 -0
- package/dist/matter/payment/use-payment-method-selection.js +30 -2
- package/dist/matter/payment/use-payment-method-selection.js.map +1 -1
- package/dist/matter/payment/use-payment-submit-gate.d.ts +16 -2
- package/dist/matter/payment/use-payment-submit-gate.js +42 -14
- package/dist/matter/payment/use-payment-submit-gate.js.map +1 -1
- package/dist/matter/place-order/place-order.d.ts +12 -7
- package/dist/matter/place-order/place-order.js +126 -103
- package/dist/matter/place-order/place-order.js.map +1 -1
- package/dist/matter/pricing/pricing.js +5 -5
- package/dist/matter/pricing/pricing.js.map +1 -1
- package/dist/matter/product-shelf/product-shelf.d.ts +61 -31
- package/dist/matter/product-shelf/product-shelf.js +157 -57
- package/dist/matter/product-shelf/product-shelf.js.map +1 -1
- package/dist/matter/region/region.js +1 -1
- package/dist/matter/saved-cards/saved-cards.js +27 -15
- package/dist/matter/saved-cards/saved-cards.js.map +1 -1
- package/dist/matter/session/session.js +2 -2
- package/dist/matter/session/session.js.map +1 -1
- package/dist/matter/shipping-address/country-descriptors.d.ts +1 -0
- package/dist/matter/shipping-address/country-descriptors.js +23 -1
- package/dist/matter/shipping-address/country-descriptors.js.map +1 -1
- package/dist/matter/shipping-address/shipping-address.js +63 -15
- package/dist/matter/shipping-address/shipping-address.js.map +1 -1
- package/dist/matter/shipping-simulator/shipping-simulator.d.ts +1 -1
- package/dist/matter/shipping-simulator/shipping-simulator.js.map +1 -1
- package/dist/matter/sign-in-redirect/sign-in-redirect.js +48 -10
- package/dist/matter/sign-in-redirect/sign-in-redirect.js.map +1 -1
- package/dist/matter/variant-selector/variant-selector.js +2 -2
- package/dist/matter/variant-selector/variant-selector.js.map +1 -1
- package/dist/particles/address-summary/address-summary.js +2 -2
- package/dist/particles/address-summary/address-summary.js.map +1 -1
- package/dist/particles/alert-dialog/alert-dialog.d.ts +5 -1
- package/dist/particles/alert-dialog/alert-dialog.js +5 -2
- package/dist/particles/alert-dialog/alert-dialog.js.map +1 -1
- package/dist/particles/avatar/avatar.d.ts +17 -0
- package/dist/particles/avatar/avatar.js +65 -0
- package/dist/particles/avatar/avatar.js.map +1 -0
- package/dist/particles/copy-text/copy-text.d.ts +28 -0
- package/dist/particles/copy-text/copy-text.js +140 -0
- package/dist/particles/copy-text/copy-text.js.map +1 -0
- package/dist/particles/document-field/document-field.d.ts +34 -5
- package/dist/particles/document-field/document-field.js +115 -19
- package/dist/particles/document-field/document-field.js.map +1 -1
- package/dist/particles/field/field.js +1 -1
- package/dist/particles/field/field.js.map +1 -1
- package/dist/particles/footer-link-group/footer-link-group.d.ts +6 -2
- package/dist/particles/footer-link-group/footer-link-group.js +18 -7
- package/dist/particles/footer-link-group/footer-link-group.js.map +1 -1
- package/dist/particles/incentives/incentives.d.ts +6 -2
- package/dist/particles/incentives/incentives.js +7 -2
- package/dist/particles/incentives/incentives.js.map +1 -1
- package/dist/particles/logo/logo.d.ts +3 -2
- package/dist/particles/logo/logo.js +20 -8
- package/dist/particles/logo/logo.js.map +1 -1
- package/dist/particles/navigation-link/navigation-link.d.ts +2 -3
- package/dist/particles/navigation-link/navigation-link.js +4 -4
- package/dist/particles/navigation-link/navigation-link.js.map +1 -1
- package/dist/particles/navigation-link-list/navigation-link-list.d.ts +6 -2
- package/dist/particles/navigation-link-list/navigation-link-list.js +18 -7
- package/dist/particles/navigation-link-list/navigation-link-list.js.map +1 -1
- package/dist/particles/order-details-back/order-details-back.d.ts +28 -0
- package/dist/particles/order-details-back/order-details-back.js +52 -0
- package/dist/particles/order-details-back/order-details-back.js.map +1 -0
- package/dist/particles/order-status-badge/order-status-badge.d.ts +19 -0
- package/dist/particles/order-status-badge/order-status-badge.js +50 -0
- package/dist/particles/order-status-badge/order-status-badge.js.map +1 -0
- package/dist/particles/phone-field/phone-field.js +2 -2
- package/dist/particles/phone-field/phone-field.js.map +1 -1
- package/dist/particles/select/select.js +6 -6
- package/dist/particles/select/select.js.map +1 -1
- package/dist/particles/toast/toast.d.ts +1 -1
- package/dist/particles/toast/toast.js +32 -6
- package/dist/particles/toast/toast.js.map +1 -1
- package/dist/schema.graphql +1079 -54
- package/dist/sdk/actions/address-action-provider.d.ts +16 -0
- package/dist/sdk/actions/address-action-provider.js +20 -0
- package/dist/sdk/actions/address-action-provider.js.map +1 -0
- package/dist/sdk/actions/analytics-action-provider.js +1 -1
- package/dist/sdk/actions/index.d.ts +3 -1
- package/dist/sdk/actions/index.js +3 -1
- package/dist/sdk/actions/order-action-provider.d.ts +12 -0
- package/dist/sdk/actions/order-action-provider.js +16 -0
- package/dist/sdk/actions/order-action-provider.js.map +1 -0
- package/dist/sdk/actions/types.d.ts +6 -2
- package/dist/sdk/address/address-fields.js +38 -0
- package/dist/sdk/address/address-fields.js.map +1 -0
- package/dist/sdk/address/checkout-readiness.js +17 -0
- package/dist/sdk/address/checkout-readiness.js.map +1 -0
- package/dist/sdk/address/constants.js +60 -0
- package/dist/sdk/address/constants.js.map +1 -0
- package/dist/sdk/address/country-display.js +19 -0
- package/dist/sdk/address/country-display.js.map +1 -0
- package/dist/sdk/address/country-rules.js +30 -0
- package/dist/sdk/address/country-rules.js.map +1 -0
- package/dist/sdk/address/format-address.js +18 -0
- package/dist/sdk/address/format-address.js.map +1 -0
- package/dist/sdk/address/iso-countries.js +262 -0
- package/dist/sdk/address/iso-countries.js.map +1 -0
- package/dist/sdk/address/layouts.js +56 -0
- package/dist/sdk/address/layouts.js.map +1 -0
- package/dist/sdk/address/messages.js +97 -0
- package/dist/sdk/address/messages.js.map +1 -0
- package/dist/sdk/address/operations.d.ts +54 -0
- package/dist/sdk/address/operations.js +83 -0
- package/dist/sdk/address/operations.js.map +1 -0
- package/dist/sdk/address/postal-code-lookup-operations.js +23 -0
- package/dist/sdk/address/postal-code-lookup-operations.js.map +1 -0
- package/dist/sdk/address/postal-code.js +11 -0
- package/dist/sdk/address/postal-code.js.map +1 -0
- package/dist/sdk/address/schema.js +14 -0
- package/dist/sdk/address/schema.js.map +1 -0
- package/dist/sdk/address/server-fields.js +25 -0
- package/dist/sdk/address/server-fields.js.map +1 -0
- package/dist/sdk/address/switch-country.js +57 -0
- package/dist/sdk/address/switch-country.js.map +1 -0
- package/dist/sdk/address/types.d.ts +26 -0
- package/dist/sdk/address/use-address-actions.d.ts +29 -0
- package/dist/sdk/address/use-address-actions.js +247 -0
- package/dist/sdk/address/use-address-actions.js.map +1 -0
- package/dist/sdk/address/use-address-by-postal-code.js +57 -0
- package/dist/sdk/address/use-address-by-postal-code.js.map +1 -0
- package/dist/sdk/address/validate-address.js +62 -0
- package/dist/sdk/address/validate-address.js.map +1 -0
- package/dist/sdk/analytics/use-analytics-actions.js +2 -1
- package/dist/sdk/analytics/use-analytics-actions.js.map +1 -1
- package/dist/sdk/cache/storefront-cache.js +29 -4
- package/dist/sdk/cache/storefront-cache.js.map +1 -1
- package/dist/sdk/cart/use-cart-actions.js +9 -8
- package/dist/sdk/cart/use-cart-actions.js.map +1 -1
- package/dist/sdk/cart/use-cart-validate-on-open.js +2 -1
- package/dist/sdk/cart/use-cart-validate-on-open.js.map +1 -1
- package/dist/sdk/client/fetch-page-data.d.ts +11 -0
- package/dist/sdk/client/fetch-page-data.js +12 -1
- package/dist/sdk/client/fetch-page-data.js.map +1 -1
- package/dist/sdk/content/create-content-runtime.d.ts +22 -1
- package/dist/sdk/content/create-content-runtime.js +90 -9
- package/dist/sdk/content/create-content-runtime.js.map +1 -1
- package/dist/sdk/data/empty-content-value.js +16 -0
- package/dist/sdk/data/empty-content-value.js.map +1 -0
- package/dist/sdk/data/failed-fields.js +23 -0
- package/dist/sdk/data/failed-fields.js.map +1 -0
- package/dist/sdk/data/hot-data-provider.js +2 -1
- package/dist/sdk/data/hot-data-provider.js.map +1 -1
- package/dist/sdk/data/index.js +1 -1
- package/dist/sdk/data/page-reactive-data-root.d.ts +45 -7
- package/dist/sdk/data/page-reactive-data-root.js +88 -12
- package/dist/sdk/data/page-reactive-data-root.js.map +1 -1
- package/dist/sdk/data/variables-from-content.d.ts +43 -0
- package/dist/sdk/data/variables-from-content.js +57 -0
- package/dist/sdk/data/variables-from-content.js.map +1 -0
- package/dist/sdk/generated/fragment-types.js +2 -0
- package/dist/sdk/generated/fragment-types.js.map +1 -1
- package/dist/sdk/generated/gql.js +4 -1
- package/dist/sdk/generated/gql.js.map +1 -1
- package/dist/sdk/generated/graphql.d.ts +8 -0
- package/dist/sdk/generated/graphql.js +296 -1
- package/dist/sdk/generated/graphql.js.map +1 -1
- package/dist/sdk/i18n/messages/en-US.js +138 -1
- package/dist/sdk/i18n/messages/en-US.json +138 -1
- package/dist/sdk/i18n/messages/en-US.json.d.ts +137 -0
- package/dist/sdk/i18n/messages/es-ES.js +138 -1
- package/dist/sdk/i18n/messages/es-ES.json +138 -1
- package/dist/sdk/i18n/messages/pt-BR.js +138 -1
- package/dist/sdk/i18n/messages/pt-BR.json +138 -1
- package/dist/sdk/identity/use-identity-actions.js +5 -4
- package/dist/sdk/identity/use-identity-actions.js.map +1 -1
- package/dist/sdk/navigation/current-page.js +30 -0
- package/dist/sdk/navigation/current-page.js.map +1 -0
- package/dist/sdk/navigation/not-found-log.d.ts +28 -0
- package/dist/sdk/navigation/not-found-log.js +133 -0
- package/dist/sdk/navigation/not-found-log.js.map +1 -0
- package/dist/sdk/navigation/path.js +25 -0
- package/dist/sdk/navigation/path.js.map +1 -0
- package/dist/sdk/navigation/redirect.d.ts +11 -0
- package/dist/sdk/navigation/redirect.js +22 -0
- package/dist/sdk/navigation/redirect.js.map +1 -0
- package/dist/sdk/navigation/report.js +70 -0
- package/dist/sdk/navigation/report.js.map +1 -0
- package/dist/sdk/navigation/resolve-storefront-href.d.ts +12 -0
- package/dist/sdk/navigation/resolve-storefront-href.js +214 -0
- package/dist/sdk/navigation/resolve-storefront-href.js.map +1 -0
- package/dist/sdk/navigation/route-identity-provider.d.ts +11 -0
- package/dist/sdk/navigation/route-identity-provider.js +20 -0
- package/dist/sdk/navigation/route-identity-provider.js.map +1 -0
- package/dist/sdk/navigation/route-map-provider.d.ts +19 -0
- package/dist/sdk/navigation/route-map-provider.js +29 -0
- package/dist/sdk/navigation/route-map-provider.js.map +1 -0
- package/dist/sdk/navigation/storefront-link.d.ts +16 -0
- package/dist/sdk/navigation/storefront-link.js +66 -0
- package/dist/sdk/navigation/storefront-link.js.map +1 -0
- package/dist/sdk/navigation/types.d.ts +45 -0
- package/dist/sdk/navigation/use-storefront-navigation.d.ts +26 -0
- package/dist/sdk/navigation/use-storefront-navigation.js +73 -0
- package/dist/sdk/navigation/use-storefront-navigation.js.map +1 -0
- package/dist/sdk/navigation/use-storefront-route.d.ts +26 -0
- package/dist/sdk/navigation/use-storefront-route.js +87 -0
- package/dist/sdk/navigation/use-storefront-route.js.map +1 -0
- package/dist/sdk/navigation/use-storefront-search-params.d.ts +11 -0
- package/dist/sdk/navigation/use-storefront-search-params.js +16 -0
- package/dist/sdk/navigation/use-storefront-search-params.js.map +1 -0
- package/dist/sdk/orders/completion-badge.d.ts +8 -0
- package/dist/sdk/orders/completion-badge.js +47 -0
- package/dist/sdk/orders/completion-badge.js.map +1 -0
- package/dist/sdk/orders/order-operations.d.ts +19 -0
- package/dist/sdk/orders/order-operations.js +21 -0
- package/dist/sdk/orders/order-operations.js.map +1 -0
- package/dist/sdk/orders/use-order-actions.d.ts +23 -0
- package/dist/sdk/orders/use-order-actions.js +62 -0
- package/dist/sdk/orders/use-order-actions.js.map +1 -0
- package/dist/sdk/payment/gateway-origin.js +26 -13
- package/dist/sdk/payment/gateway-origin.js.map +1 -1
- package/dist/sdk/payment/gateway.d.ts +14 -2
- package/dist/sdk/payment/gateway.js +32 -14
- package/dist/sdk/payment/gateway.js.map +1 -1
- package/dist/sdk/payment/operations.js +11 -0
- package/dist/sdk/payment/operations.js.map +1 -1
- package/dist/sdk/payment/submission-registry.d.ts +2 -1
- package/dist/sdk/payment/submission-registry.js +12 -8
- package/dist/sdk/payment/submission-registry.js.map +1 -1
- package/dist/sdk/payment/use-payment-actions.d.ts +5 -3
- package/dist/sdk/payment/use-payment-actions.js +6 -3
- package/dist/sdk/payment/use-payment-actions.js.map +1 -1
- package/dist/sdk/payment/use-place-order.d.ts +6 -3
- package/dist/sdk/payment/use-place-order.js +334 -144
- package/dist/sdk/payment/use-place-order.js.map +1 -1
- package/dist/sdk/region/use-region-actions.js +2 -1
- package/dist/sdk/region/use-region-actions.js.map +1 -1
- package/dist/sdk/seo/page-alternates.d.ts +55 -0
- package/dist/sdk/seo/page-alternates.js +132 -0
- package/dist/sdk/seo/page-alternates.js.map +1 -0
- package/dist/sdk/session/read-server-session.d.ts +21 -0
- package/dist/sdk/session/read-server-session.js +61 -0
- package/dist/sdk/session/read-server-session.js.map +1 -0
- package/dist/sdk/session/use-session-actions.js +5 -4
- package/dist/sdk/session/use-session-actions.js.map +1 -1
- package/dist/sdk/session/use-session-revalidation.js +2 -1
- package/dist/sdk/session/use-session-revalidation.js.map +1 -1
- package/dist/sdk/shipping/use-shipping-actions.js +3 -2
- package/dist/sdk/shipping/use-shipping-actions.js.map +1 -1
- package/dist/utils/own-value.js +19 -0
- package/dist/utils/own-value.js.map +1 -0
- package/dist/utils/safe-href.d.ts +11 -0
- package/dist/utils/safe-href.js +31 -22
- package/dist/utils/safe-href.js.map +1 -1
- package/package.json +17 -2
- package/skills/storefront-asset/SKILL.md +111 -0
- package/skills/storefront-asset/references/api-side.md +153 -0
- package/skills/storefront-asset/references/findings.md +40 -0
- package/skills/storefront-asset/references/ui-side.md +94 -0
- package/src/styles/tailwind.css +27 -0
package/dist/docs/card-entry.md
CHANGED
|
@@ -70,7 +70,9 @@ While collapsed, `CardEntry` still answers a place-order attempt: it keeps its s
|
|
|
70
70
|
|
|
71
71
|
Collapsing clears the security code field, and only the security code. The card number, holder name, and expiration survive, so a shopper who switches method and switches back finds what they typed — no credit-card component in this package retains a security code across a visibility change.
|
|
72
72
|
|
|
73
|
-
The authored `disabled` prop is independent of
|
|
73
|
+
The authored `disabled` prop is independent of the collapse: a store that freezes the form with `disabled` sees no change, and a collapsed form may also be `disabled` — neither implies the other.
|
|
74
|
+
|
|
75
|
+
In the checkout, the card number, holder name, expiration, and security code are cleared after every outcome in which the card target ran: the card POST resolved clean, resolved with errors or threw, or the target refused before any request. They are kept when the submission was refused before the target ran (the form's own check, a refused or untrusted transaction, the submit gate, no method selected) so the shopper can fix them.
|
|
74
76
|
|
|
75
77
|
---
|
|
76
78
|
|
|
@@ -78,12 +80,12 @@ The authored `disabled` prop is independent of this: a store that freezes the fo
|
|
|
78
80
|
|
|
79
81
|
`CardEntry` renders the detected card network's icon at runtime, once the typed number matches a configured payment method's `validator.numberRegex` — the icon name is computed in component code, not read from a schema prop, so the compiler's prop-type-driven icon collection never sees it.
|
|
80
82
|
|
|
81
|
-
**Any store composing `CardEntry` (or `SavedCards` / `SavedCardOption`) must declare the
|
|
83
|
+
**Any store composing `CardEntry` (or `SavedCards` / `SavedCardOption`) must declare the six network icon names in `global.icons.include`:**
|
|
82
84
|
|
|
83
85
|
```json
|
|
84
86
|
{
|
|
85
87
|
"icons": {
|
|
86
|
-
"include": ["amex", "diners", "elo-card", "mastercard", "visa"]
|
|
88
|
+
"include": ["amex", "diners", "discover", "elo-card", "mastercard", "visa"]
|
|
87
89
|
}
|
|
88
90
|
}
|
|
89
91
|
```
|
|
@@ -94,7 +96,7 @@ The authored `disabled` prop is independent of this: a store that freezes the fo
|
|
|
94
96
|
{
|
|
95
97
|
"icons": {
|
|
96
98
|
"collection": "ph",
|
|
97
|
-
"include": ["amex", "diners", "elo-card", "mastercard", "visa"]
|
|
99
|
+
"include": ["amex", "diners", "discover", "elo-card", "mastercard", "visa"]
|
|
98
100
|
}
|
|
99
101
|
}
|
|
100
102
|
```
|
|
@@ -103,6 +105,34 @@ Copying the first snippet verbatim over an existing `icons` object silently drop
|
|
|
103
105
|
|
|
104
106
|
Omitting `include` entirely is silent too. The network icon renders as an empty 24×24 box instead of the card mark.
|
|
105
107
|
|
|
108
|
+
## Store setup: response headers
|
|
109
|
+
|
|
110
|
+
The card number and security code are typed into `CardEntry`'s raw fields and POSTed from the browser straight to the VTEX payment gateway, so the page that composes it needs a policy that names the vault host the card is POSTed to, forbids framing the page, and narrows what the page may load and call. The generator ships no default: the store declares it in `global.json` under `responseHeaders`, scoped by `routes` to the page that composes `CardEntry`.
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
{
|
|
114
|
+
"responseHeaders": [
|
|
115
|
+
{
|
|
116
|
+
"routes": ["/checkout"],
|
|
117
|
+
"headers": {
|
|
118
|
+
"Content-Security-Policy": "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https://acme.vtexvault.com; frame-ancestors 'none'; base-uri 'self'; object-src 'none'",
|
|
119
|
+
"Referrer-Policy": "strict-origin-when-cross-origin"
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
]
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
- **The vault host in `connect-src` is `https://{account}.vtexvault.com`, for the account the store serves.** That is the `NEXT_PUBLIC_ACCOUNT` the store is built with, which is not always `account.name` in `global.json`. Write the served account, with no wildcard: `https://*.vtexvault.com` would let a compromised script send the card to any tenant's vault.
|
|
127
|
+
- **A policy that names the legacy payments host (`vtexpayments.com.br`) makes the browser block the card POST.** The order cannot be placed and nothing else on the page reports why. The generated app calls its own GraphQL at the relative `/api/graphql`, so `'self'` covers it; a store built with an absolute `NEXT_PUBLIC_STOREFRONT_API_URL` must add that origin.
|
|
128
|
+
- **A rule's `routes` must name the page that composes `CardEntry`**, as the page's `route` spells it (`/checkout`, `/reserva/checkout/payment`). Renaming that page fails the compile instead of dropping the policy. A page added later that composes `CardEntry` carries nothing until its route is added to the rule.
|
|
129
|
+
- **`script-src 'unsafe-inline'` is a known limit, and the policy does not stop injected script from sending the card off the page.** A static header cannot carry a nonce, so the inline scripts Next.js emits need it, and script injected into the page runs with the same rights. `connect-src` closes only `fetch`, XHR, beacons and WebSocket. The policy still leaves three channels open to any https host: an image request (`img-src https:`, which the page needs for catalog images), a form submission (no `form-action`) and a navigation (CSP cannot restrict one). What today's ruled policy does give is the vault origin pinned, no `'unsafe-eval'`, a page no other site can frame (`frame-ancestors 'none'`) and no `http:` or wildcard source. It does not replace keeping untrusted script off the payment page.
|
|
130
|
+
- **`frame-ancestors 'none'`** blanks the page inside any iframe, including an editor preview.
|
|
131
|
+
- **reCAPTCHA needs the anti-bot origins, and the ruled policy above does not declare them yet.** The challenge frame and script come from `https://www.google.com` and `https://www.gstatic.com`, the origins `sdk/anti-bot` declares. The frame is blocked by `default-src 'self'` (no `frame-src`) and the script by `script-src 'self' 'unsafe-inline'`, so both need the anti-bot origins. The stores add them together with whoever wires `getAntiBotToken`; the header check accepts a `frame-src` that names only those two origins and rejects any other.
|
|
132
|
+
- **Under `next dev` the served `script-src` also carries `'unsafe-eval'`; production does not.** React Refresh evaluates code in the browser, so the generated `next.config.ts` adds `'unsafe-eval'` to the `script-src` of every Content-Security-Policy it serves only when `NODE_ENV` is `development` (what `next dev` sets), which is what `pnpm dev:example` runs. Any build whose `NODE_ENV` is not `development` (the default for `next build` and `next start`) serves the declared policy byte for byte, so the live header check still runs against them: a dev response shows a `script-src` the store never declared, which `scripts/assert-payment-page-headers.mjs` rejects by design, so run that script against `next start`.
|
|
133
|
+
|
|
134
|
+
To check a served page, run `node scripts/assert-payment-page-headers.mjs --url <page url> --vault-host https://<account>.vtexvault.com`.
|
|
135
|
+
|
|
106
136
|
---
|
|
107
137
|
|
|
108
138
|
## Components
|
|
@@ -124,7 +154,8 @@ The only component. No internal sub-parts are separately schema-addressable.
|
|
|
124
154
|
| `cvvPlaceholder` | string | — | CVV field placeholder. |
|
|
125
155
|
| `cvvDescription` | string | `"The 3-4 digit number on your card"` | Helper text under the CVV field. Empty string renders nothing. |
|
|
126
156
|
| `numberRequiredMessage` | string | `"Card number is required"` | Shown when the card-number field is left blank. |
|
|
127
|
-
| `numberInvalidMessage` | string | `"Enter a valid card number"` | Shown for a Luhn-invalid number, or one
|
|
157
|
+
| `numberInvalidMessage` | string | `"Enter a valid card number"` | Shown for a Luhn-invalid number, or one a configured network claims only as a prefix (the wrong length, or two networks at once). |
|
|
158
|
+
| `networkNotAcceptedMessage` | string | `"This card is not from a network the store accepts"` | Shown for a Luhn-valid number that no configured network claims at all. |
|
|
128
159
|
| `holderNameRequiredMessage` | string | `"Cardholder name is required"` | Shown when the holder-name field is left blank and the detected method requires it. |
|
|
129
160
|
| `expirationRequiredMessage` | string | `"Expiration date is required"` | Shown when the expiration field is left blank and the detected method requires it. |
|
|
130
161
|
| `expirationInvalidMessage` | string | `"Enter a valid expiration date"` | Shown for a structurally malformed `MM/YY`. |
|
|
@@ -208,7 +239,7 @@ Style `CardEntry`'s root as a vertical stack of fields, matching a typical card
|
|
|
208
239
|
| Field inputs (`data-fs-field-control`) | The bordered text input | `border border-[#CCCCCC] rounded-[6px] px-[12px] py-[10px] text-[15px] w-full` |
|
|
209
240
|
| Field errors (`data-fs-field-error`) | Inline validation message, small and red | `text-[12px] text-[#C8102E] mt-[4px] block` |
|
|
210
241
|
| CVV helper text (`data-fs-card-entry-cvv-description`) | Small muted line under the CVV field | `text-[12px] text-[#666666] mt-[4px] block` |
|
|
211
|
-
| Placing (`data-fs-card-entry-placing`) | Present while an order-placement sequence is in flight (T28); the whole root is also `inert` and `aria-disabled` at that point, so style this hook rather than relying on pointer events alone | `opacity-60 cursor-not-allowed` |
|
|
242
|
+
| Placing (`data-fs-card-entry-placing`) | Present while an order-placement sequence is in flight (T28), and while the order attempt is resume-only (its card may already have been sent, so the fields do not accept input) until the attempt is freed; the whole root is also `inert` and `aria-disabled` at that point, so style this hook rather than relying on pointer events alone | `opacity-60 cursor-not-allowed` |
|
|
212
243
|
| Collapsed (`data-fs-card-entry-collapsed`) | Present on the styled root while the card payment is collapsed — the persisted selection is a method this section does not serve or one that is not a card, and a picker is composed to un-hide it (see Reveal and collapse); the root is also `inert`. **No transition or animation can run on it**: the actual hide is a `hidden` attribute one level up, on an unstyled wrapper this node cannot reach with any class, and an ancestor's `display:none` removes the whole subtree from rendering the instant it applies, before any transition on a descendant could ever paint. Use this hook only for one-shot conditional styling of the (already-unrendered) subtree, never for an entrance/exit animation | `opacity-60` |
|
|
213
244
|
|
|
214
245
|
Styled minimal example:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# CardholderDocument
|
|
2
2
|
|
|
3
3
|
**Category:** commerce
|
|
4
|
-
**Purpose:** A single tax-document input
|
|
4
|
+
**Purpose:** A single tax-document input for the checkout payment step. The store's country picks the document (SSN for the United States, CPF for Brazil, SIN for Canada, RFC for Mexico); the currently selected payment method's server-driven configuration shows or hides it and marks it required.
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -11,12 +11,12 @@ Use these signals to detect that a CardholderDocument block is present. Position
|
|
|
11
11
|
|
|
12
12
|
A CardholderDocument block is:
|
|
13
13
|
|
|
14
|
-
- A **single labeled text input**, formatted
|
|
15
|
-
- Labeled **"CPF"** or a similar tax-document label — never "Card number", "Expiration", or "CVV".
|
|
14
|
+
- A **single labeled text input**, formatted like `123.456.789-01` (CPF), `123-45-6789` (SSN), `046-454-286` (SIN) or `ABCD010101AB1` (RFC).
|
|
15
|
+
- Labeled **"CPF"**, **"SSN"**, **"SIN"**, **"RFC"** or a similar tax-document label — never "Card number", "Expiration", or "CVV".
|
|
16
16
|
- Not accompanied by a network icon, a "•••• 1234" masked number, or any card-brand logo — those belong to `CardEntry` or `SavedCards`, not this block.
|
|
17
17
|
- Sometimes marked with a required indicator (an asterisk or similar) next to its label; sometimes not — both are valid, since requiredness is server-driven per payment method.
|
|
18
18
|
|
|
19
|
-
If the image shows a **card-entry form with one extra plain text field formatted like a
|
|
19
|
+
If the image shows a **card-entry form with one extra plain text field formatted like a tax ID (CPF, SSN, SIN or RFC)**, use `CardholderDocument`. Do not use it for the shopper's account/profile document field — that is a different, identity-step component this block never composes with or reads from.
|
|
20
20
|
|
|
21
21
|
---
|
|
22
22
|
|
|
@@ -28,7 +28,7 @@ If the image shows a **card-entry form with one extra plain text field formatted
|
|
|
28
28
|
|
|
29
29
|
- The shopper's saved profile/identity document (a client-identity or user-profile field) → use the identity-step document component instead. `CardholderDocument` is a payment-time value, deliberately separate — it never reads or writes the stored profile document, because the epic's RFC records that the two may differ.
|
|
30
30
|
- A generic, data-agnostic tax-document input with no server-driven presence/requiredness → use the `DocumentField` particle directly instead; `CardholderDocument` exists specifically to wire that particle to the selected payment method's validator.
|
|
31
|
-
-
|
|
31
|
+
- A business document (CNPJ, EIN, BN, the corporate RFC) → not offered; only the four person documents render.
|
|
32
32
|
|
|
33
33
|
---
|
|
34
34
|
|
|
@@ -50,7 +50,7 @@ Child order reflects visual order. There is no parent/child relationship for thi
|
|
|
50
50
|
**Composition rules:**
|
|
51
51
|
|
|
52
52
|
- Must be inside `PaymentSectionRoot` or `PaymentSectionController`. Outside either, it throws.
|
|
53
|
-
- Renders `null` (no DOM at all) when the selected payment method's validator does not mark a document displayable,
|
|
53
|
+
- Renders `null` (no DOM at all) when the selected payment method's validator does not mark a document displayable, when no method is selected yet, or when the store's country has no document type (an unlisted country, or no country data). This is normal, not an error — most methods most of the time render nothing here.
|
|
54
54
|
- Also renders `null` while the card payment is collapsed — the persisted selection is a method that is not a card, or one the section does not serve, and a composed `PaymentMethodList` can bring the card form back (see [[payment]]) — whatever that method's own validator says. When the card comes back, the field re-seeds from the value already typed.
|
|
55
55
|
- Takes no children; passing any is a no-op.
|
|
56
56
|
|
|
@@ -60,18 +60,20 @@ Child order reflects visual order. There is no parent/child relationship for thi
|
|
|
60
60
|
|
|
61
61
|
### CardholderDocument
|
|
62
62
|
|
|
63
|
-
The field itself. Renders the `DocumentField` particle for CPF, with presence and requiredness resolved from `usePayment().selectedMethod.validator` (`documentDisplayable` / `documentRequired`) rather than from any prop.
|
|
63
|
+
The field itself. Renders the `DocumentField` particle for the type `usePayment().countryDocumentType` resolves (`USA` SSN, `BRA` CPF, `CAN` SIN, `MEX` RFC), with presence and requiredness resolved from `usePayment().selectedMethod.validator` (`documentDisplayable` / `documentRequired`) rather than from any prop.
|
|
64
64
|
|
|
65
65
|
| Prop | Type | Default | Notes |
|
|
66
66
|
|------|------|---------|-------|
|
|
67
|
-
| `label` | `string` | `
|
|
68
|
-
| `placeholder` | `string` | `
|
|
69
|
-
| `errorMessage` | `string` | `'Invalid
|
|
67
|
+
| `label` | `string` | the type's name (`SSN`, `CPF`, `SIN`, `RFC`) | The field's visible label. |
|
|
68
|
+
| `placeholder` | `string` | the type's own (`000-00-0000`, `000.000.000-00`, `000-000-000`, `AAAA000000AAA`) | Shown in the empty input as a format hint. |
|
|
69
|
+
| `errorMessage` | `string` | `'Invalid '` + the type's name | Shown inline when the typed value fails the type's validation on blur. |
|
|
70
70
|
| `disabled` | `boolean` | `false` | Disables the input without hiding it — independent of the data-driven presence gate. |
|
|
71
71
|
|
|
72
|
-
No `documentType` prop —
|
|
72
|
+
No `documentType` prop — the store's country decides it. No `required` prop — requiredness is always read from the selected method's validator, never authored.
|
|
73
73
|
|
|
74
|
-
**Data:** declares no `fragment` of its own. It reads `selectedMethod`, `draft`, and `setDraftDocument` off the ambient `payment` context that `PaymentSectionRoot` / `PaymentSectionController` already fetches for.
|
|
74
|
+
**Data:** declares no `fragment` of its own. It reads `selectedMethod`, `countryDocumentType`, `draft`, and `setDraftDocument` off the ambient `payment` context that `PaymentSectionRoot` / `PaymentSectionController` already fetches for.
|
|
75
|
+
|
|
76
|
+
**Focus on refusal:** while the field is on screen and not `disabled`, it registers itself so that when `PlaceOrder` refuses an order because the document is missing or malformed, keyboard focus moves to the `<input>`. The reason stays in `PlaceOrder`'s existing alert. Focus moves only on the refused click, and never for a refusal the gateway returned. With the field absent or `disabled`, nothing moves.
|
|
75
77
|
|
|
76
78
|
---
|
|
77
79
|
|
|
@@ -98,7 +100,7 @@ No `documentType` prop — this build supports CPF only. No `required` prop —
|
|
|
98
100
|
## Common mistakes
|
|
99
101
|
|
|
100
102
|
- **Nesting `CardholderDocument` inside `CardEntry`.** It is a sibling under the same `PaymentSectionRoot`, never a child — `CardEntry` does not accept children.
|
|
101
|
-
- **Passing a `documentType`, `required`, `countryCode`, or `document` prop.** None exist.
|
|
103
|
+
- **Passing a `documentType`, `required`, `countryCode`, or `document` prop.** None exist. The document type follows the store's country; requiredness and presence are always read from the selected method's validator, never authored; the typed value is not a prop at all — it flows into the shared payment draft internally.
|
|
102
104
|
- **Using this component for the shopper's saved profile document.** That is a different, identity-step field this component never reads from or writes to — the two are intentionally separate, even for the same shopper.
|
|
103
105
|
- **Expecting it to render outside a `PaymentSectionRoot` / `PaymentSectionController`.** It throws — the same requirement every other payment leaf (`CardEntry`, `Installments`, `SavedCards`, …) has.
|
|
104
106
|
- **Treating a blank render as broken.** Most of the time, for most payment methods, this component correctly renders nothing — that is the "not displayable" state, not a bug.
|
|
@@ -107,7 +109,7 @@ No `documentType` prop — this build supports CPF only. No `required` prop —
|
|
|
107
109
|
|
|
108
110
|
## Known limitations
|
|
109
111
|
|
|
110
|
-
- **
|
|
112
|
+
- **Four person documents, by store country.** The country comes from `Payment.storeCountryCode` and `Payment.countries`. A store whose country resolves to no document type shows no field, refuses nothing and sends no document. A document typed while the field was shown is posted only while the selected method still asks for one and the country still resolves a type; the draft itself is not cleared. `label`, `placeholder` and `errorMessage` have no catalog default (the right copy depends on the country), so leave them unset unless the store serves one country.
|
|
111
113
|
- **Server-driven requiredness renders the field correctly and is also enforced at submit time — but not by this component or by `CardEntry`.** This component marks the field required when the validator says so; a required-but-blank or malformed value (whether or not required) blocks Place Order client-side, before any transaction opens, **while the selected method's validator also says the document is displayable**. That gate lives in `matter/payment/use-payment-submit-gate.ts` (T24) and is consumed by `PlaceOrder`, not by this component or by `CardEntry`'s own `validateDraft` — this component's only job stays publishing `draft.document` via `setDraftDocument`. When the *currently* selected method's validator says `documentDisplayable: false`, the gate treats `draft.document` as inert either way (fix pass, findings R1/S4/S5): there is no field on screen for the shopper to read a leftover value from or correct it in, whether that value is left over from a previously selected, displayable method or simply blank. See `specs/cardholder-document-submit-gate.md` for the gate's full contract.
|
|
112
114
|
|
|
113
115
|
---
|
package/dist/docs/cart-item.md
CHANGED
|
@@ -53,7 +53,7 @@ CartItemRoot
|
|
|
53
53
|
|
|
54
54
|
**It names itself from what it wraps.** The link adds no `aria-label`, so its accessible name is the image's alt text (`image.altText ?? variant.name`). On a line whose `variant.image` is `null` the leaf renders its children unwrapped instead of wrapping nothing, because an anchor with no content is a keyboard focus stop with no accessible name.
|
|
55
55
|
|
|
56
|
-
**No usable product URL, no link.** The leaf runs `detailUrl` through `resolveSafeHref`, the same allowlist the navigation particle applies to CMS-authored destinations, and renders its children unwrapped when the destination is blank or refused: `javascript:`, `data:`, protocol-relative, or malformed. The particle gates only `$content.href`, so a platform URL arriving on the `href` prop is this leaf's to validate. Either way the image still shows: the leaf never self-hides, unlike the data-bearing leaves below, because hiding a wrapper would take its content with it. A refusal logs its reason and never the value; a blank URL is ordinary and stays quiet.
|
|
56
|
+
**No usable product URL, no link.** The leaf runs `detailUrl` through `resolveSafeHref`, the same allowlist the navigation particle applies to CMS-authored destinations, and renders its children unwrapped when the destination is blank or refused: `javascript:`, `data:`, protocol-relative, or malformed. A safe `detailUrl` is a logical path: `NavigationLink` prefixes it for the current binding. The particle gates only `$content.href`, so a platform URL arriving on the `href` prop is this leaf's to validate. Either way the image still shows: the leaf never self-hides, unlike the data-bearing leaves below, because hiding a wrapper would take its content with it. A refusal logs its reason and never the value and still renders the children unwrapped; a blank URL is ordinary and stays quiet.
|
|
57
57
|
|
|
58
58
|
Navigation is client-side through the `NavigationLink` particle, which also owns `rel` hardening. The link is same-tab, and `target` is omitted from the props type rather than merely left out of the schema, because an image-only link cannot carry the "(opens in new tab)" cue a `_blank` destination needs.
|
|
59
59
|
|
package/dist/docs/cart.md
CHANGED
|
@@ -65,7 +65,7 @@ What happens after a successful add to cart is a **per-store choice made by comp
|
|
|
65
65
|
|
|
66
66
|
- **Mini-cart store → `CartOpenOnAdd`.** When the store has a mini-cart drawer, compose `CartOpenOnAdd` as the **parent of the mini-cart `DrawerRoot`** (its single child). It opens the drawer automatically on each successful add, with the new item visible and the count updated. It controls the drawer internally, so **do not set raw `open` / `onOpenChange` on `DrawerRoot`** — those are not authorable props, and the header `DrawerTrigger` plus manual close (Escape / backdrop / close button) keep working through the encapsulated wiring.
|
|
67
67
|
|
|
68
|
-
- **No-mini-cart store → `CartRedirectOnAdd`.** When the store has **no** mini-cart and adding a product should send the shopper straight to checkout, compose `CartRedirectOnAdd` (and omit the drawer entirely). It navigates to `href` (default
|
|
68
|
+
- **No-mini-cart store → `CartRedirectOnAdd`.** When the store has **no** mini-cart and adding a product should send the shopper straight to checkout, compose `CartRedirectOnAdd` (and omit the drawer entirely). It navigates to `href` (default the checkout page, `{ "standard": "checkout" }`) after each successful add. It renders no UI of its own; place it once in the layout.
|
|
69
69
|
|
|
70
70
|
The two are **mutually exclusive — compose exactly one**. A store with a mini-cart uses `CartOpenOnAdd` and never `CartRedirectOnAdd`; a store without one uses `CartRedirectOnAdd` and omits the drawer. Both react only to a **successful** add (a failed add or one returning user errors triggers neither).
|
|
71
71
|
|
|
@@ -87,7 +87,7 @@ CartRoot (layout)
|
|
|
87
87
|
```
|
|
88
88
|
CartRoot (layout)
|
|
89
89
|
├── Header (add-to-cart CTAs elsewhere; no drawer)
|
|
90
|
-
└── CartRedirectOnAdd ← navigates to
|
|
90
|
+
└── CartRedirectOnAdd ← navigates to the checkout page on a successful add
|
|
91
91
|
```
|
|
92
92
|
|
|
93
93
|
---
|
|
@@ -230,7 +230,7 @@ Neither leaf renders a wrapper or carries spacing, so **order, grouping, and any
|
|
|
230
230
|
Continue-shopping is a **non-mutating** control, not a cart action. Which control depends on the surface:
|
|
231
231
|
|
|
232
232
|
- **Inside the mini-cart drawer**, use `CartContinueShopping` — it closes the drawer through the drawer's own contract and dispatches no cart write.
|
|
233
|
-
- **On a cart or checkout page** (no drawer to close), use a storefront `NavigationLink` (e.g. `href=
|
|
233
|
+
- **On a cart or checkout page** (no drawer to close), use a storefront `NavigationLink` (e.g. `href={{ page: 'home' }}`) back to browsing. Do **not** place `CartContinueShopping` there: it is a drawer close, and without a `DrawerRoot` ancestor the render fails.
|
|
234
234
|
|
|
235
235
|
```text
|
|
236
236
|
CartRoot (layout)
|
|
@@ -259,7 +259,7 @@ CartRoot (layout)
|
|
|
259
259
|
"popup-body": { "type": "CartList", "children": ["cart-item-template"] },
|
|
260
260
|
"subtotal-row": { "type": "CartTotal", "props": { "label": "subtotal" } },
|
|
261
261
|
"total-row": { "type": "CartTotal", "props": { "label": "total" } },
|
|
262
|
-
"checkout-btn": { "type": "CartGoCheckout", "props": { "href": "
|
|
262
|
+
"checkout-btn": { "type": "CartGoCheckout", "props": { "href": { "standard": "checkout" }, "children": "continuar" } },
|
|
263
263
|
|
|
264
264
|
"cart-empty": { "type": "CartEmpty", "children": ["empty-illustration", "empty-msg", "empty-footer"] },
|
|
265
265
|
"empty-illustration": { "type": "Icon", "props": { "name": "shopping-bag" } },
|
|
@@ -275,7 +275,7 @@ On a cart/checkout page there is no drawer to close, so the empty branch keeps `
|
|
|
275
275
|
{
|
|
276
276
|
"cart-empty": { "type": "CartEmpty", "children": ["empty-msg", "keep-shopping-link"] },
|
|
277
277
|
"empty-msg": { "type": "CartEmptyMessage", "props": { "text": "sua cesta está vazia" } },
|
|
278
|
-
"keep-shopping-link": { "type": "NavigationLink", "props": { "href": "
|
|
278
|
+
"keep-shopping-link": { "type": "NavigationLink", "props": { "href": { "page": "home" }, "children": "continuar comprando" } }
|
|
279
279
|
}
|
|
280
280
|
```
|
|
281
281
|
|
|
@@ -307,7 +307,7 @@ The mini-cart drawer (the layout composition described on `CartRoot`) ends in a
|
|
|
307
307
|
|
|
308
308
|
- **`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.
|
|
309
309
|
- **`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.
|
|
310
|
-
- **`CartGoCheckout`** is the link to checkout (default `href`
|
|
310
|
+
- **`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.
|
|
311
311
|
|
|
312
312
|
**The button wording is CMS content.** It resolves in a fixed order: the `cart-checkout-label` entry, then the `label` prop, then `children`, then the package default `"Checkout"`. So a merchant rewords the CTA — `"Finalizar compra"`, `"Ir para o pagamento"` — with a CMS save and no deployment, while a store with no CMS binding renders its authored value. `children` stays supported because that is where stores labelled the button before `label` existed; a CMS entry overrides it with no schema edit. A blank or whitespace-only entry value counts as unconfigured and falls through. Non-compiler hosts (Storybook, tests) pass a typed `$content` fixture directly.
|
|
313
313
|
|
|
@@ -315,7 +315,7 @@ The mini-cart drawer (the layout composition described on `CartRoot`) ends in a
|
|
|
315
315
|
|
|
316
316
|
| Prop | Type | Required | Notes |
|
|
317
317
|
|-------|------|----------|-------|
|
|
318
|
-
| `href` | string | no | Checkout destination, default
|
|
318
|
+
| `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 |
|
|
319
319
|
| `label` | string | no | Authored fallback for the wording. Ignored when an entry supplies a label |
|
|
320
320
|
| `children` | node | no | Legacy label channel, still honoured. Element children are replaced when an entry supplies a label |
|
|
321
321
|
|
|
@@ -332,7 +332,7 @@ Schema shape (inside the `DrawerPopup` footer `Container`):
|
|
|
332
332
|
"popup-footer": { "type": "Container", "children": ["checkout-cta"] },
|
|
333
333
|
"checkout-cta": { "type": "CartCheckoutGuard", "children": ["checkout-total", "checkout-btn"] },
|
|
334
334
|
"checkout-total": { "type": "CartTotal", "props": { "label": "Total" } },
|
|
335
|
-
"checkout-btn": { "type": "CartGoCheckout", "props": { "href": "
|
|
335
|
+
"checkout-btn": { "type": "CartGoCheckout", "props": { "href": { "standard": "checkout" }, "label": "Finalizar compra" } }
|
|
336
336
|
}
|
|
337
337
|
```
|
|
338
338
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# ClientProfileFieldset
|
|
2
2
|
|
|
3
3
|
**Category:** identity
|
|
4
|
-
**Purpose:** The composable, one-Save write of the `ClientProfile` entity. Registers itself with the enclosing `FormRoot` under the `clientProfile` namespace and dispatches at most one `identity.clientProfileUpdate` when the shopper presses that form's submit. Four bound controls — first name, last name, phone, document — compose freely inside it, in any order or subset.
|
|
4
|
+
**Purpose:** The composable, one-Save write of the `ClientProfile` entity. Registers itself with the enclosing `FormRoot` under the `clientProfile` namespace and dispatches at most one `identity.clientProfileUpdate` when the shopper presses that form's submit. Four bound controls — first name, last name, phone, document (CPF, SSN, SIN or RFC) — compose freely inside it, in any order or subset.
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -65,7 +65,7 @@ SessionRoot (required ancestor; session tri-state +
|
|
|
65
65
|
| Prop | Type | Default | Notes |
|
|
66
66
|
|------|------|---------|-------|
|
|
67
67
|
| `country` | `'US' \| 'BR'` | `'US'` | Phone mask/validation country, provided to the phone control via context. |
|
|
68
|
-
| `documentType` | string | — |
|
|
68
|
+
| `documentType` | string | — | One of `'CPF'`, `'SSN'`, `'SIN'` or `'RFC'` (upper case). The document control renders only when supported, and the payload carries `document` only for a supported type. |
|
|
69
69
|
| `skeletonCount` | number | `4` | Placeholder rows drawn while the profile resolves. Set it to the number of controls composed. |
|
|
70
70
|
| `loadingLabel` | string | `'Loading your details'` | Announced politely while the profile resolves. Blank means no announcement. |
|
|
71
71
|
| `loadedLabel` | string | `'Your details are ready'` | Announced politely once the controls mount. Blank means no announcement. |
|
|
@@ -105,12 +105,14 @@ governs visibility (see *Switching the phone field off* below).
|
|
|
105
105
|
|
|
106
106
|
| Prop | Type | Default | Notes |
|
|
107
107
|
|------|------|---------|-------|
|
|
108
|
-
| `label` | string | `'CPF'` | |
|
|
108
|
+
| `label` | string | the document type's name (`'CPF'`, `'SSN'`, `'SIN'` or `'RFC'`) | |
|
|
109
109
|
| `placeholder` | string | — | |
|
|
110
110
|
| `errorMessage` | string | — | |
|
|
111
111
|
|
|
112
|
-
Renders nothing, and registers no field name, when the fieldset's `documentType` is unsupported.
|
|
113
|
-
the `
|
|
112
|
+
Renders nothing, and registers no field name, when the fieldset's `documentType` is unsupported. The mask,
|
|
113
|
+
the validation and the `autocomplete` hint (`off` for SSN and SIN) come from the document type; the saved
|
|
114
|
+
`document` string is the type's sanitised value (digits for CPF, SSN and SIN, letters kept for RFC), the
|
|
115
|
+
same string the card form sends. Composes the `DocumentField` particle. Recomposable (RFC:503): given children, they replace `DocumentField`'s
|
|
114
116
|
default `Field.Label` + `DocumentFieldInput` + `Field.Error` anatomy, in any order; childless keeps
|
|
115
117
|
today's order and text.
|
|
116
118
|
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# CopyText
|
|
2
|
+
|
|
3
|
+
**Category:** action
|
|
4
|
+
**Purpose:** Copies one string the caller supplies and confirms the result inline.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Visual cues (how to identify in an image)
|
|
9
|
+
|
|
10
|
+
A small action beside an identifier, with a short confirmation that appears after the action and can be dismissed. The image is the source of truth for layout.
|
|
11
|
+
|
|
12
|
+
## When to use
|
|
13
|
+
|
|
14
|
+
Any screen that needs one action to copy a single string, such as an order number.
|
|
15
|
+
|
|
16
|
+
## When NOT to use
|
|
17
|
+
|
|
18
|
+
- Rendering the identifier itself. Pass the string in; do not ask `CopyText` to display the heading.
|
|
19
|
+
- A toast or a page-level notification. The confirmation stays with the action.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Composition
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
CopyText
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`CopyText` is one element. The caller passes the visible label or icon as `children`.
|
|
30
|
+
|
|
31
|
+
## Components
|
|
32
|
+
|
|
33
|
+
### CopyText
|
|
34
|
+
|
|
35
|
+
| Prop | Type | Default | Purpose |
|
|
36
|
+
|---|---|---|---|
|
|
37
|
+
| `accessibleName` | string | `Copy` | Accessible name of the action |
|
|
38
|
+
| `successMessage` | string | `Copied` | Announced after a successful copy |
|
|
39
|
+
| `failureMessage` | string | `Could not copy` | Announced when the clipboard rejects the write |
|
|
40
|
+
| `dismissLabel` | string | `Dismiss` | Accessible name of the dismiss control |
|
|
41
|
+
|
|
42
|
+
`text` is required and is not a schema prop. The caller supplies the exact string to copy. `children` is the visible label or icon, and it is not a schema prop either.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Canonical schema example
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"copy-identifier": {
|
|
51
|
+
"type": "CopyText",
|
|
52
|
+
"props": {
|
|
53
|
+
"accessibleName": "Copy order number",
|
|
54
|
+
"successMessage": "Copied",
|
|
55
|
+
"failureMessage": "Could not copy",
|
|
56
|
+
"dismissLabel": "Dismiss"
|
|
57
|
+
},
|
|
58
|
+
"children": []
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The screen that owns the identifier passes `text` and `children` at runtime. Do not author the identifier in the page.
|
|
64
|
+
|
|
65
|
+
## Common mistakes
|
|
66
|
+
|
|
67
|
+
- **OrderDetailsHeader** renders the number. `CopyText` only copies the string it is given.
|
|
68
|
+
- Passing the heading, including a prefix such as "Order #", copies that whole string. Pass the identifier alone.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Styling
|
|
73
|
+
|
|
74
|
+
| Component | What to style | Plausible classes |
|
|
75
|
+
|---|---|---|
|
|
76
|
+
| `CopyText` | The action and the inline confirmation | `inline-flex items-center gap-[8px] text-[14px]` |
|
|
77
|
+
|
|
78
|
+
Style the hooks `data-fs-copy-text`, `data-fs-copy-text-action`, `data-fs-copy-text-message`, and `data-fs-copy-text-outcome`. The component ships no CSS.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Related
|
|
83
|
+
|
|
84
|
+
- [[button]] — the action primitive this control composes.
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# DocumentField
|
|
2
2
|
|
|
3
3
|
**Category:** content
|
|
4
|
-
**Purpose:** A presentational tax-document input that composes the `Field` particle (label + native `<input>` + inline error). It applies
|
|
4
|
+
**Purpose:** A presentational tax-document input that composes the `Field` particle (label + native `<input>` + inline error). It applies the mask of its document type on every change (CPF `###.###.###-##`, SSN `###-##-####`, SIN `###-###-###`, or RFC, thirteen upper-case letters and digits) and runs that type's validation on blur/submit. It is data-agnostic — value flows through props; it consumes no GraphQL and no domain context.
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
## Visual cues (how to identify in an image)
|
|
9
9
|
|
|
10
|
-
- A single-line text input labelled **"CPF"** (or another tax-document name), usually on a checkout identification step, near the email/phone fields.
|
|
11
|
-
- Shows a masked placeholder like `000.000.000-00` and formats
|
|
10
|
+
- A single-line text input labelled **"CPF"**, **"SSN"**, **"SIN"** or **"RFC"** (or another tax-document name), usually on a checkout identification step, near the email/phone fields.
|
|
11
|
+
- Shows a masked placeholder like `000.000.000-00` (CPF), `000-00-0000` (SSN), `000-000-000` (SIN) or `AAAA000000AAA` (RFC) and formats characters as they are typed.
|
|
12
12
|
- When invalid, an inline error below the input (e.g. *"Enter a valid CPF."*).
|
|
13
13
|
|
|
14
14
|
If the image shows a checkout identification step with a tax-document field, use `DocumentField`.
|
|
@@ -61,15 +61,15 @@ react-hook-form and loses the mask — unsupported, the RFC's named double-binde
|
|
|
61
61
|
| `label` | string | — | Accessible label. |
|
|
62
62
|
| `placeholder` | string | — | Input placeholder. |
|
|
63
63
|
| `disabled` | boolean | `false` | Disables the input (e.g. while a write is in flight). |
|
|
64
|
-
| `requirement` | `'mandatory' \| 'optional'` | — | Raises the field to required, announced as `aria-required` (never the native attribute). Unset is no opinion, which is what keeps
|
|
64
|
+
| `requirement` | `'mandatory' \| 'optional'` | — | Raises the field to required, announced as `aria-required` (never the native attribute). Unset is no opinion, which is what keeps the document Optional by Recommendation, unlike email. Bound to a fieldset whose rule already says required, `'optional'` does not lower it. |
|
|
65
65
|
| `name` | string | `'document'` | Field/input name. |
|
|
66
|
-
| `documentType` | `'CPF'` | `'CPF'` | Selects the mask
|
|
66
|
+
| `documentType` | `'CPF' \| 'SSN' \| 'SIN' \| 'RFC'` | `'CPF'` | Selects the mask, sanitiser, validator, digit-only input mode and `autocomplete`. `DOCUMENTS` holds one entry per type; the API's lower-case ids (`cpf`, `ssn`, `sin`, `rfc`) go through `documentTypeFromId`. |
|
|
67
67
|
| `ref` | `Ref<HTMLInputElement>` | — | Lands on the `<input>` `Field.Control` renders — **not on the wrapper `<div>`, as it did before** (a deliberate, source-breaking change). Composed with react-hook-form's own ref on the bound path — a caller ref and react-hook-form's ref are both honoured. |
|
|
68
68
|
| `children` | `ReactNode` | — | Given, replaces the default `Field.Label` + `DocumentFieldInput` + `Field.Error` anatomy, in any order (RFC:503). |
|
|
69
69
|
|
|
70
|
-
**Masking:** applied progressively on every change; input is never blocked.
|
|
70
|
+
**Masking:** applied progressively on every change; input is never blocked. The type's sanitiser runs first: digit-only types (CPF, SSN, SIN) strip non-digits and hint `inputMode="numeric"`; RFC upper-cases and keeps only `A-Z` and `0-9`, and carries no `inputMode`. SSN and SIN inputs carry `autocomplete="off"` so the browser does not offer the number back; CPF and RFC carry no `autocomplete` attribute. The attribute is a request, not a guarantee.
|
|
71
71
|
|
|
72
|
-
**Validation:** the check
|
|
72
|
+
**Validation:** the type's rule (CPF check digits; SSN area, group and serial ranges; SIN Luhn check; RFC structure with a plausible month and day) is checked on blur/submit only — never per keystroke. An **empty** value is valid (the field is optional). A prior error clears while the shopper edits and is re-evaluated on the next blur.
|
|
73
73
|
|
|
74
74
|
---
|
|
75
75
|
|
|
@@ -82,7 +82,7 @@ runs the plain, unbound behaviour documented above, unaltered.
|
|
|
82
82
|
- **What the contract supplies**: `label` and `placeholder`, when the particle's own prop is omitted (an
|
|
83
83
|
explicit prop always wins); `defaultValue`, seeded into `useController`; and `rule`, merged with the
|
|
84
84
|
particle's own check-digit validator (below).
|
|
85
|
-
- **What stays the particle's**: the
|
|
85
|
+
- **What stays the particle's**: the mask of the `documentType`, the `documentType` itself, and the `errorMessage` copy.
|
|
86
86
|
- **Single binder, real contract for the read-only parts (RFC:503)**: the composite remains the sole
|
|
87
87
|
binder for its field — `useController` is called once, here. Its default (and a recomposed) anatomy's
|
|
88
88
|
input is `DocumentFieldInput`, which renders the raw Base UI `Field.Control` directly rather than this
|
|
@@ -58,7 +58,7 @@ It renders **both responsive forms at once**, each under its own hook: an accord
|
|
|
58
58
|
| Prop | Type | Required | Notes |
|
|
59
59
|
|-------|------|----------|-------|
|
|
60
60
|
| `heading` | string | no | Authored fallback. Ignored when a CMS entry supplies a heading |
|
|
61
|
-
| `links` | array | no | Authored fallback list of `{ label, href, target? }`. Ignored when a CMS entry supplies `links` |
|
|
61
|
+
| `links` | array | no | Authored fallback list of `{ label, href, target? }`. An item `href` may be a page reference or a logical path. Ignored when a CMS entry supplies `links` |
|
|
62
62
|
|
|
63
63
|
Content model (`footer-link-group`) fields, edited in the CMS:
|
|
64
64
|
|
|
@@ -67,7 +67,7 @@ Content model (`footer-link-group`) fields, edited in the CMS:
|
|
|
67
67
|
| `heading` | string | no | The group heading and the accordion trigger's accessible name. Optional so a links-only entry falls back to the authored heading instead of omitting the group. A group with no heading resolved from either channel renders nothing |
|
|
68
68
|
| `links` | array | no | Ordered links. Reordering here reorders the rendered list with no deployment. Optional so a heading-only entry falls back to the authored list instead of omitting the group |
|
|
69
69
|
| `links[].label` | string | yes | Link text. A blank label drops that link — an anchor with no name is unusable |
|
|
70
|
-
| `links[].href` | string | yes |
|
|
70
|
+
| `links[].href` | string | yes | A `uri-reference` string: `http:`, `https:`, `mailto:`, `tel:`, or a path starting with a single `/`. The binding prefix is applied at render |
|
|
71
71
|
| `links[].target` | `_self` \| `_blank` | no | `_blank` opens a new tab and adds `rel="noopener noreferrer"` automatically |
|
|
72
72
|
|
|
73
73
|
---
|
package/dist/docs/header-root.md
CHANGED
|
@@ -80,7 +80,7 @@ A layout whose root holds a `HeaderRoot` and the page `Slot` beside it, with a l
|
|
|
80
80
|
},
|
|
81
81
|
"header-logo": {
|
|
82
82
|
"type": "Logo",
|
|
83
|
-
"props": { "src": "/logo.svg", "alt": "Loja XYZ", "href": "
|
|
83
|
+
"props": { "src": "/logo.svg", "alt": "Loja XYZ", "href": { "page": "home" } }
|
|
84
84
|
},
|
|
85
85
|
"header-nav": {
|
|
86
86
|
"type": "NavigationMenuRoot",
|
package/dist/docs/incentives.md
CHANGED
|
@@ -64,7 +64,7 @@ FooterRoot
|
|
|
64
64
|
|
|
65
65
|
| Prop | Type | Required | Notes |
|
|
66
66
|
|-------|------|----------|-------|
|
|
67
|
-
| `items` | array | no | Authored fallback list of `{ title, firstLineText?, secondLineText?, href?, icon?, iconUrl?, alt? }`. Ignored when a CMS entry supplies `items` |
|
|
67
|
+
| `items` | array | no | Authored fallback list of `{ title, firstLineText?, secondLineText?, href?, icon?, iconUrl?, alt? }`. An item `href` may be a page reference or a logical path. Ignored when a CMS entry supplies `items` |
|
|
68
68
|
|
|
69
69
|
Content model (`incentives`) fields, edited in the CMS:
|
|
70
70
|
|
|
@@ -74,7 +74,7 @@ Content model (`incentives`) fields, edited in the CMS:
|
|
|
74
74
|
| `items[].title` | string | yes | The benefit's short bold label. The only required field per item; a blank one drops that item |
|
|
75
75
|
| `items[].firstLineText` | string | no | The first line of supporting copy. Optional, so a title-only item is legal; a blank one renders no line |
|
|
76
76
|
| `items[].secondLineText` | string | no | The second line. Absent or blank renders no element, so an item shows zero, one, or two lines |
|
|
77
|
-
| `items[].href` | string | no |
|
|
77
|
+
| `items[].href` | string | no | A `uri-reference` string. Optional, because a benefit strip links nowhere and a shortcut row links everywhere. Wraps the whole block — glyph included — in a same-tab link. Absent or blank renders the item unlinked; a value the render-time allowlist refuses also renders it unlinked, keeping the glyph and copy. A safe string receives the binding prefix at render |
|
|
78
78
|
| `items[].icon` | enum | no | One of `truck`, `calendar`, `gift`, `store`, `shield-check`. Renders the collection glyph, decorative |
|
|
79
79
|
| `items[].iconUrl` | string | no | An uploaded image, for a benefit the predefined set has no glyph for. Wins over `icon` when both are set |
|
|
80
80
|
| `items[].alt` | string | no | Alt text for an uploaded image. Defaults to empty, keeping the image decorative — the visible title beside it is already the item's accessible content, so repeating it would announce the same words twice |
|
package/dist/docs/logo.md
CHANGED
|
@@ -40,7 +40,7 @@ Logo
|
|
|
40
40
|
|------|------|---------|-------|
|
|
41
41
|
| `src` | string | — | Brand logo asset URL. Optional, so an element can be authored from the CMS alone. |
|
|
42
42
|
| `alt` | string | — | Accessible alt text for the logo image. Optional for the same reason. |
|
|
43
|
-
| `href` | string |
|
|
43
|
+
| `href` | page reference or string | `{ "standard": "home" }` | A page reference or a logical path. The default names the home page. A store whose home page declares no `standard` authors `{ "page": "home" }`. |
|
|
44
44
|
| `loading` | `'lazy' \| 'eager'` | `'eager'` | Set `lazy` below the fold; the default suits the header. |
|
|
45
45
|
|
|
46
46
|
Content model (`logo`) fields, edited in the CMS:
|
|
@@ -49,13 +49,13 @@ Content model (`logo`) fields, edited in the CMS:
|
|
|
49
49
|
|-------|------|----------|-------|
|
|
50
50
|
| `src` | string | no | Picked via the media gallery widget. Cleared or absent keeps the authored `src` |
|
|
51
51
|
| `alt` | string | yes | Accessible alt text |
|
|
52
|
-
| `href` | string | no | Cleared or absent keeps the authored `href
|
|
52
|
+
| `href` | string | no | A `uri-reference` string. Cleared or absent keeps the authored `href`. A safe string receives the binding prefix at render |
|
|
53
53
|
|
|
54
54
|
**Props and content both work.** The props stay the authoring surface, and a CMS entry overrides them field by field, so a merchant can swap the brand mark for a campaign without a deploy. A store with no CMS binding receives no `$content` and renders from the props alone. The `logo` model puts no `format` on `src`, because a store's logo is usually a root-relative path served from `public/` (`/logo.svg`), which JSON Schema's `uri` format rejects. `href` carries `uri-reference` and the same destination pattern the link-bearing footer models declare, which admits a root-relative path.
|
|
55
55
|
|
|
56
56
|
**Nothing renders without a resolved `src` and `alt`.** Both props are optional and only `alt` is required in the model, so an element can author nothing and take everything from the CMS. Presence is enforced once, at render, on the resolved values: an unconfigured logo renders no element at all rather than a broken image. An optional field that arrives blank reads as unauthored and falls through to the prop; a blank `alt` renders nothing, since an unnamed link is worse than no link.
|
|
57
57
|
|
|
58
|
-
**A destination that is not a plain web address is dropped.**
|
|
58
|
+
**A string destination that is not a plain web address is dropped.** A CMS `href` is a `uri-reference` string. It is checked at render, and a safe one receives the binding's base path. A page reference, including the default `{ "standard": "home" }`, is not checked as a string. Only `http:`, `https:`, `mailto:`, `tel:`, and single-slash site-relative paths are kept. Anything else — a `javascript:` URL, a protocol-relative `//host`, a scheme-less relative path — renders the image with no link around it and logs the reason, and does not fall back to the prop. No read-time validator enforces a URL pattern, so this is the only gate on a destination the CMS supplied.
|
|
59
59
|
|
|
60
60
|
---
|
|
61
61
|
|
|
@@ -68,7 +68,7 @@ Content model (`logo`) fields, edited in the CMS:
|
|
|
68
68
|
"props": {
|
|
69
69
|
"src": "https://store.example/logo.svg",
|
|
70
70
|
"alt": "Acme Store",
|
|
71
|
-
"href": "
|
|
71
|
+
"href": { "standard": "home" }
|
|
72
72
|
},
|
|
73
73
|
"style": ["$logo"]
|
|
74
74
|
}
|
|
@@ -110,7 +110,7 @@ Bound to a CMS entry, the element authors no content props at all — the entry
|
|
|
110
110
|
{
|
|
111
111
|
"header-logo": {
|
|
112
112
|
"type": "Logo",
|
|
113
|
-
"props": { "src": "https://store.example/logo.svg", "alt": "Acme Store", "href": "
|
|
113
|
+
"props": { "src": "https://store.example/logo.svg", "alt": "Acme Store", "href": { "standard": "home" } },
|
|
114
114
|
"style": ["w-[140px]", "md:w-[220px]"]
|
|
115
115
|
}
|
|
116
116
|
}
|
|
@@ -61,7 +61,7 @@ A field Control is absent from the composition means absent from both states and
|
|
|
61
61
|
- **Save order**: compute dirtiness first → nothing dirty raises the saved toast without dispatching → otherwise validate only the dirty registered fields' current draft values (Decision 9) → any error blocks the dispatch and focuses the first invalid field in rendered DOM order → otherwise normalize dirty values and dispatch one `$actions.identity.customerProfileUpdate` → a `userError` raises an error toast and keeps the edit state with the draft intact → success returns to the view state and raises a success toast (Decision 10). A field the shopper never touched is neither validated nor sent.
|
|
62
62
|
- **Edit always opens from the latest saved values**: pressing Edit re-seeds the draft from `savedValues` before switching modes, so a value the server normalized on a previous save (not this task's concern, but a sibling Control's) is what the shopper sees, not a stale local draft.
|
|
63
63
|
- **Background re-delivery**: when `$data` delivers new values while editing, a field re-seeds only if its draft still equals the previously saved value; a dirty field is never clobbered.
|
|
64
|
-
- **Self-gate**: renders nothing outside `state === 'loggedIn'`, even if the topology's `SessionGuard` is missing. Renders `MyAccountProfileSkeleton` while `$data` is unresolved and the shopper is logged in — never an empty summary.
|
|
64
|
+
- **Self-gate**: renders nothing outside `state === 'loggedIn'`, even if the topology's `SessionGuard` is missing. Renders `MyAccountProfileSkeleton` while `$data` is unresolved and the shopper is logged in — never an empty summary. `customerProfile` is nullable, so `$data` is also `null` for an anonymous session (the self-gate renders nothing) and for a logged-in shopper whose read failed (the skeleton stays).
|
|
65
65
|
- **PII**: no profile value appears in any log line. A write that throws (rather than resolving `userErrors`) logs only the error's name; the message shown to the shopper is the `saveFailedMessage` schema prop.
|
|
66
66
|
|
|
67
67
|
---
|
|
@@ -78,7 +78,7 @@ A field Control is absent from the composition means absent from both states and
|
|
|
78
78
|
|
|
79
79
|
**`.PhoneControl`** — `field` (`'homePhone' | 'mobilePhone'`, default `'mobilePhone'`; compose the Control twice to expose both numbers), `country` (`'US' | 'BR'`, default `'US'`), `label`, `invalidMessage`.
|
|
80
80
|
|
|
81
|
-
**`.TaxIdControl`** — `label` (default `'National tax ID'`), `invalidMessage`, `lockedReason` (the inline copy shown beside the disabled input when a
|
|
81
|
+
**`.TaxIdControl`** — `label` (default `'National tax ID'`), `invalidMessage`, `lockedReason` (the inline copy shown beside the disabled input when a document is already saved). The control masks, validates and normalizes with the active document type: CPF, SSN, SIN or RFC. It sends `document` only (never `documentType`): digits for CPF, SSN and SIN, letters kept for RFC.
|
|
82
82
|
|
|
83
83
|
**`.BirthDateControl`** — `label` (default `'Birth date'`).
|
|
84
84
|
|
|
@@ -93,8 +93,8 @@ Each Control is a thin binding over an existing presentational particle — it a
|
|
|
93
93
|
- **Registration**: in a mount effect, a Control calls `registerField({ key, validate?, normalize? })` and returns the unregister function from the effect. `firstName`/`lastName` register a validator that rejects an empty draft value; every other Control either registers a format-only validator (a present value must be well-formed; empty is always valid) or no validator at all.
|
|
94
94
|
- **Rendering**: `mode === 'view'` renders `savedValues[key]` as plain text (empty, never a placeholder, when the key was never saved); `mode === 'edit'` renders the bound particle over `draft[key]`, writing through `setField(key, value)`.
|
|
95
95
|
- **Normalization**: `PhoneControl` registers `normalize = (v) => v ? toE164(v, country) : v`; `BirthDateControl` registers the native `yyyy-mm-dd` ↔ stored-format identity map. Normalization runs once, on Save, only for a field the shopper actually changed.
|
|
96
|
-
- **The locked tax ID**: when a saved
|
|
97
|
-
- **Self-gate**: `TaxIdControl` renders nothing when the Root's `activeDocumentType` is undefined or unsupported
|
|
96
|
+
- **The locked tax ID**: when a saved document exists, `TaxIdControl`'s edit branch renders a **disabled** input carrying the saved (masked) value, a `data-fs-my-account-profile-tax-id-readonly` hook, and `lockedReason` — never plain text, never omitted. It registers no validator in this branch and is never dirty. With no saved document, it renders an editable, optional `DocumentField` instead.
|
|
97
|
+
- **Self-gate**: `TaxIdControl` renders nothing when the Root's `activeDocumentType` is undefined or unsupported. The supported types are CPF, SSN, SIN and RFC; a saved `documentType` of any of them (any casing) wins over the Root's `documentType` prop.
|
|
98
98
|
- **One phone Control, two bindings**: `PhoneControl`'s `field` prop selects which draft key an instance binds; composing it twice (once per `field` value) exposes both `homePhone` and `mobilePhone` as independent, independently-erasable fields.
|
|
99
99
|
|
|
100
100
|
---
|
|
@@ -172,7 +172,7 @@ Add each field Control id to `profile-root`'s `children` array for the fields th
|
|
|
172
172
|
- **Reading `draft` in the view state, or `savedValues` in the edit state.** Each Control must branch on `mode` itself (Decision 2); the Root does not hide this for you.
|
|
173
173
|
- **Rendering a frame part or field Control outside `MyAccountProfileRoot`.** Every part except `Skeleton` `requiresContext: 'my-account-profile'` and throws otherwise.
|
|
174
174
|
- **Giving a required Control's native input a `required` HTML attribute.** Requiredness is expressed only through the registered `validate` function (Decision 2 of SFS-3288/3289/3290); a native `required` attribute makes the browser block the form's `submit` event before the Root's own validation and focus logic ever runs.
|
|
175
|
-
- **Hiding the `TaxIdControl` in the edit state when a
|
|
175
|
+
- **Hiding the `TaxIdControl` in the edit state when a document is already saved.** It must render a disabled, locked input instead — a field disappearing between view and edit reads as a bug (product-confirmed, 2026-09-03).
|
|
176
176
|
- **Composing only the `mobilePhone` Control on a store whose shoppers check out.** The checkout reads its phone from `homePhone`, and it treats a profile without one as incomplete: a new cart imports only the email and drops the shopper's saved addresses. Compose a `PhoneControl` with `field: "homePhone"` whenever the store sells, alongside the mobile one if the page shows both.
|
|
177
177
|
- **Adding a `showPhone`/`visible` boolean prop to a Control.** Presence is composition; a boolean visibility prop contradicts compose-or-omit and is out of scope for every Control in this group.
|
|
178
178
|
|