@vtex/faststore 0.0.1
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 +18 -0
- package/LICENSE +21 -0
- package/README.md +95 -0
- package/dist/actions.json +334 -0
- package/dist/catalog.json +6615 -0
- package/dist/client.d.ts +17 -0
- package/dist/client.js +8 -0
- package/dist/components.d.ts +87 -0
- package/dist/components.js +87 -0
- package/dist/content-types.json +684 -0
- package/dist/core/dist/actions/mock-action.d.ts +24 -0
- package/dist/core/dist/actions/mock-action.js +28 -0
- package/dist/core/dist/actions/mock-action.js.map +1 -0
- package/dist/core/dist/actions/registry.d.ts +24 -0
- package/dist/core/dist/actions/registry.js +28 -0
- package/dist/core/dist/actions/registry.js.map +1 -0
- package/dist/core/dist/define-component.d.ts +100 -0
- package/dist/core/dist/define-component.js +8 -0
- package/dist/core/dist/define-component.js.map +1 -0
- package/dist/core/dist/define-content-type.d.ts +95 -0
- package/dist/core/dist/define-content-type.js +283 -0
- package/dist/core/dist/define-content-type.js.map +1 -0
- package/dist/core/dist/index.d.ts +7 -0
- package/dist/core/dist/index.js +5 -0
- package/dist/core/dist/schema/generated/schema.d.ts +28 -0
- package/dist/core/dist/types.d.ts +1 -0
- package/dist/docs/access-code-field.md +100 -0
- package/dist/docs/access-code-sign-in.md +174 -0
- package/dist/docs/account-entry-point.md +155 -0
- package/dist/docs/address-summary.md +50 -0
- package/dist/docs/buy-button.md +162 -0
- package/dist/docs/carousel.md +105 -0
- package/dist/docs/cart-item.md +162 -0
- package/dist/docs/cart-totalizer.md +197 -0
- package/dist/docs/cart.md +495 -0
- package/dist/docs/client-preferences.md +184 -0
- package/dist/docs/client-profile-form.md +192 -0
- package/dist/docs/client-profile.md +117 -0
- package/dist/docs/container.md +97 -0
- package/dist/docs/document-field.md +97 -0
- package/dist/docs/email-field.md +93 -0
- package/dist/docs/email-identification.md +102 -0
- package/dist/docs/footer-copyright.md +112 -0
- package/dist/docs/footer-link-group.md +162 -0
- package/dist/docs/footer-root.md +145 -0
- package/dist/docs/footer-social.md +151 -0
- package/dist/docs/free-shipping-progress.md +87 -0
- package/dist/docs/gallery.md +84 -0
- package/dist/docs/header-root.md +150 -0
- package/dist/docs/identity-edit.md +88 -0
- package/dist/docs/identity-summary.md +106 -0
- package/dist/docs/incentives.md +151 -0
- package/dist/docs/logo.md +135 -0
- package/dist/docs/meter.md +67 -0
- package/dist/docs/navigation-link-list.md +171 -0
- package/dist/docs/navigation-link.md +163 -0
- package/dist/docs/navigation-menu.md +264 -0
- package/dist/docs/payment-methods.md +139 -0
- package/dist/docs/phone-field.md +106 -0
- package/dist/docs/postal-code-field.md +126 -0
- package/dist/docs/pricing.md +499 -0
- package/dist/docs/product-gallery.md +409 -0
- package/dist/docs/product-information.md +295 -0
- package/dist/docs/product-list.md +170 -0
- package/dist/docs/product-quantity.md +88 -0
- package/dist/docs/product-shelf.md +141 -0
- package/dist/docs/promotion.md +109 -0
- package/dist/docs/region.md +225 -0
- package/dist/docs/session.md +123 -0
- package/dist/docs/shipping-address.md +390 -0
- package/dist/docs/shipping-simulator.md +147 -0
- package/dist/docs/sign-in-form.md +117 -0
- package/dist/docs/tabs.md +176 -0
- package/dist/docs/toast.md +124 -0
- package/dist/docs/variant-selector.md +450 -0
- package/dist/graphql/define-subgraph.d.ts +12 -0
- package/dist/graphql/define-subgraph.js +15 -0
- package/dist/graphql/define-subgraph.js.map +1 -0
- package/dist/graphql/gql.d.ts +10 -0
- package/dist/graphql/gql.js +16 -0
- package/dist/graphql/gql.js.map +1 -0
- package/dist/graphql/types.d.ts +88 -0
- package/dist/graphql.d.ts +4 -0
- package/dist/graphql.js +3 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +5 -0
- package/dist/internal/client.d.ts +24 -0
- package/dist/internal/client.js +23 -0
- package/dist/internal/content.d.ts +2 -0
- package/dist/internal/content.js +2 -0
- package/dist/internal/server.d.ts +7 -0
- package/dist/internal/server.js +6 -0
- package/dist/matter/access-code-sign-in/access-code-sign-in.d.ts +111 -0
- package/dist/matter/access-code-sign-in/access-code-sign-in.js +387 -0
- package/dist/matter/access-code-sign-in/access-code-sign-in.js.map +1 -0
- package/dist/matter/account-entry-point/account-entry-point.d.ts +64 -0
- package/dist/matter/account-entry-point/account-entry-point.js +151 -0
- package/dist/matter/account-entry-point/account-entry-point.js.map +1 -0
- package/dist/matter/breadcrumb/breadcrumb.d.ts +40 -0
- package/dist/matter/breadcrumb/breadcrumb.js +155 -0
- package/dist/matter/breadcrumb/breadcrumb.js.map +1 -0
- package/dist/matter/buy-button/buy-button.d.ts +95 -0
- package/dist/matter/buy-button/buy-button.js +259 -0
- package/dist/matter/buy-button/buy-button.js.map +1 -0
- package/dist/matter/cart/cart-namespace.d.ts +48 -0
- package/dist/matter/cart/cart-namespace.js +50 -0
- package/dist/matter/cart/cart-namespace.js.map +1 -0
- package/dist/matter/cart/cart.d.ts +312 -0
- package/dist/matter/cart/cart.js +1034 -0
- package/dist/matter/cart/cart.js.map +1 -0
- package/dist/matter/cart-item/cart-item.d.ts +103 -0
- package/dist/matter/cart-item/cart-item.js +672 -0
- package/dist/matter/cart-item/cart-item.js.map +1 -0
- package/dist/matter/cart-item-compositions/cart-item-compositions.d.ts +49 -0
- package/dist/matter/cart-item-compositions/cart-item-compositions.js +165 -0
- package/dist/matter/cart-item-compositions/cart-item-compositions.js.map +1 -0
- package/dist/matter/cart-item-customizations/cart-item-customizations.d.ts +28 -0
- package/dist/matter/cart-item-customizations/cart-item-customizations.js +73 -0
- package/dist/matter/cart-item-customizations/cart-item-customizations.js.map +1 -0
- package/dist/matter/cart-item-discounts/cart-item-discounts.d.ts +33 -0
- package/dist/matter/cart-item-discounts/cart-item-discounts.js +70 -0
- package/dist/matter/cart-item-discounts/cart-item-discounts.js.map +1 -0
- package/dist/matter/cart-item-seller-info/cart-item-seller-info.d.ts +24 -0
- package/dist/matter/cart-item-seller-info/cart-item-seller-info.js +54 -0
- package/dist/matter/cart-item-seller-info/cart-item-seller-info.js.map +1 -0
- package/dist/matter/cart-item-variations/cart-item-variations.d.ts +27 -0
- package/dist/matter/cart-item-variations/cart-item-variations.js +69 -0
- package/dist/matter/cart-item-variations/cart-item-variations.js.map +1 -0
- package/dist/matter/cart-totalizer/cart-totalizer.d.ts +78 -0
- package/dist/matter/cart-totalizer/cart-totalizer.js +220 -0
- package/dist/matter/cart-totalizer/cart-totalizer.js.map +1 -0
- package/dist/matter/client-preferences/client-preferences.d.ts +50 -0
- package/dist/matter/client-preferences/client-preferences.js +206 -0
- package/dist/matter/client-preferences/client-preferences.js.map +1 -0
- package/dist/matter/client-profile/client-profile.d.ts +59 -0
- package/dist/matter/client-profile/client-profile.js +185 -0
- package/dist/matter/client-profile/client-profile.js.map +1 -0
- package/dist/matter/client-profile-form/client-profile-form.d.ts +126 -0
- package/dist/matter/client-profile-form/client-profile-form.js +660 -0
- package/dist/matter/client-profile-form/client-profile-form.js.map +1 -0
- package/dist/matter/delivery-options/delivery-options-accordion.d.ts +30 -0
- package/dist/matter/delivery-options/delivery-options-accordion.js +189 -0
- package/dist/matter/delivery-options/delivery-options-accordion.js.map +1 -0
- package/dist/matter/delivery-options/delivery-options-controller.d.ts +49 -0
- package/dist/matter/delivery-options/delivery-options-controller.js +203 -0
- package/dist/matter/delivery-options/delivery-options-controller.js.map +1 -0
- package/dist/matter/delivery-options/delivery-options.d.ts +31 -0
- package/dist/matter/delivery-options/delivery-options.js +103 -0
- package/dist/matter/delivery-options/delivery-options.js.map +1 -0
- package/dist/matter/delivery-options/use-delivery-option-selection.d.ts +9 -0
- package/dist/matter/delivery-options/use-delivery-option-selection.js +76 -0
- package/dist/matter/delivery-options/use-delivery-option-selection.js.map +1 -0
- package/dist/matter/email-identification/email-identification.d.ts +37 -0
- package/dist/matter/email-identification/email-identification.js +111 -0
- package/dist/matter/email-identification/email-identification.js.map +1 -0
- package/dist/matter/free-shipping-progress/free-shipping-progress.d.ts +44 -0
- package/dist/matter/free-shipping-progress/free-shipping-progress.js +170 -0
- package/dist/matter/free-shipping-progress/free-shipping-progress.js.map +1 -0
- package/dist/matter/identity-edit/identity-edit.d.ts +52 -0
- package/dist/matter/identity-edit/identity-edit.js +148 -0
- package/dist/matter/identity-edit/identity-edit.js.map +1 -0
- package/dist/matter/identity-summary/identity-summary.d.ts +128 -0
- package/dist/matter/identity-summary/identity-summary.js +344 -0
- package/dist/matter/identity-summary/identity-summary.js.map +1 -0
- package/dist/matter/pricing/pricing.d.ts +162 -0
- package/dist/matter/pricing/pricing.js +793 -0
- package/dist/matter/pricing/pricing.js.map +1 -0
- package/dist/matter/product-gallery/product-gallery.d.ts +23 -0
- package/dist/matter/product-gallery/product-gallery.js +188 -0
- package/dist/matter/product-gallery/product-gallery.js.map +1 -0
- package/dist/matter/product-information/product-information.d.ts +61 -0
- package/dist/matter/product-information/product-information.js +355 -0
- package/dist/matter/product-information/product-information.js.map +1 -0
- package/dist/matter/product-list/product-list.d.ts +86 -0
- package/dist/matter/product-list/product-list.js +342 -0
- package/dist/matter/product-list/product-list.js.map +1 -0
- package/dist/matter/product-quantity/product-quantity.d.ts +50 -0
- package/dist/matter/product-quantity/product-quantity.js +111 -0
- package/dist/matter/product-quantity/product-quantity.js.map +1 -0
- package/dist/matter/product-shelf/product-shelf.d.ts +125 -0
- package/dist/matter/product-shelf/product-shelf.js +376 -0
- package/dist/matter/product-shelf/product-shelf.js.map +1 -0
- package/dist/matter/region/region.d.ts +211 -0
- package/dist/matter/region/region.js +579 -0
- package/dist/matter/region/region.js.map +1 -0
- package/dist/matter/session/session.d.ts +58 -0
- package/dist/matter/session/session.js +112 -0
- package/dist/matter/session/session.js.map +1 -0
- package/dist/matter/shipping-address/country-descriptors.js +101 -0
- package/dist/matter/shipping-address/country-descriptors.js.map +1 -0
- package/dist/matter/shipping-address/shipping-address.d.ts +284 -0
- package/dist/matter/shipping-address/shipping-address.js +1036 -0
- package/dist/matter/shipping-address/shipping-address.js.map +1 -0
- package/dist/matter/shipping-simulator/shipping-simulator.d.ts +143 -0
- package/dist/matter/shipping-simulator/shipping-simulator.js +644 -0
- package/dist/matter/shipping-simulator/shipping-simulator.js.map +1 -0
- package/dist/matter/sign-in-form/sign-in-form.d.ts +79 -0
- package/dist/matter/sign-in-form/sign-in-form.js +226 -0
- package/dist/matter/sign-in-form/sign-in-form.js.map +1 -0
- package/dist/matter/variant-selector/variant-selector.d.ts +183 -0
- package/dist/matter/variant-selector/variant-selector.js +840 -0
- package/dist/matter/variant-selector/variant-selector.js.map +1 -0
- package/dist/message-locales.json +7 -0
- package/dist/particles/access-code-field/access-code-field.d.ts +33 -0
- package/dist/particles/access-code-field/access-code-field.js +95 -0
- package/dist/particles/access-code-field/access-code-field.js.map +1 -0
- package/dist/particles/accordion/accordion.d.ts +45 -0
- package/dist/particles/accordion/accordion.js +156 -0
- package/dist/particles/accordion/accordion.js.map +1 -0
- package/dist/particles/address-summary/address-summary.d.ts +50 -0
- package/dist/particles/address-summary/address-summary.js +129 -0
- package/dist/particles/address-summary/address-summary.js.map +1 -0
- package/dist/particles/badge/badge.d.ts +10 -0
- package/dist/particles/badge/badge.js +27 -0
- package/dist/particles/badge/badge.js.map +1 -0
- package/dist/particles/button/button.d.ts +18 -0
- package/dist/particles/button/button.js +37 -0
- package/dist/particles/button/button.js.map +1 -0
- package/dist/particles/carousel/carousel.d.ts +60 -0
- package/dist/particles/carousel/carousel.js +335 -0
- package/dist/particles/carousel/carousel.js.map +1 -0
- package/dist/particles/checkbox/checkbox.d.ts +40 -0
- package/dist/particles/checkbox/checkbox.js +82 -0
- package/dist/particles/checkbox/checkbox.js.map +1 -0
- package/dist/particles/container/container.d.ts +20 -0
- package/dist/particles/container/container.js +36 -0
- package/dist/particles/container/container.js.map +1 -0
- package/dist/particles/dialog/dialog.d.ts +54 -0
- package/dist/particles/dialog/dialog.js +192 -0
- package/dist/particles/dialog/dialog.js.map +1 -0
- package/dist/particles/document-field/document-field.d.ts +61 -0
- package/dist/particles/document-field/document-field.js +146 -0
- package/dist/particles/document-field/document-field.js.map +1 -0
- package/dist/particles/drawer/drawer.d.ts +52 -0
- package/dist/particles/drawer/drawer.js +183 -0
- package/dist/particles/drawer/drawer.js.map +1 -0
- package/dist/particles/email-field/email-field.d.ts +37 -0
- package/dist/particles/email-field/email-field.js +106 -0
- package/dist/particles/email-field/email-field.js.map +1 -0
- package/dist/particles/field/field.d.ts +50 -0
- package/dist/particles/field/field.js +133 -0
- package/dist/particles/field/field.js.map +1 -0
- package/dist/particles/fieldset/fieldset.d.ts +16 -0
- package/dist/particles/fieldset/fieldset.js +52 -0
- package/dist/particles/fieldset/fieldset.js.map +1 -0
- package/dist/particles/footer-copyright/footer-copyright.d.ts +32 -0
- package/dist/particles/footer-copyright/footer-copyright.js +50 -0
- package/dist/particles/footer-copyright/footer-copyright.js.map +1 -0
- package/dist/particles/footer-link-group/footer-link-group.d.ts +66 -0
- package/dist/particles/footer-link-group/footer-link-group.js +154 -0
- package/dist/particles/footer-link-group/footer-link-group.js.map +1 -0
- package/dist/particles/footer-root/footer-root.d.ts +21 -0
- package/dist/particles/footer-root/footer-root.js +38 -0
- package/dist/particles/footer-root/footer-root.js.map +1 -0
- package/dist/particles/footer-social/footer-social.d.ts +79 -0
- package/dist/particles/footer-social/footer-social.js +176 -0
- package/dist/particles/footer-social/footer-social.js.map +1 -0
- package/dist/particles/gallery/gallery.d.ts +181 -0
- package/dist/particles/gallery/gallery.js +920 -0
- package/dist/particles/gallery/gallery.js.map +1 -0
- package/dist/particles/header-root/header-root.d.ts +21 -0
- package/dist/particles/header-root/header-root.js +38 -0
- package/dist/particles/header-root/header-root.js.map +1 -0
- package/dist/particles/icon/icon.d.ts +22 -0
- package/dist/particles/icon/icon.js +48 -0
- package/dist/particles/icon/icon.js.map +1 -0
- package/dist/particles/image/image.d.ts +13 -0
- package/dist/particles/image/image.js +59 -0
- package/dist/particles/image/image.js.map +1 -0
- package/dist/particles/incentives/incentives.d.ts +85 -0
- package/dist/particles/incentives/incentives.js +200 -0
- package/dist/particles/incentives/incentives.js.map +1 -0
- package/dist/particles/input/input.d.ts +9 -0
- package/dist/particles/input/input.js +28 -0
- package/dist/particles/input/input.js.map +1 -0
- package/dist/particles/logo/logo.d.ts +55 -0
- package/dist/particles/logo/logo.js +96 -0
- package/dist/particles/logo/logo.js.map +1 -0
- package/dist/particles/menu/menu.d.ts +103 -0
- package/dist/particles/menu/menu.js +409 -0
- package/dist/particles/menu/menu.js.map +1 -0
- package/dist/particles/menubar/menubar.d.ts +18 -0
- package/dist/particles/menubar/menubar.js +42 -0
- package/dist/particles/menubar/menubar.js.map +1 -0
- package/dist/particles/meter/meter.d.ts +36 -0
- package/dist/particles/meter/meter.js +132 -0
- package/dist/particles/meter/meter.js.map +1 -0
- package/dist/particles/navigation-link/navigation-link.d.ts +43 -0
- package/dist/particles/navigation-link/navigation-link.js +82 -0
- package/dist/particles/navigation-link/navigation-link.js.map +1 -0
- package/dist/particles/navigation-link-list/navigation-link-list.d.ts +59 -0
- package/dist/particles/navigation-link-list/navigation-link-list.js +103 -0
- package/dist/particles/navigation-link-list/navigation-link-list.js.map +1 -0
- package/dist/particles/navigation-menu/navigation-menu.d.ts +78 -0
- package/dist/particles/navigation-menu/navigation-menu.js +295 -0
- package/dist/particles/navigation-menu/navigation-menu.js.map +1 -0
- package/dist/particles/number-field/number-field.d.ts +46 -0
- package/dist/particles/number-field/number-field.js +169 -0
- package/dist/particles/number-field/number-field.js.map +1 -0
- package/dist/particles/password-field/password-field.d.ts +31 -0
- package/dist/particles/password-field/password-field.js +109 -0
- package/dist/particles/password-field/password-field.js.map +1 -0
- package/dist/particles/payment-methods/payment-methods.d.ts +72 -0
- package/dist/particles/payment-methods/payment-methods.js +151 -0
- package/dist/particles/payment-methods/payment-methods.js.map +1 -0
- package/dist/particles/phone-field/phone-field.d.ts +67 -0
- package/dist/particles/phone-field/phone-field.js +250 -0
- package/dist/particles/phone-field/phone-field.js.map +1 -0
- package/dist/particles/popover/popover.d.ts +68 -0
- package/dist/particles/popover/popover.js +284 -0
- package/dist/particles/popover/popover.js.map +1 -0
- package/dist/particles/postal-code-field/postal-code-field.d.ts +75 -0
- package/dist/particles/postal-code-field/postal-code-field.js +169 -0
- package/dist/particles/postal-code-field/postal-code-field.js.map +1 -0
- package/dist/particles/promotion/promotion.d.ts +46 -0
- package/dist/particles/promotion/promotion.js +78 -0
- package/dist/particles/promotion/promotion.js.map +1 -0
- package/dist/particles/quantity-selector/quantity-selector.d.ts +30 -0
- package/dist/particles/quantity-selector/quantity-selector.js +116 -0
- package/dist/particles/quantity-selector/quantity-selector.js.map +1 -0
- package/dist/particles/radio/radio.d.ts +36 -0
- package/dist/particles/radio/radio.js +76 -0
- package/dist/particles/radio/radio.js.map +1 -0
- package/dist/particles/scroll-area/scroll-area.d.ts +36 -0
- package/dist/particles/scroll-area/scroll-area.js +145 -0
- package/dist/particles/scroll-area/scroll-area.js.map +1 -0
- package/dist/particles/select/select.d.ts +125 -0
- package/dist/particles/select/select.js +478 -0
- package/dist/particles/select/select.js.map +1 -0
- package/dist/particles/separator/separator.d.ts +12 -0
- package/dist/particles/separator/separator.js +33 -0
- package/dist/particles/separator/separator.js.map +1 -0
- package/dist/particles/shared/input-mask.d.ts +5 -0
- package/dist/particles/shared/input-mask.js +58 -0
- package/dist/particles/shared/input-mask.js.map +1 -0
- package/dist/particles/spinner/spinner.d.ts +13 -0
- package/dist/particles/spinner/spinner.js +31 -0
- package/dist/particles/spinner/spinner.js.map +1 -0
- package/dist/particles/switch/switch.d.ts +27 -0
- package/dist/particles/switch/switch.js +59 -0
- package/dist/particles/switch/switch.js.map +1 -0
- package/dist/particles/tabs/tabs.d.ts +45 -0
- package/dist/particles/tabs/tabs.js +164 -0
- package/dist/particles/tabs/tabs.js.map +1 -0
- package/dist/particles/text/text.d.ts +24 -0
- package/dist/particles/text/text.js +40 -0
- package/dist/particles/text/text.js.map +1 -0
- package/dist/particles/toast/toast.d.ts +83 -0
- package/dist/particles/toast/toast.js +194 -0
- package/dist/particles/toast/toast.js.map +1 -0
- package/dist/particles/toggle/toggle.d.ts +26 -0
- package/dist/particles/toggle/toggle.js +61 -0
- package/dist/particles/toggle/toggle.js.map +1 -0
- package/dist/particles/tooltip/tooltip.d.ts +61 -0
- package/dist/particles/tooltip/tooltip.js +240 -0
- package/dist/particles/tooltip/tooltip.js.map +1 -0
- package/dist/schema.graphql +2953 -0
- package/dist/sdk/actions/cart-action-provider.d.ts +19 -0
- package/dist/sdk/actions/cart-action-provider.js +23 -0
- package/dist/sdk/actions/cart-action-provider.js.map +1 -0
- package/dist/sdk/actions/identity-action-provider.d.ts +15 -0
- package/dist/sdk/actions/identity-action-provider.js +19 -0
- package/dist/sdk/actions/identity-action-provider.js.map +1 -0
- package/dist/sdk/actions/index.d.ts +7 -0
- package/dist/sdk/actions/index.js +6 -0
- package/dist/sdk/actions/inject-actions.d.ts +14 -0
- package/dist/sdk/actions/inject-actions.js +36 -0
- package/dist/sdk/actions/inject-actions.js.map +1 -0
- package/dist/sdk/actions/region-action-provider.d.ts +15 -0
- package/dist/sdk/actions/region-action-provider.js +19 -0
- package/dist/sdk/actions/region-action-provider.js.map +1 -0
- package/dist/sdk/actions/session-action-provider.d.ts +15 -0
- package/dist/sdk/actions/session-action-provider.js +19 -0
- package/dist/sdk/actions/session-action-provider.js.map +1 -0
- package/dist/sdk/actions/shipping-action-provider.d.ts +15 -0
- package/dist/sdk/actions/shipping-action-provider.js +19 -0
- package/dist/sdk/actions/shipping-action-provider.js.map +1 -0
- package/dist/sdk/actions/types.d.ts +21 -0
- package/dist/sdk/cache/storefront-cache.js +35 -0
- package/dist/sdk/cache/storefront-cache.js.map +1 -0
- package/dist/sdk/cart/operations.d.ts +31 -0
- package/dist/sdk/cart/operations.js +215 -0
- package/dist/sdk/cart/operations.js.map +1 -0
- package/dist/sdk/cart/optimistic.d.ts +24 -0
- package/dist/sdk/cart/optimistic.js +164 -0
- package/dist/sdk/cart/optimistic.js.map +1 -0
- package/dist/sdk/cart/use-cart-actions.d.ts +56 -0
- package/dist/sdk/cart/use-cart-actions.js +348 -0
- package/dist/sdk/cart/use-cart-actions.js.map +1 -0
- package/dist/sdk/cart/use-cart-validate-on-open.js +50 -0
- package/dist/sdk/cart/use-cart-validate-on-open.js.map +1 -0
- package/dist/sdk/cart/write-gate.js +54 -0
- package/dist/sdk/cart/write-gate.js.map +1 -0
- package/dist/sdk/client/assert-api-url.js +20 -0
- package/dist/sdk/client/assert-api-url.js.map +1 -0
- package/dist/sdk/client/create-client.d.ts +23 -0
- package/dist/sdk/client/create-client.js +46 -0
- package/dist/sdk/client/create-client.js.map +1 -0
- package/dist/sdk/client/fetch-page-data.d.ts +39 -0
- package/dist/sdk/client/fetch-page-data.js +33 -0
- package/dist/sdk/client/fetch-page-data.js.map +1 -0
- package/dist/sdk/client/register-preload-query.d.ts +24 -0
- package/dist/sdk/client/register-preload-query.js +33 -0
- package/dist/sdk/client/register-preload-query.js.map +1 -0
- package/dist/sdk/content/create-content-runtime.d.ts +68 -0
- package/dist/sdk/content/create-content-runtime.js +503 -0
- package/dist/sdk/content/create-content-runtime.js.map +1 -0
- package/dist/sdk/context/headers.d.ts +15 -0
- package/dist/sdk/context/headers.js +21 -0
- package/dist/sdk/context/headers.js.map +1 -0
- package/dist/sdk/context/storefront-context.d.ts +11 -0
- package/dist/sdk/context/storefront-context.js +29 -0
- package/dist/sdk/context/storefront-context.js.map +1 -0
- package/dist/sdk/data/data-override-context.d.ts +12 -0
- package/dist/sdk/data/data-override-context.js +19 -0
- package/dist/sdk/data/data-override-context.js.map +1 -0
- package/dist/sdk/data/entity-subscriber.js +28 -0
- package/dist/sdk/data/entity-subscriber.js.map +1 -0
- package/dist/sdk/data/hot-data-provider.d.ts +19 -0
- package/dist/sdk/data/hot-data-provider.js +33 -0
- package/dist/sdk/data/hot-data-provider.js.map +1 -0
- package/dist/sdk/data/index.d.ts +8 -0
- package/dist/sdk/data/index.js +8 -0
- package/dist/sdk/data/list-item-ref-context.d.ts +20 -0
- package/dist/sdk/data/list-item-ref-context.js +11 -0
- package/dist/sdk/data/list-item-ref-context.js.map +1 -0
- package/dist/sdk/data/multiple-reactive-data-provider.d.ts +32 -0
- package/dist/sdk/data/multiple-reactive-data-provider.js +20 -0
- package/dist/sdk/data/multiple-reactive-data-provider.js.map +1 -0
- package/dist/sdk/data/page-reactive-data-root.d.ts +53 -0
- package/dist/sdk/data/page-reactive-data-root.js +153 -0
- package/dist/sdk/data/page-reactive-data-root.js.map +1 -0
- package/dist/sdk/data/reactive-data-provider.d.ts +25 -0
- package/dist/sdk/data/reactive-data-provider.js +24 -0
- package/dist/sdk/data/reactive-data-provider.js.map +1 -0
- package/dist/sdk/data/reactive-list-item-data-provider.d.ts +26 -0
- package/dist/sdk/data/reactive-list-item-data-provider.js +42 -0
- package/dist/sdk/data/reactive-list-item-data-provider.js.map +1 -0
- package/dist/sdk/data/use-reactive-entity.js +40 -0
- package/dist/sdk/data/use-reactive-entity.js.map +1 -0
- package/dist/sdk/format/client.d.ts +12 -0
- package/dist/sdk/format/client.js +20 -0
- package/dist/sdk/format/client.js.map +1 -0
- package/dist/sdk/format/formatters.d.ts +32 -0
- package/dist/sdk/format/formatters.js +45 -0
- package/dist/sdk/format/formatters.js.map +1 -0
- package/dist/sdk/generated/fragment-types.js +23 -0
- package/dist/sdk/generated/fragment-types.js.map +1 -0
- package/dist/sdk/generated/gql.js +51 -0
- package/dist/sdk/generated/gql.js.map +1 -0
- package/dist/sdk/generated/graphql.d.ts +622 -0
- package/dist/sdk/generated/graphql.js +11917 -0
- package/dist/sdk/generated/graphql.js.map +1 -0
- package/dist/sdk/graphql-tag.d.ts +10 -0
- package/dist/sdk/graphql-tag.js +21 -0
- package/dist/sdk/graphql-tag.js.map +1 -0
- package/dist/sdk/i18n/client.d.ts +4 -0
- package/dist/sdk/i18n/client.js +4 -0
- package/dist/sdk/i18n/locales.d.ts +8 -0
- package/dist/sdk/i18n/locales.js +57 -0
- package/dist/sdk/i18n/locales.js.map +1 -0
- package/dist/sdk/i18n/messages/en-US.js +24 -0
- package/dist/sdk/i18n/messages/en-US.js.map +1 -0
- package/dist/sdk/i18n/messages/en-US.json +19 -0
- package/dist/sdk/i18n/messages/en-US.json.d.ts +23 -0
- package/dist/sdk/i18n/messages/es-ES.js +24 -0
- package/dist/sdk/i18n/messages/es-ES.js.map +1 -0
- package/dist/sdk/i18n/messages/es-ES.json +19 -0
- package/dist/sdk/i18n/messages/pt-BR.js +24 -0
- package/dist/sdk/i18n/messages/pt-BR.js.map +1 -0
- package/dist/sdk/i18n/messages/pt-BR.json +19 -0
- package/dist/sdk/i18n/provider.d.ts +1 -0
- package/dist/sdk/i18n/provider.js +30 -0
- package/dist/sdk/i18n/provider.js.map +1 -0
- package/dist/sdk/i18n/server.d.ts +28 -0
- package/dist/sdk/i18n/server.js +59 -0
- package/dist/sdk/i18n/server.js.map +1 -0
- package/dist/sdk/identity/operations.d.ts +34 -0
- package/dist/sdk/identity/operations.js +78 -0
- package/dist/sdk/identity/operations.js.map +1 -0
- package/dist/sdk/identity/use-identity-actions.d.ts +62 -0
- package/dist/sdk/identity/use-identity-actions.js +180 -0
- package/dist/sdk/identity/use-identity-actions.js.map +1 -0
- package/dist/sdk/provider/index.d.ts +2 -0
- package/dist/sdk/provider/index.js +2 -0
- package/dist/sdk/provider/storefront-provider.d.ts +32 -0
- package/dist/sdk/provider/storefront-provider.js +111 -0
- package/dist/sdk/provider/storefront-provider.js.map +1 -0
- package/dist/sdk/region/operations.d.ts +6 -0
- package/dist/sdk/region/region-operations.d.ts +30 -0
- package/dist/sdk/region/region-operations.js +23 -0
- package/dist/sdk/region/region-operations.js.map +1 -0
- package/dist/sdk/region/use-region-actions.d.ts +23 -0
- package/dist/sdk/region/use-region-actions.js +66 -0
- package/dist/sdk/region/use-region-actions.js.map +1 -0
- package/dist/sdk/seller.js +11 -0
- package/dist/sdk/seller.js.map +1 -0
- package/dist/sdk/session/auth-operations.d.ts +47 -0
- package/dist/sdk/session/auth-operations.js +79 -0
- package/dist/sdk/session/auth-operations.js.map +1 -0
- package/dist/sdk/session/operations.d.ts +6 -0
- package/dist/sdk/session/use-session-actions.d.ts +27 -0
- package/dist/sdk/session/use-session-actions.js +126 -0
- package/dist/sdk/session/use-session-actions.js.map +1 -0
- package/dist/sdk/shipping/cart-operations.d.ts +3 -0
- package/dist/sdk/shipping/cart-operations.js +33 -0
- package/dist/sdk/shipping/cart-operations.js.map +1 -0
- package/dist/sdk/shipping/operations.d.ts +3 -0
- package/dist/sdk/shipping/operations.js +33 -0
- package/dist/sdk/shipping/operations.js.map +1 -0
- package/dist/sdk/shipping/option-select-operations.d.ts +24 -0
- package/dist/sdk/shipping/option-select-operations.js +45 -0
- package/dist/sdk/shipping/option-select-operations.js.map +1 -0
- package/dist/sdk/shipping/request-timeout.js +41 -0
- package/dist/sdk/shipping/request-timeout.js.map +1 -0
- package/dist/sdk/shipping/shipping-operations.d.ts +38 -0
- package/dist/sdk/shipping/shipping-operations.js +77 -0
- package/dist/sdk/shipping/shipping-operations.js.map +1 -0
- package/dist/sdk/shipping/use-cart-shipping-simulation.d.ts +7 -0
- package/dist/sdk/shipping/use-cart-shipping-simulation.js +72 -0
- package/dist/sdk/shipping/use-cart-shipping-simulation.js.map +1 -0
- package/dist/sdk/shipping/use-shipping-actions.d.ts +27 -0
- package/dist/sdk/shipping/use-shipping-actions.js +113 -0
- package/dist/sdk/shipping/use-shipping-actions.js.map +1 -0
- package/dist/sdk/shipping/use-shipping-simulation.d.ts +7 -0
- package/dist/sdk/shipping/use-shipping-simulation.js +72 -0
- package/dist/sdk/shipping/use-shipping-simulation.js.map +1 -0
- package/dist/sdk/state/cart.d.ts +42 -0
- package/dist/sdk/state/cart.js +64 -0
- package/dist/sdk/state/cart.js.map +1 -0
- package/dist/sdk/state/index.js +3 -0
- package/dist/sdk/state/variant-selector.d.ts +17 -0
- package/dist/sdk/state/variant-selector.js +14 -0
- package/dist/sdk/state/variant-selector.js.map +1 -0
- package/dist/utils/safe-href.js +63 -0
- package/dist/utils/safe-href.js.map +1 -0
- package/package.json +84 -0
- package/src/styles/tailwind.css +32 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { defineComponent } from "../../core/dist/define-component.js";
|
|
3
|
+
import "../../core/dist/index.js";
|
|
4
|
+
import { Field } from "../../particles/field/field.js";
|
|
5
|
+
import { useDataOverride } from "../../sdk/data/data-override-context.js";
|
|
6
|
+
import { useSession } from "../session/session.js";
|
|
7
|
+
import { Icon } from "../../particles/icon/icon.js";
|
|
8
|
+
import { Checkbox } from "../../particles/checkbox/checkbox.js";
|
|
9
|
+
import { createContext, useCallback, useContext, useMemo, useState } from "react";
|
|
10
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
const ClientPreferencesRootDefinition = defineComponent({
|
|
12
|
+
name: "ClientPreferencesRoot",
|
|
13
|
+
importPath: "@vtex/faststore/components",
|
|
14
|
+
component: ClientPreferencesRoot,
|
|
15
|
+
fragment: `
|
|
16
|
+
fragment ClientPreferencesData on Query {
|
|
17
|
+
clientPreferences {
|
|
18
|
+
__typename
|
|
19
|
+
id
|
|
20
|
+
optinNewsLetter
|
|
21
|
+
savePersonalData
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
`,
|
|
25
|
+
fetchStrategy: "reactive",
|
|
26
|
+
providesContext: "client-preferences",
|
|
27
|
+
requiresContext: "session",
|
|
28
|
+
editor: {
|
|
29
|
+
label: "Client Preferences Root",
|
|
30
|
+
category: "identity"
|
|
31
|
+
},
|
|
32
|
+
schema: {},
|
|
33
|
+
guideline: "Binding provider for the consent opt-in section; reads both opt-in values (optinNewsLetter, savePersonalData) from the ClientPreferences identity entity (a sibling of Cart, via Query.clientPreferences) and exposes them to its Controls. Reads session state from useSession(); must be inside SessionRoot. Writes flow through $actions.identity.clientPreferencesUpdate. Wrap a NewsletterOptInControl and/or a SavePersonalDataOptInControl."
|
|
34
|
+
});
|
|
35
|
+
const NewsletterOptInControlDefinition = defineComponent({
|
|
36
|
+
name: "NewsletterOptInControl",
|
|
37
|
+
importPath: "@vtex/faststore/components",
|
|
38
|
+
component: NewsletterOptInControl,
|
|
39
|
+
requiresContext: "client-preferences",
|
|
40
|
+
actions: { identity: ["clientPreferencesUpdate"] },
|
|
41
|
+
editor: {
|
|
42
|
+
label: "Newsletter Opt-In Control",
|
|
43
|
+
category: "identity"
|
|
44
|
+
},
|
|
45
|
+
schema: { label: {
|
|
46
|
+
type: "string",
|
|
47
|
+
label: "Label"
|
|
48
|
+
} },
|
|
49
|
+
guideline: "The bound newsletter opt-in checkbox; must be a descendant of ClientPreferencesRoot. Toggling writes the optinNewsLetter preference via $actions.identity.clientPreferencesUpdate. Defaults to unchecked."
|
|
50
|
+
});
|
|
51
|
+
const SavePersonalDataOptInControlDefinition = defineComponent({
|
|
52
|
+
name: "SavePersonalDataOptInControl",
|
|
53
|
+
importPath: "@vtex/faststore/components",
|
|
54
|
+
component: SavePersonalDataOptInControl,
|
|
55
|
+
requiresContext: "client-preferences",
|
|
56
|
+
actions: { identity: ["clientPreferencesUpdate"] },
|
|
57
|
+
editor: {
|
|
58
|
+
label: "Save Personal Data Opt-In Control",
|
|
59
|
+
category: "identity"
|
|
60
|
+
},
|
|
61
|
+
schema: { label: {
|
|
62
|
+
type: "string",
|
|
63
|
+
label: "Label"
|
|
64
|
+
} },
|
|
65
|
+
guideline: "The bound save-personal-data opt-in checkbox; must be a descendant of ClientPreferencesRoot. Toggling writes the savePersonalData preference via $actions.identity.clientPreferencesUpdate. Defaults to unchecked."
|
|
66
|
+
});
|
|
67
|
+
const CLIENT_PREFERENCES_UNSET = Symbol("ClientPreferencesContextUnset");
|
|
68
|
+
const ClientPreferencesContext = createContext(CLIENT_PREFERENCES_UNSET);
|
|
69
|
+
function useClientPreferencesContext() {
|
|
70
|
+
const ctx = useContext(ClientPreferencesContext);
|
|
71
|
+
if (ctx === CLIENT_PREFERENCES_UNSET) throw new Error("A client-preferences Control must be used inside a ClientPreferencesRoot.");
|
|
72
|
+
return ctx;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Renders the client-preferences section Root: reads `$data` (the `ClientPreferences` sibling entity),
|
|
76
|
+
* reads `useSession()` (which also enforces the `SessionRoot` ancestor, mirroring
|
|
77
|
+
* `EmailIdentificationControl`), seeds both opt-in values from the section fragment, and publishes a
|
|
78
|
+
* section context exposing both values plus per-field pending/error tracking. The write itself flows
|
|
79
|
+
* through the Control's `$actions.identity.clientPreferencesUpdate` (ADR-0010); this Root tracks which
|
|
80
|
+
* keys are in flight and stores the returned userErrors under each key so each Control surfaces ITS OWN
|
|
81
|
+
* pending/error. When the session reports `canEditData: false` (identified but unauthenticated claimed
|
|
82
|
+
* profile — VTEX refuses the write server-side) every Control renders disabled with its readonly
|
|
83
|
+
* `data-fs-*` attribute, mirroring `EmailIdentificationControl`.
|
|
84
|
+
*/
|
|
85
|
+
function ClientPreferencesRoot({ $data: $dataProp, className, children }) {
|
|
86
|
+
const $data = useDataOverride($dataProp);
|
|
87
|
+
const { canEditData } = useSession();
|
|
88
|
+
const readOnly = !canEditData;
|
|
89
|
+
const optinNewsLetter = Boolean($data?.clientPreferences?.optinNewsLetter ?? false);
|
|
90
|
+
const savePersonalData = Boolean($data?.clientPreferences?.savePersonalData ?? false);
|
|
91
|
+
const [pendingKeys, setPendingKeys] = useState(/* @__PURE__ */ new Set());
|
|
92
|
+
const [errorByKey, setErrorByKey] = useState({});
|
|
93
|
+
const trackWrite = useCallback((key, write) => {
|
|
94
|
+
setErrorByKey((prev) => ({
|
|
95
|
+
...prev,
|
|
96
|
+
[key]: []
|
|
97
|
+
}));
|
|
98
|
+
setPendingKeys((prev) => new Set(prev).add(key));
|
|
99
|
+
write.then((userErrors) => {
|
|
100
|
+
setErrorByKey((prev) => ({
|
|
101
|
+
...prev,
|
|
102
|
+
[key]: userErrors
|
|
103
|
+
}));
|
|
104
|
+
}).finally(() => {
|
|
105
|
+
setPendingKeys((prev) => {
|
|
106
|
+
const next = new Set(prev);
|
|
107
|
+
next.delete(key);
|
|
108
|
+
return next;
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
}, []);
|
|
112
|
+
const values = useMemo(() => ({
|
|
113
|
+
optinNewsLetter,
|
|
114
|
+
savePersonalData
|
|
115
|
+
}), [optinNewsLetter, savePersonalData]);
|
|
116
|
+
const contextValue = useMemo(() => ({
|
|
117
|
+
values,
|
|
118
|
+
trackWrite,
|
|
119
|
+
pendingKeys,
|
|
120
|
+
errorByKey,
|
|
121
|
+
readOnly
|
|
122
|
+
}), [
|
|
123
|
+
values,
|
|
124
|
+
trackWrite,
|
|
125
|
+
pendingKeys,
|
|
126
|
+
errorByKey,
|
|
127
|
+
readOnly
|
|
128
|
+
]);
|
|
129
|
+
return /* @__PURE__ */ jsx(ClientPreferencesContext, {
|
|
130
|
+
value: contextValue,
|
|
131
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
132
|
+
className,
|
|
133
|
+
"data-fs-client-preferences-root": "",
|
|
134
|
+
children
|
|
135
|
+
})
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Renders one bound opt-in checkbox by inlining `Field` + `Checkbox` + `Icon` (no `CheckboxField`
|
|
140
|
+
* particle). Reads ITS field's value, pending, and error from the section context and dispatches the
|
|
141
|
+
* write through `$actions.identity.clientPreferencesUpdate({ [key]: value })`, handing the promise to
|
|
142
|
+
* the section so the in-flight key and returned userErrors are tracked per field. The `fieldKey`,
|
|
143
|
+
* `dataAttr`, `pendingAttr`, and `readonlyAttr` are fixed by each registered Control; only
|
|
144
|
+
* `label`/`className` are merchant-configurable.
|
|
145
|
+
*/
|
|
146
|
+
function OptInControl({ fieldKey, dataAttr, pendingAttr, readonlyAttr, label, className, $actions }) {
|
|
147
|
+
const { values, trackWrite, pendingKeys, errorByKey, readOnly } = useClientPreferencesContext();
|
|
148
|
+
const fieldErrors = errorByKey[fieldKey] ?? [];
|
|
149
|
+
const value = values[fieldKey];
|
|
150
|
+
const pending = pendingKeys.has(fieldKey);
|
|
151
|
+
const disabled = pending || readOnly;
|
|
152
|
+
const [firstError] = fieldErrors;
|
|
153
|
+
const invalid = Boolean(firstError);
|
|
154
|
+
function handleCheckedChange(checked) {
|
|
155
|
+
const update = $actions?.identity?.clientPreferencesUpdate;
|
|
156
|
+
if (!update) return;
|
|
157
|
+
trackWrite(fieldKey, update({ [fieldKey]: checked }));
|
|
158
|
+
}
|
|
159
|
+
return /* @__PURE__ */ jsx("div", {
|
|
160
|
+
className,
|
|
161
|
+
[dataAttr]: "",
|
|
162
|
+
...pending ? { [pendingAttr]: "" } : {},
|
|
163
|
+
...readOnly ? { [readonlyAttr]: "" } : {},
|
|
164
|
+
children: /* @__PURE__ */ jsxs(Field.Root, {
|
|
165
|
+
invalid,
|
|
166
|
+
disabled,
|
|
167
|
+
"data-fs-field-root": "",
|
|
168
|
+
children: [/* @__PURE__ */ jsxs(Field.Label, { children: [/* @__PURE__ */ jsx(Checkbox.Root, {
|
|
169
|
+
checked: value,
|
|
170
|
+
onCheckedChange: handleCheckedChange,
|
|
171
|
+
disabled,
|
|
172
|
+
children: /* @__PURE__ */ jsx(Checkbox.Indicator, { children: /* @__PURE__ */ jsx(Icon, { name: "checked" }) })
|
|
173
|
+
}), label] }), invalid && firstError ? /* @__PURE__ */ jsx(Field.Error, {
|
|
174
|
+
match: true,
|
|
175
|
+
children: firstError.message
|
|
176
|
+
}) : null]
|
|
177
|
+
})
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
function NewsletterOptInControl(props) {
|
|
181
|
+
return /* @__PURE__ */ jsx(OptInControl, {
|
|
182
|
+
...props,
|
|
183
|
+
fieldKey: "optinNewsLetter",
|
|
184
|
+
dataAttr: "data-fs-newsletter-opt-in",
|
|
185
|
+
pendingAttr: "data-fs-newsletter-opt-in-pending",
|
|
186
|
+
readonlyAttr: "data-fs-newsletter-opt-in-readonly"
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
function SavePersonalDataOptInControl(props) {
|
|
190
|
+
return /* @__PURE__ */ jsx(OptInControl, {
|
|
191
|
+
...props,
|
|
192
|
+
fieldKey: "savePersonalData",
|
|
193
|
+
dataAttr: "data-fs-save-personal-data-opt-in",
|
|
194
|
+
pendingAttr: "data-fs-save-personal-data-opt-in-pending",
|
|
195
|
+
readonlyAttr: "data-fs-save-personal-data-opt-in-readonly"
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
const ClientPreferences = {
|
|
199
|
+
Root: ClientPreferencesRoot,
|
|
200
|
+
NewsletterOptInControl,
|
|
201
|
+
SavePersonalDataOptInControl
|
|
202
|
+
};
|
|
203
|
+
//#endregion
|
|
204
|
+
export { ClientPreferences, ClientPreferencesRoot, ClientPreferencesRootDefinition, NewsletterOptInControl, NewsletterOptInControlDefinition, SavePersonalDataOptInControl, SavePersonalDataOptInControlDefinition };
|
|
205
|
+
|
|
206
|
+
//# sourceMappingURL=client-preferences.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-preferences.js","names":[],"sources":["../../../src/matter/client-preferences/client-preferences.tsx"],"sourcesContent":["'use client';\n\nimport { defineComponent } from '@vtex/fs-core';\nimport { createContext, type ReactNode, useCallback, useContext, useMemo, useState } from 'react';\nimport { Checkbox } from '../../particles/checkbox/checkbox.js';\nimport { Field } from '../../particles/field/field.js';\nimport { Icon } from '../../particles/icon/icon.js';\nimport type { ComponentActions } from '../../sdk/actions/types.js';\nimport { useDataOverride } from '../../sdk/data/data-override-context.js';\nimport type { ClientPreferenceKey, ClientProfileUserError } from '../../sdk/identity/operations.js';\nimport { useSession } from '../session/session.js';\n\n/**\n * The `client-preferences` section matter (per ADR-0011: a matter is decomposed by DATA OWNERSHIP,\n * not per field). Both opt-ins — newsletter (`optinNewsLetter`) and save-personal-data\n * (`savePersonalData`) — are light booleans owned by the User Identity `ClientPreferences` entity\n * (a SIBLING of `Cart`, not nested under it, per the identity RFC), so they live under ONE\n * `ClientPreferencesRoot` that declares a single section fragment on `Query` selecting both fields.\n * The two merchant-facing Controls consume that one section context (ADR-0011 governs data\n * ownership, not the editor palette) and share one internal `OptInControl` implementation: the\n * section context, the `$data` → values seeding, the per-field pending/error tracking, the inlined\n * `Checkbox` + `Field` Control render, and dispatch via `$actions.identity.clientPreferencesUpdate`\n * (mirrors the `email-identification` matter; reads/writes follow ADR-0006 / ADR-0010 / ADR-0011).\n */\n\n// ---------------------------------------------------------------------------\n// GraphQL Fragment — colocated (ADR-0011), reads the ClientPreferences sibling\n// entity via Query. Authored as a raw string (not the codegen graphql() factory),\n// mirroring the EmailIdentification matter: the compiler derives the entity fragment\n// on `clientPreferences` and subscribes reactively. One section fragment owns both\n// opt-in fields (ADR-0011).\n// ---------------------------------------------------------------------------\n\nconst fragment = /* GraphQL */ `\n fragment ClientPreferencesData on Query {\n clientPreferences {\n __typename\n id\n optinNewsLetter\n savePersonalData\n }\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** The `$data` slice forwarded by the reactive runtime — the `ClientPreferences` sibling entity. */\nexport type ClientPreferencesData = {\n clientPreferences?: {\n optinNewsLetter?: boolean | null;\n savePersonalData?: boolean | null;\n } | null;\n} | null;\n\nexport type ClientPreferencesRootProps = {\n /** `Query` slice forwarded by the reactive runtime (value of the section fragment). */\n $data?: ClientPreferencesData;\n className?: string;\n children?: ReactNode;\n};\n\nexport type ClientPreferencesControlProps = {\n label: string;\n className?: string;\n /** Injected by the compiler from `actions: { identity: ['clientPreferencesUpdate'] }`; the write surface. */\n $actions?: ComponentActions;\n};\n\nexport type NewsletterOptInControlProps = ClientPreferencesControlProps;\nexport type SavePersonalDataOptInControlProps = ClientPreferencesControlProps;\n\n// ---------------------------------------------------------------------------\n// Definitions\n// ---------------------------------------------------------------------------\n\nexport const ClientPreferencesRootDefinition = defineComponent<ClientPreferencesRootProps>({\n name: 'ClientPreferencesRoot',\n importPath: '@vtex/faststore/components',\n component: ClientPreferencesRoot,\n fragment,\n fetchStrategy: 'reactive',\n providesContext: 'client-preferences',\n requiresContext: 'session',\n editor: { label: 'Client Preferences Root', category: 'identity' },\n schema: {},\n guideline:\n 'Binding provider for the consent opt-in section; reads both opt-in values (optinNewsLetter, savePersonalData) from the ClientPreferences identity entity (a sibling of Cart, via Query.clientPreferences) and exposes them to its Controls. Reads session state from useSession(); must be inside SessionRoot. Writes flow through $actions.identity.clientPreferencesUpdate. Wrap a NewsletterOptInControl and/or a SavePersonalDataOptInControl.',\n});\n\nexport const NewsletterOptInControlDefinition = defineComponent<NewsletterOptInControlProps>({\n name: 'NewsletterOptInControl',\n importPath: '@vtex/faststore/components',\n component: NewsletterOptInControl,\n requiresContext: 'client-preferences',\n actions: { identity: ['clientPreferencesUpdate'] },\n editor: { label: 'Newsletter Opt-In Control', category: 'identity' },\n schema: {\n label: { type: 'string', label: 'Label' },\n },\n guideline:\n 'The bound newsletter opt-in checkbox; must be a descendant of ClientPreferencesRoot. Toggling writes the optinNewsLetter preference via $actions.identity.clientPreferencesUpdate. Defaults to unchecked.',\n});\n\nexport const SavePersonalDataOptInControlDefinition = defineComponent<SavePersonalDataOptInControlProps>({\n name: 'SavePersonalDataOptInControl',\n importPath: '@vtex/faststore/components',\n component: SavePersonalDataOptInControl,\n requiresContext: 'client-preferences',\n actions: { identity: ['clientPreferencesUpdate'] },\n editor: { label: 'Save Personal Data Opt-In Control', category: 'identity' },\n schema: {\n label: { type: 'string', label: 'Label' },\n },\n guideline:\n 'The bound save-personal-data opt-in checkbox; must be a descendant of ClientPreferencesRoot. Toggling writes the savePersonalData preference via $actions.identity.clientPreferencesUpdate. Defaults to unchecked.',\n});\n\n// ---------------------------------------------------------------------------\n// Context\n// ---------------------------------------------------------------------------\n\ntype ClientPreferencesContextValue = Readonly<{\n /** Current value of each opt-in, seeded from the query response (null → unchecked). */\n values: Readonly<Record<ClientPreferenceKey, boolean>>;\n /**\n * Records that a write for `key` is in flight and stores its returned userErrors under that key so\n * each Control surfaces ITS OWN pending/error. The Control owns the actual dispatch (it holds\n * `$actions`); it hands the resulting promise here for the section to track.\n */\n trackWrite: (key: ClientPreferenceKey, write: Promise<readonly ClientProfileUserError[]>) => void;\n /**\n * The fields whose writes are currently in flight. A per-key set, not a single slot: concurrent\n * writes on different fields must each keep their own Control disabled until THEIR write settles.\n */\n pendingKeys: ReadonlySet<ClientPreferenceKey>;\n /** The userErrors returned by the most recent write, keyed by the field that produced them. */\n errorByKey: Readonly<Partial<Record<ClientPreferenceKey, readonly ClientProfileUserError[]>>>;\n /**\n * True when the session reports `canEditData: false` — VTEX refuses profile-data edits for an\n * identified-but-unauthenticated claimed profile, so the Controls render disabled instead of\n * accepting writes that are doomed server-side (mirrors the email control).\n */\n readOnly: boolean;\n}>;\n\nconst CLIENT_PREFERENCES_UNSET = Symbol('ClientPreferencesContextUnset');\n\nconst ClientPreferencesContext = createContext<ClientPreferencesContextValue | typeof CLIENT_PREFERENCES_UNSET>(\n CLIENT_PREFERENCES_UNSET,\n);\n\nfunction useClientPreferencesContext(): ClientPreferencesContextValue {\n const ctx = useContext(ClientPreferencesContext);\n if (ctx === CLIENT_PREFERENCES_UNSET) {\n throw new Error('A client-preferences Control must be used inside a ClientPreferencesRoot.');\n }\n return ctx;\n}\n\n// ---------------------------------------------------------------------------\n// Root\n// ---------------------------------------------------------------------------\n\n/**\n * Renders the client-preferences section Root: reads `$data` (the `ClientPreferences` sibling entity),\n * reads `useSession()` (which also enforces the `SessionRoot` ancestor, mirroring\n * `EmailIdentificationControl`), seeds both opt-in values from the section fragment, and publishes a\n * section context exposing both values plus per-field pending/error tracking. The write itself flows\n * through the Control's `$actions.identity.clientPreferencesUpdate` (ADR-0010); this Root tracks which\n * keys are in flight and stores the returned userErrors under each key so each Control surfaces ITS OWN\n * pending/error. When the session reports `canEditData: false` (identified but unauthenticated claimed\n * profile — VTEX refuses the write server-side) every Control renders disabled with its readonly\n * `data-fs-*` attribute, mirroring `EmailIdentificationControl`.\n */\nexport function ClientPreferencesRoot({ $data: $dataProp, className, children }: ClientPreferencesRootProps) {\n const $data = useDataOverride($dataProp);\n // Also enforces the SessionRoot ancestor: useSession() throws when rendered outside one.\n const { canEditData } = useSession();\n const readOnly = !canEditData;\n\n const optinNewsLetter = Boolean($data?.clientPreferences?.optinNewsLetter ?? false);\n const savePersonalData = Boolean($data?.clientPreferences?.savePersonalData ?? false);\n\n const [pendingKeys, setPendingKeys] = useState<ReadonlySet<ClientPreferenceKey>>(new Set());\n const [errorByKey, setErrorByKey] = useState<Partial<Record<ClientPreferenceKey, readonly ClientProfileUserError[]>>>(\n {},\n );\n\n const trackWrite = useCallback((key: ClientPreferenceKey, write: Promise<readonly ClientProfileUserError[]>) => {\n // Clear the key's stale error at the start of a retry (parity with the email control clearing\n // its serverError on a new write).\n setErrorByKey((prev) => ({ ...prev, [key]: [] }));\n setPendingKeys((prev) => new Set(prev).add(key));\n void write\n .then((userErrors) => {\n setErrorByKey((prev) => ({ ...prev, [key]: userErrors }));\n })\n .finally(() => {\n setPendingKeys((prev) => {\n const next = new Set(prev);\n next.delete(key);\n return next;\n });\n });\n }, []);\n\n const values = useMemo(() => ({ optinNewsLetter, savePersonalData }) as const, [optinNewsLetter, savePersonalData]);\n\n const contextValue = useMemo<ClientPreferencesContextValue>(\n () => ({ values, trackWrite, pendingKeys, errorByKey, readOnly }),\n [values, trackWrite, pendingKeys, errorByKey, readOnly],\n );\n\n return (\n <ClientPreferencesContext value={contextValue}>\n <div className={className} data-fs-client-preferences-root=\"\">\n {children}\n </div>\n </ClientPreferencesContext>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Controls\n// ---------------------------------------------------------------------------\n\n/**\n * Renders one bound opt-in checkbox by inlining `Field` + `Checkbox` + `Icon` (no `CheckboxField`\n * particle). Reads ITS field's value, pending, and error from the section context and dispatches the\n * write through `$actions.identity.clientPreferencesUpdate({ [key]: value })`, handing the promise to\n * the section so the in-flight key and returned userErrors are tracked per field. The `fieldKey`,\n * `dataAttr`, `pendingAttr`, and `readonlyAttr` are fixed by each registered Control; only\n * `label`/`className` are merchant-configurable.\n */\nfunction OptInControl({\n fieldKey,\n dataAttr,\n pendingAttr,\n readonlyAttr,\n label,\n className,\n $actions,\n}: ClientPreferencesControlProps & {\n fieldKey: ClientPreferenceKey;\n dataAttr: string;\n pendingAttr: string;\n readonlyAttr: string;\n}) {\n const { values, trackWrite, pendingKeys, errorByKey, readOnly } = useClientPreferencesContext();\n const fieldErrors = errorByKey[fieldKey] ?? [];\n const value = values[fieldKey];\n const pending = pendingKeys.has(fieldKey);\n const disabled = pending || readOnly;\n const [firstError] = fieldErrors;\n const invalid = Boolean(firstError);\n\n function handleCheckedChange(checked: boolean) {\n const update = $actions?.identity?.clientPreferencesUpdate;\n if (!update) return;\n trackWrite(fieldKey, update({ [fieldKey]: checked }));\n }\n\n return (\n <div\n className={className}\n {...{ [dataAttr]: '' }}\n {...(pending ? { [pendingAttr]: '' } : {})}\n {...(readOnly ? { [readonlyAttr]: '' } : {})}\n >\n <Field.Root invalid={invalid} disabled={disabled} data-fs-field-root=\"\">\n <Field.Label>\n <Checkbox.Root checked={value} onCheckedChange={handleCheckedChange} disabled={disabled}>\n <Checkbox.Indicator>\n <Icon name=\"checked\" />\n </Checkbox.Indicator>\n </Checkbox.Root>\n {label}\n </Field.Label>\n {invalid && firstError ? <Field.Error match>{firstError.message}</Field.Error> : null}\n </Field.Root>\n </div>\n );\n}\n\nexport function NewsletterOptInControl(props: NewsletterOptInControlProps) {\n return (\n <OptInControl\n {...props}\n fieldKey=\"optinNewsLetter\"\n dataAttr=\"data-fs-newsletter-opt-in\"\n pendingAttr=\"data-fs-newsletter-opt-in-pending\"\n readonlyAttr=\"data-fs-newsletter-opt-in-readonly\"\n />\n );\n}\n\nexport function SavePersonalDataOptInControl(props: SavePersonalDataOptInControlProps) {\n return (\n <OptInControl\n {...props}\n fieldKey=\"savePersonalData\"\n dataAttr=\"data-fs-save-personal-data-opt-in\"\n pendingAttr=\"data-fs-save-personal-data-opt-in-pending\"\n readonlyAttr=\"data-fs-save-personal-data-opt-in-readonly\"\n />\n );\n}\n\n// ---------------------------------------------------------------------------\n// Namespace export\n// ---------------------------------------------------------------------------\n\nexport const ClientPreferences = {\n Root: ClientPreferencesRoot,\n NewsletterOptInControl,\n SavePersonalDataOptInControl,\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { ComponentDefinition } from "../../core/dist/define-component.js";
|
|
2
|
+
import "../../core/dist/index.js";
|
|
3
|
+
import { ComponentActions } from "../../sdk/actions/types.js";
|
|
4
|
+
import { PhoneCountry } from "../../particles/phone-field/phone-field.js";
|
|
5
|
+
import { ReactNode } from "react";
|
|
6
|
+
//#region src/matter/client-profile/client-profile.d.ts
|
|
7
|
+
/** The `$data` slice forwarded by the reactive runtime — the `ClientProfile` sibling entity. */
|
|
8
|
+
export type ClientProfileData = {
|
|
9
|
+
clientProfile?: {
|
|
10
|
+
phone?: string | null;
|
|
11
|
+
} | null;
|
|
12
|
+
} | null;
|
|
13
|
+
export type ClientProfileRootProps = {
|
|
14
|
+
/** ClientProfile entity slice forwarded by the reactive runtime (value of the section fragment). */
|
|
15
|
+
$data?: ClientProfileData;
|
|
16
|
+
className?: string;
|
|
17
|
+
children?: ReactNode;
|
|
18
|
+
};
|
|
19
|
+
export declare const ClientProfileRootDefinition: ComponentDefinition<ClientProfileRootProps>;
|
|
20
|
+
/**
|
|
21
|
+
* Renders the client-profile section Root: reads `$data` (the `ClientProfile` sibling entity), seeds
|
|
22
|
+
* the profile values from the colocated fragment, and publishes a section context. It also reads
|
|
23
|
+
* `useSession()` — which enforces the `SessionRoot` ancestor. Writes are owned by the Control's
|
|
24
|
+
* `$actions.identity` (ADR-0010); the Root only supplies the pre-fill.
|
|
25
|
+
*/
|
|
26
|
+
export declare function ClientProfileRoot({ $data: $dataProp, className, children }: ClientProfileRootProps): import("react/jsx-runtime").JSX.Element;
|
|
27
|
+
type PhoneFieldRequirement = 'mandatory' | 'optional' | 'hidden';
|
|
28
|
+
export type ClientProfilePhoneControlProps = {
|
|
29
|
+
/** Visible field label. */
|
|
30
|
+
label?: string;
|
|
31
|
+
/** Selects the phone mask and validation rule. */
|
|
32
|
+
country?: PhoneCountry;
|
|
33
|
+
/** Controls field visibility and required validation. */
|
|
34
|
+
requirement?: PhoneFieldRequirement;
|
|
35
|
+
/** Error string shown when the input format is invalid. */
|
|
36
|
+
errorInvalid?: string;
|
|
37
|
+
/** Error string shown when the mandatory field is left empty. */
|
|
38
|
+
errorRequired?: string;
|
|
39
|
+
className?: string;
|
|
40
|
+
/** Injected by the compiler from `actions: { identity: ['clientProfileUpdate'] }`; the write surface. */
|
|
41
|
+
$actions?: ComponentActions;
|
|
42
|
+
};
|
|
43
|
+
export declare const ClientProfilePhoneControlDefinition: ComponentDefinition<ClientProfilePhoneControlProps>;
|
|
44
|
+
/**
|
|
45
|
+
* Renders the bound phone field by composing the reusable `PhoneField` particle. Reads the saved
|
|
46
|
+
* phone from the section context, and on a **changed** value persists only `phone` — normalized to
|
|
47
|
+
* E.164 — through `$actions.identity.clientProfileUpdate({ phone })` on blur (pessimistic,
|
|
48
|
+
* mirroring `EmailIdentificationControl`). While the write is in flight the field is disabled and
|
|
49
|
+
* `data-fs-client-profile-phone-pending` is present so a checkout-CTA guard can block. When the
|
|
50
|
+
* session reports `canEditData: false` the field renders disabled with
|
|
51
|
+
* `data-fs-client-profile-phone-readonly`. Server `userErrors` are surfaced inline.
|
|
52
|
+
*/
|
|
53
|
+
export declare function ClientProfilePhoneControl({ label, country, requirement, errorInvalid, errorRequired, className, $actions }: ClientProfilePhoneControlProps): import("react/jsx-runtime").JSX.Element;
|
|
54
|
+
export declare const ClientProfile: {
|
|
55
|
+
Root: typeof ClientProfileRoot;
|
|
56
|
+
PhoneControl: typeof ClientProfilePhoneControl;
|
|
57
|
+
};
|
|
58
|
+
//#endregion
|
|
59
|
+
//# sourceMappingURL=client-profile.d.ts.map
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { defineComponent } from "../../core/dist/define-component.js";
|
|
3
|
+
import "../../core/dist/index.js";
|
|
4
|
+
import { useDataOverride } from "../../sdk/data/data-override-context.js";
|
|
5
|
+
import { useSession } from "../session/session.js";
|
|
6
|
+
import { PhoneField, toE164, validatePhoneNumber } from "../../particles/phone-field/phone-field.js";
|
|
7
|
+
import { createContext, useContext, useMemo, useRef, useState } from "react";
|
|
8
|
+
import { jsx } from "react/jsx-runtime";
|
|
9
|
+
//#region src/matter/client-profile/client-profile.tsx
|
|
10
|
+
/**
|
|
11
|
+
* The `client-profile` section matter (per ADR-0011: a matter is decomposed by DATA OWNERSHIP, not
|
|
12
|
+
* per field). The shopper-profile fields recorded on the cart's `clientProfileData` live on the User
|
|
13
|
+
* Identity `ClientProfile` entity — a SIBLING of `Cart`, not nested under it. They are read through
|
|
14
|
+
* `Query.clientProfile` and written through the shared `$actions.identity.clientProfileUpdate`
|
|
15
|
+
* action, which performs a partial write that leaves the fields it is not given untouched.
|
|
16
|
+
*
|
|
17
|
+
* This matter wires only `phone`: a `ClientProfilePhoneControl` that composes the reusable,
|
|
18
|
+
* business-agnostic `PhoneField` particle (reused later in MyAccount / extensions; the binding here
|
|
19
|
+
* owns the data source and persistence). Room is kept for future profile Controls on the same Root.
|
|
20
|
+
* Reads follow the colocated-fragment Root pattern (ADR-0006, fetchStrategy 'reactive'), mirroring
|
|
21
|
+
* `EmailIdentificationControl`; writes flow through `$actions.identity` (ADR-0010). The write is
|
|
22
|
+
* pessimistic (awaits the mutation) and is dispatched on blur — form-bound saving via the profile-form
|
|
23
|
+
* CTA is a follow-up, not implemented here.
|
|
24
|
+
*/
|
|
25
|
+
const fragment = `
|
|
26
|
+
fragment ClientProfilePhoneData on Query {
|
|
27
|
+
clientProfile {
|
|
28
|
+
__typename
|
|
29
|
+
id
|
|
30
|
+
phone
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
`;
|
|
34
|
+
const CLIENT_PROFILE_UNSET = Symbol("ClientProfileContextUnset");
|
|
35
|
+
const ClientProfileContext = createContext(CLIENT_PROFILE_UNSET);
|
|
36
|
+
function useClientProfileContext() {
|
|
37
|
+
const ctx = useContext(ClientProfileContext);
|
|
38
|
+
if (ctx === CLIENT_PROFILE_UNSET) throw new Error("A client-profile Control must be used inside a ClientProfileRoot.");
|
|
39
|
+
return ctx;
|
|
40
|
+
}
|
|
41
|
+
const ClientProfileRootDefinition = defineComponent({
|
|
42
|
+
name: "ClientProfileRoot",
|
|
43
|
+
importPath: "@vtex/faststore/components",
|
|
44
|
+
component: ClientProfileRoot,
|
|
45
|
+
fragment,
|
|
46
|
+
fetchStrategy: "reactive",
|
|
47
|
+
providesContext: "client-profile",
|
|
48
|
+
requiresContext: "session",
|
|
49
|
+
editor: {
|
|
50
|
+
label: "Client Profile Root",
|
|
51
|
+
category: "identity"
|
|
52
|
+
},
|
|
53
|
+
schema: {},
|
|
54
|
+
guideline: "Binding provider for the shopper-profile section; reads the profile fields (today: phone) from the ClientProfile entity (Query.clientProfile) and exposes them to its Controls. Writes flow through $actions.identity.clientProfileUpdate. Must be inside SessionRoot. Wrap a ClientProfilePhoneControl."
|
|
55
|
+
});
|
|
56
|
+
/**
|
|
57
|
+
* Renders the client-profile section Root: reads `$data` (the `ClientProfile` sibling entity), seeds
|
|
58
|
+
* the profile values from the colocated fragment, and publishes a section context. It also reads
|
|
59
|
+
* `useSession()` — which enforces the `SessionRoot` ancestor. Writes are owned by the Control's
|
|
60
|
+
* `$actions.identity` (ADR-0010); the Root only supplies the pre-fill.
|
|
61
|
+
*/
|
|
62
|
+
function ClientProfileRoot({ $data: $dataProp, className, children }) {
|
|
63
|
+
const $data = useDataOverride($dataProp);
|
|
64
|
+
useSession();
|
|
65
|
+
const phone = $data?.clientProfile?.phone ?? "";
|
|
66
|
+
const contextValue = useMemo(() => ({ phone }), [phone]);
|
|
67
|
+
return /* @__PURE__ */ jsx(ClientProfileContext, {
|
|
68
|
+
value: contextValue,
|
|
69
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
70
|
+
className,
|
|
71
|
+
"data-fs-client-profile-root": "",
|
|
72
|
+
children
|
|
73
|
+
})
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
const ClientProfilePhoneControlDefinition = defineComponent({
|
|
77
|
+
name: "ClientProfilePhoneControl",
|
|
78
|
+
importPath: "@vtex/faststore/components",
|
|
79
|
+
component: ClientProfilePhoneControl,
|
|
80
|
+
requiresContext: "client-profile",
|
|
81
|
+
actions: { identity: ["clientProfileUpdate"] },
|
|
82
|
+
editor: {
|
|
83
|
+
label: "Client Profile Phone Control",
|
|
84
|
+
category: "identity"
|
|
85
|
+
},
|
|
86
|
+
schema: {
|
|
87
|
+
label: {
|
|
88
|
+
type: "string",
|
|
89
|
+
default: "Phone",
|
|
90
|
+
label: "Label"
|
|
91
|
+
},
|
|
92
|
+
country: {
|
|
93
|
+
type: "string",
|
|
94
|
+
default: "US",
|
|
95
|
+
label: "Country (US or BR)"
|
|
96
|
+
},
|
|
97
|
+
requirement: {
|
|
98
|
+
type: "string",
|
|
99
|
+
default: "mandatory",
|
|
100
|
+
label: "Requirement"
|
|
101
|
+
},
|
|
102
|
+
errorInvalid: {
|
|
103
|
+
type: "string",
|
|
104
|
+
default: "Invalid phone number",
|
|
105
|
+
label: "Invalid error message"
|
|
106
|
+
},
|
|
107
|
+
errorRequired: {
|
|
108
|
+
type: "string",
|
|
109
|
+
default: "Phone number is required",
|
|
110
|
+
label: "Required error message"
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
guideline: "The bound phone field; must be a descendant of ClientProfileRoot. Reads the saved phone from the ClientProfile entity and persists it on blur via $actions.identity.clientProfileUpdate({ phone }). Composes the reusable PhoneField particle."
|
|
114
|
+
});
|
|
115
|
+
/**
|
|
116
|
+
* Renders the bound phone field by composing the reusable `PhoneField` particle. Reads the saved
|
|
117
|
+
* phone from the section context, and on a **changed** value persists only `phone` — normalized to
|
|
118
|
+
* E.164 — through `$actions.identity.clientProfileUpdate({ phone })` on blur (pessimistic,
|
|
119
|
+
* mirroring `EmailIdentificationControl`). While the write is in flight the field is disabled and
|
|
120
|
+
* `data-fs-client-profile-phone-pending` is present so a checkout-CTA guard can block. When the
|
|
121
|
+
* session reports `canEditData: false` the field renders disabled with
|
|
122
|
+
* `data-fs-client-profile-phone-readonly`. Server `userErrors` are surfaced inline.
|
|
123
|
+
*/
|
|
124
|
+
function ClientProfilePhoneControl({ label = "Phone", country = "US", requirement = "mandatory", errorInvalid = "Invalid phone number", errorRequired = "Phone number is required", className, $actions }) {
|
|
125
|
+
const { phone: savedPhone } = useClientProfileContext();
|
|
126
|
+
const { canEditData } = useSession();
|
|
127
|
+
const readOnly = !canEditData;
|
|
128
|
+
const [draft, setDraft] = useState(savedPhone);
|
|
129
|
+
const [pending, setPending] = useState(false);
|
|
130
|
+
const [serverError, setServerError] = useState(null);
|
|
131
|
+
const prevSavedRef = useRef(savedPhone);
|
|
132
|
+
if (prevSavedRef.current !== savedPhone) {
|
|
133
|
+
prevSavedRef.current = savedPhone;
|
|
134
|
+
setDraft(savedPhone);
|
|
135
|
+
}
|
|
136
|
+
function handleValueChange(next) {
|
|
137
|
+
setDraft(next);
|
|
138
|
+
if (serverError) setServerError(null);
|
|
139
|
+
}
|
|
140
|
+
async function handleBlur() {
|
|
141
|
+
const clientProfileUpdate = $actions?.identity?.clientProfileUpdate;
|
|
142
|
+
if (!clientProfileUpdate) return;
|
|
143
|
+
if (draft === savedPhone) return;
|
|
144
|
+
const isEmpty = !draft.trim();
|
|
145
|
+
if (requirement === "mandatory" && isEmpty) return;
|
|
146
|
+
if (!isEmpty && !validatePhoneNumber(draft, country)) return;
|
|
147
|
+
const phone = isEmpty ? "" : toE164(draft, country);
|
|
148
|
+
if (phone === savedPhone) return;
|
|
149
|
+
setPending(true);
|
|
150
|
+
setServerError(null);
|
|
151
|
+
try {
|
|
152
|
+
const errors = await clientProfileUpdate({ phone }) ?? [];
|
|
153
|
+
if (errors.length > 0) setServerError(errors[0]?.message ?? null);
|
|
154
|
+
} finally {
|
|
155
|
+
setPending(false);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return /* @__PURE__ */ jsx("div", {
|
|
159
|
+
className,
|
|
160
|
+
"data-fs-client-profile-phone-control": "",
|
|
161
|
+
...pending ? { "data-fs-client-profile-phone-pending": "" } : {},
|
|
162
|
+
...readOnly ? { "data-fs-client-profile-phone-readonly": "" } : {},
|
|
163
|
+
children: /* @__PURE__ */ jsx(PhoneField, {
|
|
164
|
+
label,
|
|
165
|
+
country,
|
|
166
|
+
requirement,
|
|
167
|
+
errorInvalid,
|
|
168
|
+
errorRequired,
|
|
169
|
+
value: draft,
|
|
170
|
+
onValueChange: handleValueChange,
|
|
171
|
+
onBlur: handleBlur,
|
|
172
|
+
isDisabled: pending || readOnly,
|
|
173
|
+
invalid: serverError != null || void 0,
|
|
174
|
+
error: serverError ?? void 0
|
|
175
|
+
})
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
const ClientProfile = {
|
|
179
|
+
Root: ClientProfileRoot,
|
|
180
|
+
PhoneControl: ClientProfilePhoneControl
|
|
181
|
+
};
|
|
182
|
+
//#endregion
|
|
183
|
+
export { ClientProfile, ClientProfilePhoneControl, ClientProfilePhoneControlDefinition, ClientProfileRoot, ClientProfileRootDefinition };
|
|
184
|
+
|
|
185
|
+
//# sourceMappingURL=client-profile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-profile.js","names":[],"sources":["../../../src/matter/client-profile/client-profile.tsx"],"sourcesContent":["'use client';\n\nimport { defineComponent } from '@vtex/fs-core';\nimport { createContext, type ReactNode, useContext, useMemo, useRef, useState } from 'react';\nimport type { PhoneCountry } from '../../particles/phone-field/phone-field.js';\nimport { PhoneField, toE164, validatePhoneNumber } from '../../particles/phone-field/phone-field.js';\nimport type { ComponentActions } from '../../sdk/actions/types.js';\nimport { useDataOverride } from '../../sdk/data/data-override-context.js';\nimport { useSession } from '../session/session.js';\n\n/**\n * The `client-profile` section matter (per ADR-0011: a matter is decomposed by DATA OWNERSHIP, not\n * per field). The shopper-profile fields recorded on the cart's `clientProfileData` live on the User\n * Identity `ClientProfile` entity — a SIBLING of `Cart`, not nested under it. They are read through\n * `Query.clientProfile` and written through the shared `$actions.identity.clientProfileUpdate`\n * action, which performs a partial write that leaves the fields it is not given untouched.\n *\n * This matter wires only `phone`: a `ClientProfilePhoneControl` that composes the reusable,\n * business-agnostic `PhoneField` particle (reused later in MyAccount / extensions; the binding here\n * owns the data source and persistence). Room is kept for future profile Controls on the same Root.\n * Reads follow the colocated-fragment Root pattern (ADR-0006, fetchStrategy 'reactive'), mirroring\n * `EmailIdentificationControl`; writes flow through `$actions.identity` (ADR-0010). The write is\n * pessimistic (awaits the mutation) and is dispatched on blur — form-bound saving via the profile-form\n * CTA is a follow-up, not implemented here.\n */\n\n// ---------------------------------------------------------------------------\n// GraphQL Fragment — colocated on the ClientProfile sibling entity (ADR-0011)\n// ---------------------------------------------------------------------------\n\nconst fragment = /* GraphQL */ `\n fragment ClientProfilePhoneData on Query {\n clientProfile {\n __typename\n id\n phone\n }\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Raw data shape of the section fragment\n// ---------------------------------------------------------------------------\n\n/** The `$data` slice forwarded by the reactive runtime — the `ClientProfile` sibling entity. */\nexport type ClientProfileData = {\n clientProfile?: {\n phone?: string | null;\n } | null;\n} | null;\n\n// ---------------------------------------------------------------------------\n// Context — the Root publishes the seeded profile values to its Controls\n// ---------------------------------------------------------------------------\n\nexport type ClientProfileContextValue = Readonly<{\n /** Current value of each profile field, seeded from the ClientProfile entity (null → empty). */\n phone: string;\n}>;\n\nconst CLIENT_PROFILE_UNSET = Symbol('ClientProfileContextUnset');\n\nconst ClientProfileContext = createContext<ClientProfileContextValue | typeof CLIENT_PROFILE_UNSET>(\n CLIENT_PROFILE_UNSET,\n);\n\nfunction useClientProfileContext(): ClientProfileContextValue {\n const ctx = useContext(ClientProfileContext);\n if (ctx === CLIENT_PROFILE_UNSET) {\n throw new Error('A client-profile Control must be used inside a ClientProfileRoot.');\n }\n return ctx;\n}\n\n// ---------------------------------------------------------------------------\n// Root\n// ---------------------------------------------------------------------------\n\nexport type ClientProfileRootProps = {\n /** ClientProfile entity slice forwarded by the reactive runtime (value of the section fragment). */\n $data?: ClientProfileData;\n className?: string;\n children?: ReactNode;\n};\n\nexport const ClientProfileRootDefinition = defineComponent<ClientProfileRootProps>({\n name: 'ClientProfileRoot',\n importPath: '@vtex/faststore/components',\n component: ClientProfileRoot,\n fragment,\n fetchStrategy: 'reactive',\n providesContext: 'client-profile',\n requiresContext: 'session',\n editor: { label: 'Client Profile Root', category: 'identity' },\n schema: {},\n guideline:\n 'Binding provider for the shopper-profile section; reads the profile fields (today: phone) from the ClientProfile entity (Query.clientProfile) and exposes them to its Controls. Writes flow through $actions.identity.clientProfileUpdate. Must be inside SessionRoot. Wrap a ClientProfilePhoneControl.',\n});\n\n/**\n * Renders the client-profile section Root: reads `$data` (the `ClientProfile` sibling entity), seeds\n * the profile values from the colocated fragment, and publishes a section context. It also reads\n * `useSession()` — which enforces the `SessionRoot` ancestor. Writes are owned by the Control's\n * `$actions.identity` (ADR-0010); the Root only supplies the pre-fill.\n */\nexport function ClientProfileRoot({ $data: $dataProp, className, children }: ClientProfileRootProps) {\n const $data = useDataOverride($dataProp);\n // Reads identification state and, as a side effect, throws when rendered outside <SessionRoot>.\n useSession();\n\n const phone = $data?.clientProfile?.phone ?? '';\n\n const contextValue = useMemo<ClientProfileContextValue>(() => ({ phone }), [phone]);\n\n return (\n <ClientProfileContext value={contextValue}>\n <div className={className} data-fs-client-profile-root=\"\">\n {children}\n </div>\n </ClientProfileContext>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Phone Control\n// ---------------------------------------------------------------------------\n\ntype PhoneFieldRequirement = 'mandatory' | 'optional' | 'hidden';\n\nexport type ClientProfilePhoneControlProps = {\n /** Visible field label. */\n label?: string;\n /** Selects the phone mask and validation rule. */\n country?: PhoneCountry;\n /** Controls field visibility and required validation. */\n requirement?: PhoneFieldRequirement;\n /** Error string shown when the input format is invalid. */\n errorInvalid?: string;\n /** Error string shown when the mandatory field is left empty. */\n errorRequired?: string;\n className?: string;\n /** Injected by the compiler from `actions: { identity: ['clientProfileUpdate'] }`; the write surface. */\n $actions?: ComponentActions;\n};\n\nexport const ClientProfilePhoneControlDefinition = defineComponent<ClientProfilePhoneControlProps>({\n name: 'ClientProfilePhoneControl',\n importPath: '@vtex/faststore/components',\n component: ClientProfilePhoneControl,\n requiresContext: 'client-profile',\n actions: { identity: ['clientProfileUpdate'] },\n editor: { label: 'Client Profile Phone Control', category: 'identity' },\n schema: {\n label: { type: 'string', default: 'Phone', label: 'Label' },\n country: { type: 'string', default: 'US', label: 'Country (US or BR)' },\n requirement: { type: 'string', default: 'mandatory', label: 'Requirement' },\n errorInvalid: { type: 'string', default: 'Invalid phone number', label: 'Invalid error message' },\n errorRequired: { type: 'string', default: 'Phone number is required', label: 'Required error message' },\n },\n guideline:\n 'The bound phone field; must be a descendant of ClientProfileRoot. Reads the saved phone from the ClientProfile entity and persists it on blur via $actions.identity.clientProfileUpdate({ phone }). Composes the reusable PhoneField particle.',\n});\n\n/**\n * Renders the bound phone field by composing the reusable `PhoneField` particle. Reads the saved\n * phone from the section context, and on a **changed** value persists only `phone` — normalized to\n * E.164 — through `$actions.identity.clientProfileUpdate({ phone })` on blur (pessimistic,\n * mirroring `EmailIdentificationControl`). While the write is in flight the field is disabled and\n * `data-fs-client-profile-phone-pending` is present so a checkout-CTA guard can block. When the\n * session reports `canEditData: false` the field renders disabled with\n * `data-fs-client-profile-phone-readonly`. Server `userErrors` are surfaced inline.\n */\nexport function ClientProfilePhoneControl({\n label = 'Phone',\n country = 'US',\n requirement = 'mandatory',\n errorInvalid = 'Invalid phone number',\n errorRequired = 'Phone number is required',\n className,\n $actions,\n}: ClientProfilePhoneControlProps) {\n const { phone: savedPhone } = useClientProfileContext();\n // VTEX refuses profile edits for an identified-but-unauthenticated claimed profile; render the\n // field read-only instead of accepting a write that is doomed server-side (mirrors\n // EmailIdentificationControl).\n const { canEditData } = useSession();\n const readOnly = !canEditData;\n const [draft, setDraft] = useState(savedPhone);\n const [pending, setPending] = useState(false);\n const [serverError, setServerError] = useState<string | null>(null);\n\n // Re-seed the local draft when the saved value changes (e.g. cache update after a write, or a\n // logged-in shopper's profile resolving). Like the email control's pre-fill sync, this overwrites\n // any in-progress draft — the profile is the source of truth when it changes.\n const prevSavedRef = useRef(savedPhone);\n if (prevSavedRef.current !== savedPhone) {\n // react-doctor-disable-next-line no-ref-current-in-render -- paired with the setDraft call right below, both replay together\n prevSavedRef.current = savedPhone;\n setDraft(savedPhone);\n }\n\n function handleValueChange(next: string) {\n setDraft(next);\n if (serverError) setServerError(null);\n }\n\n async function handleBlur() {\n const clientProfileUpdate = $actions?.identity?.clientProfileUpdate;\n if (!clientProfileUpdate) return;\n // Untouched → nothing to persist.\n if (draft === savedPhone) return;\n // Client-side invalid → skip the write and let the PhoneField's inline error stand; don't\n // rely on server userErrors for a value the mask/validator already rejects. Mirrors the\n // validity the PhoneField particle computes on blur (mandatory-empty or bad format).\n const isEmpty = !draft.trim();\n if (requirement === 'mandatory' && isEmpty) return;\n if (!isEmpty && !validatePhoneNumber(draft, country)) return;\n const phone = isEmpty ? '' : toE164(draft, country);\n // Unchanged after normalization (e.g. the saved \"+12015551234\" re-typed as \"2015551234\") →\n // nothing to persist either.\n if (phone === savedPhone) return;\n\n setPending(true);\n setServerError(null);\n try {\n const errors = (await clientProfileUpdate({ phone })) ?? [];\n if (errors.length > 0) setServerError(errors[0]?.message ?? null);\n } finally {\n setPending(false);\n }\n }\n\n return (\n <div\n className={className}\n data-fs-client-profile-phone-control=\"\"\n {...(pending ? { 'data-fs-client-profile-phone-pending': '' } : {})}\n {...(readOnly ? { 'data-fs-client-profile-phone-readonly': '' } : {})}\n >\n <PhoneField\n label={label}\n country={country}\n requirement={requirement}\n errorInvalid={errorInvalid}\n errorRequired={errorRequired}\n value={draft}\n onValueChange={handleValueChange}\n onBlur={handleBlur}\n isDisabled={pending || readOnly}\n invalid={serverError != null || undefined}\n error={serverError ?? undefined}\n />\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Namespace export\n// ---------------------------------------------------------------------------\n\nexport const ClientProfile = {\n Root: ClientProfileRoot,\n PhoneControl: ClientProfilePhoneControl,\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { ComponentDefinition } from "../../core/dist/define-component.js";
|
|
2
|
+
import "../../core/dist/index.js";
|
|
3
|
+
import { ComponentActions } from "../../sdk/actions/types.js";
|
|
4
|
+
import { PhoneCountry } from "../../particles/phone-field/phone-field.js";
|
|
5
|
+
import { ReactNode } from "react";
|
|
6
|
+
//#region src/matter/client-profile-form/client-profile-form.d.ts
|
|
7
|
+
/** The `$data` slice forwarded by the reactive runtime — both identity sibling entities. */
|
|
8
|
+
export type ClientProfileFormData = {
|
|
9
|
+
clientProfile?: {
|
|
10
|
+
email?: string | null;
|
|
11
|
+
firstName?: string | null;
|
|
12
|
+
lastName?: string | null;
|
|
13
|
+
phone?: string | null;
|
|
14
|
+
document?: string | null;
|
|
15
|
+
} | null;
|
|
16
|
+
clientPreferences?: {
|
|
17
|
+
optinNewsLetter?: boolean | null;
|
|
18
|
+
savePersonalData?: boolean | null;
|
|
19
|
+
} | null;
|
|
20
|
+
} | null;
|
|
21
|
+
export type ClientProfileFormRootProps = {
|
|
22
|
+
/** Phone mask/validation country, provided to the phone leaf via context. */
|
|
23
|
+
country?: PhoneCountry;
|
|
24
|
+
/** Locale document type; the document leaf renders only when supported. Provided via context. */
|
|
25
|
+
documentType?: string;
|
|
26
|
+
className?: string;
|
|
27
|
+
children?: ReactNode;
|
|
28
|
+
/** `ClientProfileFormData` slice forwarded by the reactive runtime. */
|
|
29
|
+
$data?: ClientProfileFormData;
|
|
30
|
+
/** Compiler-injected action surface; carries `identity.clientProfileUpdate` / `clientPreferencesUpdate`. */
|
|
31
|
+
$actions?: ComponentActions;
|
|
32
|
+
};
|
|
33
|
+
export type ClientProfileFormFieldsetProps = {
|
|
34
|
+
/** Visible legend; omitted (no title) when unset. */
|
|
35
|
+
legend?: string;
|
|
36
|
+
/** Value emitted on `data-fs-client-profile-form-section` for scoped styling (e.g. `profile`). */
|
|
37
|
+
section?: string;
|
|
38
|
+
className?: string;
|
|
39
|
+
children?: ReactNode;
|
|
40
|
+
};
|
|
41
|
+
type LabelledFieldProps = {
|
|
42
|
+
label?: string;
|
|
43
|
+
className?: string;
|
|
44
|
+
};
|
|
45
|
+
export type ClientProfileFormEmailFieldProps = LabelledFieldProps;
|
|
46
|
+
export type ClientProfileFormFirstNameFieldProps = LabelledFieldProps;
|
|
47
|
+
export type ClientProfileFormLastNameFieldProps = LabelledFieldProps;
|
|
48
|
+
export type ClientProfileFormPhoneFieldProps = LabelledFieldProps;
|
|
49
|
+
export type ClientProfileFormDocumentFieldProps = LabelledFieldProps;
|
|
50
|
+
export type ClientProfileFormNewsletterCheckboxProps = LabelledFieldProps;
|
|
51
|
+
export type ClientProfileFormSavePersonalDataCheckboxProps = LabelledFieldProps;
|
|
52
|
+
export type ClientProfileFormErrorProps = {
|
|
53
|
+
className?: string;
|
|
54
|
+
};
|
|
55
|
+
export type ClientProfileFormConfirmationProps = {
|
|
56
|
+
message?: string;
|
|
57
|
+
className?: string;
|
|
58
|
+
};
|
|
59
|
+
export type ClientProfileFormSubmitButtonProps = {
|
|
60
|
+
label?: string;
|
|
61
|
+
className?: string;
|
|
62
|
+
children?: ReactNode;
|
|
63
|
+
};
|
|
64
|
+
export declare const ClientProfileFormRootDefinition: ComponentDefinition<ClientProfileFormRootProps>;
|
|
65
|
+
export declare const ClientProfileFormFieldsetDefinition: ComponentDefinition<ClientProfileFormFieldsetProps>;
|
|
66
|
+
export declare const ClientProfileFormEmailFieldDefinition: ComponentDefinition<LabelledFieldProps>;
|
|
67
|
+
export declare const ClientProfileFormFirstNameFieldDefinition: ComponentDefinition<LabelledFieldProps>;
|
|
68
|
+
export declare const ClientProfileFormLastNameFieldDefinition: ComponentDefinition<LabelledFieldProps>;
|
|
69
|
+
export declare const ClientProfileFormPhoneFieldDefinition: ComponentDefinition<LabelledFieldProps>;
|
|
70
|
+
export declare const ClientProfileFormDocumentFieldDefinition: ComponentDefinition<LabelledFieldProps>;
|
|
71
|
+
export declare const ClientProfileFormNewsletterCheckboxDefinition: ComponentDefinition<LabelledFieldProps>;
|
|
72
|
+
export declare const ClientProfileFormSavePersonalDataCheckboxDefinition: ComponentDefinition<LabelledFieldProps>;
|
|
73
|
+
export declare const ClientProfileFormErrorDefinition: ComponentDefinition<ClientProfileFormErrorProps>;
|
|
74
|
+
export declare const ClientProfileFormConfirmationDefinition: ComponentDefinition<ClientProfileFormConfirmationProps>;
|
|
75
|
+
export declare const ClientProfileFormSubmitButtonDefinition: ComponentDefinition<ClientProfileFormSubmitButtonProps>;
|
|
76
|
+
/**
|
|
77
|
+
* Data root + form shell. Seeds a local draft from `$data`, tracks dirty fields (background `$data`
|
|
78
|
+
* refreshes only re-seed untouched fields), runs format-only validation, and on Save dispatches the
|
|
79
|
+
* batched `clientProfileUpdate` / `clientPreferencesUpdate` (touched fields only), showing the
|
|
80
|
+
* confirmation on success. Provides everything the field leaves need via context; renders a `<form>`
|
|
81
|
+
* around its children.
|
|
82
|
+
*
|
|
83
|
+
* It publishes nothing. A finished press is not announced, so no section collapses as a result and
|
|
84
|
+
* nothing outside this form can react to it. Whether a checkout sequences on a completed form is left to
|
|
85
|
+
* the flow-of-steps RFC (#611).
|
|
86
|
+
*/
|
|
87
|
+
export declare function ClientProfileFormRoot({ country, documentType, className, children, $data: $dataProp, $actions }: ClientProfileFormRootProps): import("react/jsx-runtime").JSX.Element;
|
|
88
|
+
export declare function ClientProfileFormFieldset({ legend, section, className, children }: ClientProfileFormFieldsetProps): import("react/jsx-runtime").JSX.Element;
|
|
89
|
+
export declare function ClientProfileFormEmailField({ label, className }: ClientProfileFormEmailFieldProps): import("react/jsx-runtime").JSX.Element;
|
|
90
|
+
export declare function ClientProfileFormFirstNameField({ label, className }: ClientProfileFormFirstNameFieldProps): import("react/jsx-runtime").JSX.Element;
|
|
91
|
+
export declare function ClientProfileFormLastNameField({ label, className }: ClientProfileFormLastNameFieldProps): import("react/jsx-runtime").JSX.Element;
|
|
92
|
+
export declare function ClientProfileFormPhoneField({ label, className }: ClientProfileFormPhoneFieldProps): import("react/jsx-runtime").JSX.Element;
|
|
93
|
+
export declare function ClientProfileFormDocumentField({ label, className }: ClientProfileFormDocumentFieldProps): import("react/jsx-runtime").JSX.Element | null;
|
|
94
|
+
export declare function ClientProfileFormNewsletterCheckbox({ label, className }: ClientProfileFormNewsletterCheckboxProps): import("react/jsx-runtime").JSX.Element;
|
|
95
|
+
export declare function ClientProfileFormSavePersonalDataCheckbox({ label, className }: ClientProfileFormSavePersonalDataCheckboxProps): import("react/jsx-runtime").JSX.Element;
|
|
96
|
+
export declare function ClientProfileFormError({ className }: ClientProfileFormErrorProps): import("react/jsx-runtime").JSX.Element | null;
|
|
97
|
+
export declare function ClientProfileFormConfirmation({ message, className }: ClientProfileFormConfirmationProps): import("react/jsx-runtime").JSX.Element | null;
|
|
98
|
+
export declare function ClientProfileFormSubmitButton({ label, className, children }: ClientProfileFormSubmitButtonProps): import("react/jsx-runtime").JSX.Element | null;
|
|
99
|
+
export declare const ClientProfileForm: {
|
|
100
|
+
Root: typeof ClientProfileFormRoot;
|
|
101
|
+
RootDefinition: ComponentDefinition<ClientProfileFormRootProps>;
|
|
102
|
+
Fieldset: typeof ClientProfileFormFieldset;
|
|
103
|
+
FieldsetDefinition: ComponentDefinition<ClientProfileFormFieldsetProps>;
|
|
104
|
+
EmailField: typeof ClientProfileFormEmailField;
|
|
105
|
+
EmailFieldDefinition: ComponentDefinition<LabelledFieldProps>;
|
|
106
|
+
FirstNameField: typeof ClientProfileFormFirstNameField;
|
|
107
|
+
FirstNameFieldDefinition: ComponentDefinition<LabelledFieldProps>;
|
|
108
|
+
LastNameField: typeof ClientProfileFormLastNameField;
|
|
109
|
+
LastNameFieldDefinition: ComponentDefinition<LabelledFieldProps>;
|
|
110
|
+
PhoneField: typeof ClientProfileFormPhoneField;
|
|
111
|
+
PhoneFieldDefinition: ComponentDefinition<LabelledFieldProps>;
|
|
112
|
+
DocumentField: typeof ClientProfileFormDocumentField;
|
|
113
|
+
DocumentFieldDefinition: ComponentDefinition<LabelledFieldProps>;
|
|
114
|
+
NewsletterCheckbox: typeof ClientProfileFormNewsletterCheckbox;
|
|
115
|
+
NewsletterCheckboxDefinition: ComponentDefinition<LabelledFieldProps>;
|
|
116
|
+
SavePersonalDataCheckbox: typeof ClientProfileFormSavePersonalDataCheckbox;
|
|
117
|
+
SavePersonalDataCheckboxDefinition: ComponentDefinition<LabelledFieldProps>;
|
|
118
|
+
Error: typeof ClientProfileFormError;
|
|
119
|
+
ErrorDefinition: ComponentDefinition<ClientProfileFormErrorProps>;
|
|
120
|
+
Confirmation: typeof ClientProfileFormConfirmation;
|
|
121
|
+
ConfirmationDefinition: ComponentDefinition<ClientProfileFormConfirmationProps>;
|
|
122
|
+
SubmitButton: typeof ClientProfileFormSubmitButton;
|
|
123
|
+
SubmitButtonDefinition: ComponentDefinition<ClientProfileFormSubmitButtonProps>;
|
|
124
|
+
};
|
|
125
|
+
//#endregion
|
|
126
|
+
//# sourceMappingURL=client-profile-form.d.ts.map
|