@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 @@
|
|
|
1
|
+
{"version":3,"file":"client-profile-form.js","names":["PhoneFieldParticle","DocumentFieldParticle"],"sources":["../../../src/matter/client-profile-form/client-profile-form.tsx"],"sourcesContent":["'use client';\n\nimport { defineComponent } from '@vtex/fs-core';\nimport { createContext, type FormEvent, type ReactNode, useContext, useRef, useState } from 'react';\nimport { Checkbox } from '../../particles/checkbox/checkbox.js';\nimport {\n DocumentField as DocumentFieldParticle,\n isSupportedDocumentType,\n isValidDocument,\n} from '../../particles/document-field/document-field.js';\nimport { Field } from '../../particles/field/field.js';\nimport { Fieldset } from '../../particles/fieldset/fieldset.js';\nimport { Icon } from '../../particles/icon/icon.js';\nimport type { PhoneCountry } from '../../particles/phone-field/phone-field.js';\nimport {\n PhoneField as PhoneFieldParticle,\n toE164,\n validatePhoneNumber,\n} 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 type { ClientProfileUserError } from '../../sdk/identity/operations.js';\nimport { useSession } from '../session/session.js';\n\n/**\n * The `client-profile-form` compound (specs/fspg-863-client-profile-form.md) — the batched,\n * explicit-save customer-information form, decomposed into freely-composable parts. `Root` owns the\n * mechanics (a local draft across BOTH sibling identity entities, dirty tracking, format validation,\n * a single batched Save that dispatches at most one `clientProfileUpdate` and one\n * `clientPreferencesUpdate` per press carrying only touched fields, and the confirmation on a clean\n * save); it publishes no signal, so nothing outside it reacts to a completed press. The\n * field/fieldset/feedback leaves are thin, context-bound, and placed by the\n * schema author in any order/subset.\n *\n * Composability is the point: a merchant whose platform config drops a field, reorders them, or adds\n * a derived one just composes accordingly — nothing is hard-coded into a closed template. A part that\n * needs extra data declares its own `requiresContext`.\n *\n * Email is read-only (identification, not profile data — `EmailIdentificationControl`'s job). The\n * document field self-gates on `isSupportedDocumentType(documentType)`.\n */\n\n// ---------------------------------------------------------------------------\n// GraphQL Fragment — colocated on Root (ADR-0011), self-contained data root\n// ---------------------------------------------------------------------------\n\nconst fragment = /* GraphQL */ `\n fragment ClientProfileFormData on Query {\n clientProfile {\n __typename\n id\n email\n firstName\n lastName\n phone\n document\n }\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 — both identity sibling entities. */\nexport type ClientProfileFormData = {\n clientProfile?: {\n email?: string | null;\n firstName?: string | null;\n lastName?: string | null;\n phone?: string | null;\n document?: string | null;\n } | null;\n clientPreferences?: {\n optinNewsLetter?: boolean | null;\n savePersonalData?: boolean | null;\n } | null;\n} | null;\n\ntype Draft = {\n firstName: string;\n lastName: string;\n phone: string;\n document: string;\n optinNewsLetter: boolean;\n savePersonalData: boolean;\n};\n\ntype FieldKey = keyof Draft;\ntype TextFieldKey = 'firstName' | 'lastName';\ntype CheckboxKey = 'optinNewsLetter' | 'savePersonalData';\ntype ValidatableFieldKey = 'phone' | 'document';\ntype FieldErrors = Partial<Record<ValidatableFieldKey, string>>;\n\nconst VALIDATION_ORDER: readonly ValidatableFieldKey[] = ['phone', 'document'];\n\n/** Shown when a write throws instead of resolving `userErrors`; the resolved case carries its own message. */\nconst SAVE_FAILED_MESSAGE = 'Unable to save your information. Please try again.';\n\nfunction stripNonDigits(value: string): string {\n return value.replace(/\\D/g, '');\n}\n\n// ---------------------------------------------------------------------------\n// Context — Root publishes the draft + mechanics to its field leaves\n// ---------------------------------------------------------------------------\n\ntype ClientProfileFormContextValue = {\n savedEmail: string;\n draft: Draft;\n fieldErrors: FieldErrors;\n disabled: boolean;\n readOnly: boolean;\n pending: boolean;\n serverError: string | null;\n saved: boolean;\n country: PhoneCountry;\n documentType: string | undefined;\n setText: (key: TextFieldKey, value: string) => void;\n setPhone: (value: string) => void;\n setDocument: (value: string) => void;\n setCheckbox: (key: CheckboxKey, checked: boolean) => void;\n};\n\nconst CLIENT_PROFILE_FORM_UNSET = Symbol('ClientProfileFormContextUnset');\n\nconst ClientProfileFormContext = createContext<ClientProfileFormContextValue | typeof CLIENT_PROFILE_FORM_UNSET>(\n CLIENT_PROFILE_FORM_UNSET,\n);\n\nfunction useClientProfileFormContext(): ClientProfileFormContextValue {\n const ctx = useContext(ClientProfileFormContext);\n if (ctx === CLIENT_PROFILE_FORM_UNSET) {\n throw new Error('ClientProfileForm parts must be used inside ClientProfileForm.Root.');\n }\n return ctx;\n}\n\n// ---------------------------------------------------------------------------\n// Props\n// ---------------------------------------------------------------------------\n\nexport type ClientProfileFormRootProps = {\n /** Phone mask/validation country, provided to the phone leaf via context. */\n country?: PhoneCountry;\n /** Locale document type; the document leaf renders only when supported. Provided via context. */\n documentType?: string;\n className?: string;\n children?: ReactNode;\n /** `ClientProfileFormData` slice forwarded by the reactive runtime. */\n $data?: ClientProfileFormData;\n /** Compiler-injected action surface; carries `identity.clientProfileUpdate` / `clientPreferencesUpdate`. */\n $actions?: ComponentActions;\n};\n\nexport type ClientProfileFormFieldsetProps = {\n /** Visible legend; omitted (no title) when unset. */\n legend?: string;\n /** Value emitted on `data-fs-client-profile-form-section` for scoped styling (e.g. `profile`). */\n section?: string;\n className?: string;\n children?: ReactNode;\n};\n\ntype LabelledFieldProps = { label?: string; className?: string };\n\nexport type ClientProfileFormEmailFieldProps = LabelledFieldProps;\nexport type ClientProfileFormFirstNameFieldProps = LabelledFieldProps;\nexport type ClientProfileFormLastNameFieldProps = LabelledFieldProps;\nexport type ClientProfileFormPhoneFieldProps = LabelledFieldProps;\nexport type ClientProfileFormDocumentFieldProps = LabelledFieldProps;\nexport type ClientProfileFormNewsletterCheckboxProps = LabelledFieldProps;\nexport type ClientProfileFormSavePersonalDataCheckboxProps = LabelledFieldProps;\nexport type ClientProfileFormErrorProps = { className?: string };\nexport type ClientProfileFormConfirmationProps = { message?: string; className?: string };\nexport type ClientProfileFormSubmitButtonProps = { label?: string; className?: string; children?: ReactNode };\n\n// ---------------------------------------------------------------------------\n// Definitions\n// ---------------------------------------------------------------------------\n\nexport const ClientProfileFormRootDefinition = defineComponent<ClientProfileFormRootProps>({\n name: 'ClientProfileFormRoot',\n importPath: '@vtex/faststore/components',\n component: ClientProfileFormRoot,\n fragment,\n fetchStrategy: 'reactive',\n requiresContext: 'session',\n providesContext: 'client-profile-form',\n actions: { identity: ['clientProfileUpdate', 'clientPreferencesUpdate'] },\n editor: { label: 'Client Profile Form Root', category: 'action' },\n schema: {\n country: { type: 'string', default: 'US', label: 'Phone country (US or BR)' },\n documentType: { type: 'string', label: 'Document type (e.g. CPF)' },\n },\n guideline:\n 'Data root + form mechanics for the batched customer-information form: owns the draft across clientProfile + clientPreferences, dirty tracking, format-only validation (never requiredness), one batched Save (dispatches only touched fields), and the confirmation on a clean save. It reports nothing to anything outside itself. Requires a SessionRoot ancestor. Compose the field/fieldset/feedback parts as children in any order/subset. See client-profile-form.md.',\n});\n\nexport const ClientProfileFormFieldsetDefinition = defineComponent<ClientProfileFormFieldsetProps>({\n name: 'ClientProfileFormFieldset',\n importPath: '@vtex/faststore/components',\n component: ClientProfileFormFieldset,\n requiresContext: 'client-profile-form',\n editor: { label: 'Client Profile Form Fieldset', category: 'layout' },\n schema: {\n legend: { type: 'string', label: 'Legend' },\n section: { type: 'string', label: 'Section name (data-fs hook)' },\n },\n guideline:\n 'Optional grouping wrapper: a Fieldset whose disabled state follows the form, with an optional legend and a `section` name emitted on data-fs-client-profile-form-section for scoped styling. Compose any subset of the field parts as children. Must be inside ClientProfileForm.Root.',\n});\n\n// Each field leaf is registered with its own inline `defineComponent({...})` — the native catalog\n// builder statically extracts only that literal form, so a factory helper would leave these parts out\n// of catalog.json (and thus uncomposable in a store schema). See client-profile-form.test.tsx's\n// catalog-completeness guard.\n\nexport const ClientProfileFormEmailFieldDefinition = defineComponent<ClientProfileFormEmailFieldProps>({\n name: 'ClientProfileFormEmailField',\n importPath: '@vtex/faststore/components',\n component: ClientProfileFormEmailField,\n requiresContext: 'client-profile-form',\n editor: { label: 'Client Profile Email Field', category: 'action' },\n schema: { label: { type: 'string', default: 'Email', label: 'Label' } },\n guideline: 'Read-only email display, seeded from the profile. Must be inside ClientProfileForm.Root.',\n});\n\nexport const ClientProfileFormFirstNameFieldDefinition = defineComponent<ClientProfileFormFirstNameFieldProps>({\n name: 'ClientProfileFormFirstNameField',\n importPath: '@vtex/faststore/components',\n component: ClientProfileFormFirstNameField,\n requiresContext: 'client-profile-form',\n editor: { label: 'Client Profile First Name Field', category: 'action' },\n schema: { label: { type: 'string', default: 'First name', label: 'Label' } },\n guideline: 'First-name text field bound to the form draft. Must be inside ClientProfileForm.Root.',\n});\n\nexport const ClientProfileFormLastNameFieldDefinition = defineComponent<ClientProfileFormLastNameFieldProps>({\n name: 'ClientProfileFormLastNameField',\n importPath: '@vtex/faststore/components',\n component: ClientProfileFormLastNameField,\n requiresContext: 'client-profile-form',\n editor: { label: 'Client Profile Last Name Field', category: 'action' },\n schema: { label: { type: 'string', default: 'Last name', label: 'Label' } },\n guideline: 'Last-name text field bound to the form draft. Must be inside ClientProfileForm.Root.',\n});\n\nexport const ClientProfileFormPhoneFieldDefinition = defineComponent<ClientProfileFormPhoneFieldProps>({\n name: 'ClientProfileFormPhoneField',\n importPath: '@vtex/faststore/components',\n component: ClientProfileFormPhoneField,\n requiresContext: 'client-profile-form',\n editor: { label: 'Client Profile Phone Field', category: 'action' },\n schema: { label: { type: 'string', default: 'Phone number', label: 'Label' } },\n guideline:\n 'Country-masked phone field (country from Root); format-validated on Save. Must be inside ClientProfileForm.Root.',\n});\n\nexport const ClientProfileFormDocumentFieldDefinition = defineComponent<ClientProfileFormDocumentFieldProps>({\n name: 'ClientProfileFormDocumentField',\n importPath: '@vtex/faststore/components',\n component: ClientProfileFormDocumentField,\n requiresContext: 'client-profile-form',\n editor: { label: 'Client Profile Document Field', category: 'action' },\n schema: { label: { type: 'string', default: 'CPF', label: 'Label' } },\n guideline:\n 'Tax-document field; self-gates on Root.documentType and check-digit-validates on Save. Must be inside ClientProfileForm.Root.',\n});\n\nexport const ClientProfileFormNewsletterCheckboxDefinition = defineComponent<ClientProfileFormNewsletterCheckboxProps>({\n name: 'ClientProfileFormNewsletterCheckbox',\n importPath: '@vtex/faststore/components',\n component: ClientProfileFormNewsletterCheckbox,\n requiresContext: 'client-profile-form',\n editor: { label: 'Client Profile Newsletter Checkbox', category: 'action' },\n schema: { label: { type: 'string', default: 'Email me with news and offers', label: 'Label' } },\n guideline: 'Newsletter opt-in checkbox bound to the form draft. Must be inside ClientProfileForm.Root.',\n});\n\nexport const ClientProfileFormSavePersonalDataCheckboxDefinition =\n defineComponent<ClientProfileFormSavePersonalDataCheckboxProps>({\n name: 'ClientProfileFormSavePersonalDataCheckbox',\n importPath: '@vtex/faststore/components',\n component: ClientProfileFormSavePersonalDataCheckbox,\n requiresContext: 'client-profile-form',\n editor: { label: 'Client Profile Save-Personal-Data Checkbox', category: 'action' },\n schema: { label: { type: 'string', default: 'Save my information for next time', label: 'Label' } },\n guideline: 'Save-personal-data opt-in checkbox bound to the form draft. Must be inside ClientProfileForm.Root.',\n });\n\nexport const ClientProfileFormErrorDefinition = defineComponent<ClientProfileFormErrorProps>({\n name: 'ClientProfileFormError',\n importPath: '@vtex/faststore/components',\n component: ClientProfileFormError,\n requiresContext: 'client-profile-form',\n editor: { label: 'Client Profile Form Error', category: 'content' },\n schema: {},\n guideline:\n 'Renders the inline server error (role=\"alert\") from the last Save, or nothing. Must be inside ClientProfileForm.Root.',\n});\n\nexport const ClientProfileFormConfirmationDefinition = defineComponent<ClientProfileFormConfirmationProps>({\n name: 'ClientProfileFormConfirmation',\n importPath: '@vtex/faststore/components',\n component: ClientProfileFormConfirmation,\n requiresContext: 'client-profile-form',\n editor: { label: 'Client Profile Form Confirmation', category: 'content' },\n schema: { message: { type: 'string', default: 'Your information has been saved.', label: 'Confirmation message' } },\n guideline:\n 'Renders the success confirmation (an <output>) after a Save with no errors, cleared on the next edit. Must be inside ClientProfileForm.Root.',\n});\n\nexport const ClientProfileFormSubmitButtonDefinition = defineComponent<ClientProfileFormSubmitButtonProps>({\n name: 'ClientProfileFormSubmitButton',\n importPath: '@vtex/faststore/components',\n component: ClientProfileFormSubmitButton,\n requiresContext: 'client-profile-form',\n editor: { label: 'Client Profile Form Submit Button', category: 'action' },\n schema: { label: { type: 'string', default: 'Save and continue', label: 'Button label' } },\n guideline:\n 'The batched-Save submit button (type=submit). Disabled while a write is in flight; renders nothing when the session is read-only. Compose an Icon + text as children, or rely on `label`. Must be inside ClientProfileForm.Root.',\n});\n\n// ---------------------------------------------------------------------------\n// Validation — field-intrinsic format only\n//\n// Which fields a shopper must fill is a business rule, and the parts of this form are composed freely\n// by the schema, so a required check here can fire for a field the page never mounted: nothing renders\n// the message, focus has nowhere to land, and Save goes dead. Requiredness waits for the RFC that\n// decides where it belongs.\n// ---------------------------------------------------------------------------\n\nfunction validateDraft(draft: Draft, country: PhoneCountry, documentType: string | undefined): FieldErrors {\n const errors: FieldErrors = {};\n\n const phoneRaw = draft.phone.trim();\n if (phoneRaw && !validatePhoneNumber(phoneRaw, country)) {\n errors.phone = 'Invalid phone number';\n }\n\n if (isSupportedDocumentType(documentType)) {\n const digits = stripNonDigits(draft.document);\n if (digits && !isValidDocument(digits, documentType)) {\n errors.document = 'Invalid document number';\n }\n }\n\n return errors;\n}\n\n// ---------------------------------------------------------------------------\n// Root\n// ---------------------------------------------------------------------------\n\n/**\n * Data root + form shell. Seeds a local draft from `$data`, tracks dirty fields (background `$data`\n * refreshes only re-seed untouched fields), runs format-only validation, and on Save dispatches the\n * batched `clientProfileUpdate` / `clientPreferencesUpdate` (touched fields only), showing the\n * confirmation on success. Provides everything the field leaves need via context; renders a `<form>`\n * around its children.\n *\n * It publishes nothing. A finished press is not announced, so no section collapses as a result and\n * nothing outside this form can react to it. Whether a checkout sequences on a completed form is left to\n * the flow-of-steps RFC (#611).\n */\nexport function ClientProfileFormRoot({\n country = 'US',\n documentType,\n className,\n children,\n $data: $dataProp,\n $actions,\n}: ClientProfileFormRootProps) {\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 savedEmail = $data?.clientProfile?.email ?? '';\n const savedFirstName = $data?.clientProfile?.firstName ?? '';\n const savedLastName = $data?.clientProfile?.lastName ?? '';\n const savedPhone = $data?.clientProfile?.phone ?? '';\n const savedDocument = $data?.clientProfile?.document ?? '';\n const savedOptinNewsLetter = Boolean($data?.clientPreferences?.optinNewsLetter ?? false);\n const savedSavePersonalData = Boolean($data?.clientPreferences?.savePersonalData ?? false);\n\n const [draft, setDraft] = useState<Draft>(() => ({\n firstName: savedFirstName,\n lastName: savedLastName,\n phone: savedPhone,\n document: savedDocument,\n optinNewsLetter: savedOptinNewsLetter,\n savePersonalData: savedSavePersonalData,\n }));\n const [dirtyFields, setDirtyFields] = useState<ReadonlySet<FieldKey>>(new Set());\n const [fieldErrors, setFieldErrors] = useState<FieldErrors>({});\n const [pending, setPending] = useState(false);\n const [serverError, setServerError] = useState<string | null>(null);\n const [saved, setSaved] = useState(false);\n\n const formRef = useRef<HTMLFormElement>(null);\n\n // Re-seed pristine fields when the underlying saved entities change; dirty fields are never\n // clobbered. Runs during render (ref-comparison), so the re-seed lands in the same commit.\n const prevSavedRef = useRef({\n firstName: savedFirstName,\n lastName: savedLastName,\n phone: savedPhone,\n document: savedDocument,\n optinNewsLetter: savedOptinNewsLetter,\n savePersonalData: savedSavePersonalData,\n });\n const prevSaved = prevSavedRef.current;\n const changedKeys: FieldKey[] = [];\n if (prevSaved.firstName !== savedFirstName) changedKeys.push('firstName');\n if (prevSaved.lastName !== savedLastName) changedKeys.push('lastName');\n if (prevSaved.phone !== savedPhone) changedKeys.push('phone');\n if (prevSaved.document !== savedDocument) changedKeys.push('document');\n if (prevSaved.optinNewsLetter !== savedOptinNewsLetter) changedKeys.push('optinNewsLetter');\n if (prevSaved.savePersonalData !== savedSavePersonalData) changedKeys.push('savePersonalData');\n if (changedKeys.length > 0) {\n const nextSaved = {\n firstName: savedFirstName,\n lastName: savedLastName,\n phone: savedPhone,\n document: savedDocument,\n optinNewsLetter: savedOptinNewsLetter,\n savePersonalData: savedSavePersonalData,\n };\n // react-doctor-disable-next-line no-ref-current-in-render -- paired with the setDraft call right below, both replay together\n prevSavedRef.current = nextSaved;\n setDraft((prevDraft) => {\n let next = prevDraft;\n for (const key of changedKeys) {\n if (dirtyFields.has(key)) continue;\n if (next === prevDraft) next = { ...prevDraft };\n (next as Record<FieldKey, string | boolean>)[key] = nextSaved[key];\n }\n return next;\n });\n }\n\n const disabled = pending || readOnly;\n\n function markDirty(key: FieldKey) {\n setDirtyFields((prev) => {\n if (prev.has(key)) return prev;\n const next = new Set(prev);\n next.add(key);\n return next;\n });\n }\n\n function clearFeedback() {\n if (saved) setSaved(false);\n if (serverError) setServerError(null);\n }\n\n function clearFieldError(key: ValidatableFieldKey) {\n if (fieldErrors[key]) {\n setFieldErrors((prev) => {\n const next = { ...prev };\n delete next[key];\n return next;\n });\n }\n }\n\n function setText(key: TextFieldKey, value: string) {\n setDraft((prev) => ({ ...prev, [key]: value }));\n markDirty(key);\n clearFeedback();\n }\n\n function setPhone(value: string) {\n setDraft((prev) => ({ ...prev, phone: value }));\n markDirty('phone');\n clearFeedback();\n clearFieldError('phone');\n }\n\n function setDocument(value: string) {\n setDraft((prev) => ({ ...prev, document: value }));\n markDirty('document');\n clearFeedback();\n clearFieldError('document');\n }\n\n function setCheckbox(key: CheckboxKey, checked: boolean) {\n setDraft((prev) => ({ ...prev, [key]: checked }));\n markDirty(key);\n clearFeedback();\n }\n\n function focusField(key: ValidatableFieldKey) {\n const el = formRef.current?.querySelector<HTMLInputElement>(`[data-fs-client-profile-form-field=\"${key}\"] input`);\n el?.focus();\n }\n\n async function handleSubmit(event: FormEvent<HTMLFormElement>) {\n event.preventDefault();\n if (readOnly || pending) return;\n\n // Validation runs before the pristine shortcut below, not after: a stored value can be malformed\n // without anything having been typed this session, and a press that reached the shortcut first would\n // confirm it as acceptable.\n const errors = validateDraft(draft, country, documentType);\n if (Object.keys(errors).length > 0) {\n setFieldErrors(errors);\n const firstInvalid = VALIDATION_ORDER.find((key) => errors[key]);\n if (firstInvalid) focusField(firstInvalid);\n return;\n }\n setFieldErrors({});\n\n // Nothing changed: dispatch nothing, which also avoids the NO_*_PROVIDED user errors. The press\n // still confirms, because a shopper who opens an already-filled form and presses Save is asking\n // whether their data is accepted, and a silent return answers nothing.\n if (dirtyFields.size === 0) {\n setServerError(null);\n setSaved(true);\n return;\n }\n\n const identity = $actions?.identity;\n if (!identity) return;\n\n const profilePayload: Record<string, string> = {};\n if (dirtyFields.has('firstName')) profilePayload.firstName = draft.firstName.trim();\n if (dirtyFields.has('lastName')) profilePayload.lastName = draft.lastName.trim();\n // toE164 is documented for values validatePhoneNumber has accepted; on a blank one it would return\n // the bare country code, writing \"+55\" over the shopper's number and then failing every later Save.\n if (dirtyFields.has('phone')) {\n profilePayload.phone = draft.phone.trim() ? toE164(draft.phone, country) : '';\n }\n if (dirtyFields.has('document')) profilePayload.document = stripNonDigits(draft.document);\n\n const preferencesPayload: Record<string, boolean> = {};\n if (dirtyFields.has('optinNewsLetter')) preferencesPayload.optinNewsLetter = draft.optinNewsLetter;\n if (dirtyFields.has('savePersonalData')) preferencesPayload.savePersonalData = draft.savePersonalData;\n\n const writes: Promise<readonly ClientProfileUserError[]>[] = [];\n if (Object.keys(profilePayload).length > 0 && identity.clientProfileUpdate) {\n writes.push(identity.clientProfileUpdate(profilePayload));\n }\n if (Object.keys(preferencesPayload).length > 0 && identity.clientPreferencesUpdate) {\n writes.push(identity.clientPreferencesUpdate(preferencesPayload));\n }\n if (writes.length === 0) return;\n\n setPending(true);\n setServerError(null);\n setSaved(false);\n try {\n const results = await Promise.all(writes);\n const allErrors = results.flat();\n if (allErrors.length > 0) {\n setServerError(allErrors[0]?.message ?? null);\n return;\n }\n setDirtyFields(new Set());\n setSaved(true);\n } catch (error) {\n // A write that throws rather than resolving userErrors would otherwise snap the form back to idle\n // with no message, losing the edit silently and escaping as an unhandled rejection. The dirty marks\n // stay, so the shopper can press Save again without retyping.\n console.error('[ClientProfileForm] profile write failed:', error);\n setServerError(SAVE_FAILED_MESSAGE);\n } finally {\n setPending(false);\n }\n }\n\n const contextValue: ClientProfileFormContextValue = {\n savedEmail,\n draft,\n fieldErrors,\n disabled,\n readOnly,\n pending,\n serverError,\n saved,\n country,\n documentType,\n setText,\n setPhone,\n setDocument,\n setCheckbox,\n };\n\n return (\n <ClientProfileFormContext.Provider value={contextValue}>\n <form\n ref={formRef}\n onSubmit={handleSubmit}\n className={className}\n data-fs-client-profile-form=\"\"\n {...(pending ? { 'data-fs-client-profile-form-pending': '' } : {})}\n {...(readOnly ? { 'data-fs-client-profile-form-readonly': '' } : {})}\n {...(saved ? { 'data-fs-client-profile-form-saved': '' } : {})}\n >\n {children}\n </form>\n </ClientProfileFormContext.Provider>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Fieldset (optional grouping)\n// ---------------------------------------------------------------------------\n\nexport function ClientProfileFormFieldset({ legend, section, className, children }: ClientProfileFormFieldsetProps) {\n const { disabled } = useClientProfileFormContext();\n return (\n <Fieldset.Root\n disabled={disabled}\n className={className}\n {...(section ? { 'data-fs-client-profile-form-section': section } : {})}\n >\n {legend ? <Fieldset.Legend>{legend}</Fieldset.Legend> : null}\n {children}\n </Fieldset.Root>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Field leaves\n// ---------------------------------------------------------------------------\n\nexport function ClientProfileFormEmailField({ label = 'Email', className }: ClientProfileFormEmailFieldProps) {\n const { savedEmail, disabled } = useClientProfileFormContext();\n return (\n <Field.Root className={className} data-fs-client-profile-form-field=\"email\" disabled={disabled}>\n <Field.Label>{label}</Field.Label>\n <Field.Control readOnly value={savedEmail} disabled={disabled} />\n </Field.Root>\n );\n}\n\nfunction TextField({ fieldKey, label, className }: { fieldKey: TextFieldKey; label: string; className?: string }) {\n const { draft, disabled, setText } = useClientProfileFormContext();\n const attr = fieldKey === 'firstName' ? 'first-name' : 'last-name';\n const autoComplete = fieldKey === 'firstName' ? 'given-name' : 'family-name';\n return (\n <Field.Root className={className} data-fs-client-profile-form-field={attr} disabled={disabled}>\n <Field.Label>{label}</Field.Label>\n <Field.Control\n name={fieldKey}\n autoComplete={autoComplete}\n value={draft[fieldKey]}\n onChange={(event) => setText(fieldKey, event.target.value)}\n disabled={disabled}\n />\n </Field.Root>\n );\n}\n\nexport function ClientProfileFormFirstNameField({\n label = 'First name',\n className,\n}: ClientProfileFormFirstNameFieldProps) {\n return <TextField fieldKey=\"firstName\" label={label} className={className} />;\n}\n\nexport function ClientProfileFormLastNameField({\n label = 'Last name',\n className,\n}: ClientProfileFormLastNameFieldProps) {\n return <TextField fieldKey=\"lastName\" label={label} className={className} />;\n}\n\nexport function ClientProfileFormPhoneField({ label = 'Phone number', className }: ClientProfileFormPhoneFieldProps) {\n const { draft, fieldErrors, disabled, country, setPhone } = useClientProfileFormContext();\n return (\n <div className={className} data-fs-client-profile-form-field=\"phone\">\n <PhoneFieldParticle\n label={label}\n country={country}\n value={draft.phone}\n onValueChange={setPhone}\n isDisabled={disabled}\n invalid={fieldErrors.phone ? true : undefined}\n error={fieldErrors.phone}\n />\n </div>\n );\n}\n\nexport function ClientProfileFormDocumentField({ label = 'CPF', className }: ClientProfileFormDocumentFieldProps) {\n const { draft, fieldErrors, disabled, documentType, setDocument } = useClientProfileFormContext();\n if (!isSupportedDocumentType(documentType)) return null;\n return (\n <div className={className} data-fs-client-profile-form-field=\"document\">\n <DocumentFieldParticle\n label={label}\n documentType={documentType}\n value={draft.document}\n onValueChange={setDocument}\n disabled={disabled}\n invalid={Boolean(fieldErrors.document)}\n errorMessage={fieldErrors.document ?? 'Invalid document number'}\n />\n </div>\n );\n}\n\nfunction CheckboxField({\n fieldKey,\n attr,\n label,\n className,\n}: {\n fieldKey: CheckboxKey;\n attr: string;\n label: string;\n className?: string;\n}) {\n const { draft, disabled, setCheckbox } = useClientProfileFormContext();\n return (\n <Field.Root className={className} data-fs-client-profile-form-field={attr} disabled={disabled}>\n <Field.Label>\n <Checkbox.Root\n checked={draft[fieldKey]}\n onCheckedChange={(checked) => setCheckbox(fieldKey, checked)}\n disabled={disabled}\n >\n <Checkbox.Indicator>\n <Icon name=\"checked\" />\n </Checkbox.Indicator>\n </Checkbox.Root>\n {label}\n </Field.Label>\n </Field.Root>\n );\n}\n\nexport function ClientProfileFormNewsletterCheckbox({\n label = 'Email me with news and offers',\n className,\n}: ClientProfileFormNewsletterCheckboxProps) {\n return <CheckboxField fieldKey=\"optinNewsLetter\" attr=\"newsletter\" label={label} className={className} />;\n}\n\nexport function ClientProfileFormSavePersonalDataCheckbox({\n label = 'Save my information for next time',\n className,\n}: ClientProfileFormSavePersonalDataCheckboxProps) {\n return <CheckboxField fieldKey=\"savePersonalData\" attr=\"save-personal-data\" label={label} className={className} />;\n}\n\n// ---------------------------------------------------------------------------\n// Feedback + submit\n// ---------------------------------------------------------------------------\n\nexport function ClientProfileFormError({ className }: ClientProfileFormErrorProps) {\n const { serverError } = useClientProfileFormContext();\n if (!serverError) return null;\n return (\n <div role=\"alert\" className={className} data-fs-client-profile-form-error=\"\">\n {serverError}\n </div>\n );\n}\n\nexport function ClientProfileFormConfirmation({\n message = 'Your information has been saved.',\n className,\n}: ClientProfileFormConfirmationProps) {\n const { saved } = useClientProfileFormContext();\n if (!saved) return null;\n return (\n <output className={className} data-fs-client-profile-form-confirmation=\"\">\n {message}\n </output>\n );\n}\n\nexport function ClientProfileFormSubmitButton({\n label = 'Save and continue',\n className,\n children,\n}: ClientProfileFormSubmitButtonProps) {\n const { pending, readOnly } = useClientProfileFormContext();\n if (readOnly) return null;\n return (\n <button\n type=\"submit\"\n disabled={pending}\n className={className}\n data-fs-button=\"\"\n data-fs-client-profile-form-save=\"\"\n >\n {children ?? label}\n </button>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Namespace Export\n// ---------------------------------------------------------------------------\n\nexport const ClientProfileForm = {\n Root: ClientProfileFormRoot,\n RootDefinition: ClientProfileFormRootDefinition,\n Fieldset: ClientProfileFormFieldset,\n FieldsetDefinition: ClientProfileFormFieldsetDefinition,\n EmailField: ClientProfileFormEmailField,\n EmailFieldDefinition: ClientProfileFormEmailFieldDefinition,\n FirstNameField: ClientProfileFormFirstNameField,\n FirstNameFieldDefinition: ClientProfileFormFirstNameFieldDefinition,\n LastNameField: ClientProfileFormLastNameField,\n LastNameFieldDefinition: ClientProfileFormLastNameFieldDefinition,\n PhoneField: ClientProfileFormPhoneField,\n PhoneFieldDefinition: ClientProfileFormPhoneFieldDefinition,\n DocumentField: ClientProfileFormDocumentField,\n DocumentFieldDefinition: ClientProfileFormDocumentFieldDefinition,\n NewsletterCheckbox: ClientProfileFormNewsletterCheckbox,\n NewsletterCheckboxDefinition: ClientProfileFormNewsletterCheckboxDefinition,\n SavePersonalDataCheckbox: ClientProfileFormSavePersonalDataCheckbox,\n SavePersonalDataCheckboxDefinition: ClientProfileFormSavePersonalDataCheckboxDefinition,\n Error: ClientProfileFormError,\n ErrorDefinition: ClientProfileFormErrorDefinition,\n Confirmation: ClientProfileFormConfirmation,\n ConfirmationDefinition: ClientProfileFormConfirmationDefinition,\n SubmitButton: ClientProfileFormSubmitButton,\n SubmitButtonDefinition: ClientProfileFormSubmitButtonDefinition,\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ComponentDefinition } from "../../core/dist/define-component.js";
|
|
2
|
+
import "../../core/dist/index.js";
|
|
3
|
+
import { ShippingOption } from "../shipping-simulator/shipping-simulator.js";
|
|
4
|
+
import { ComponentActions } from "../../sdk/actions/types.js";
|
|
5
|
+
import { RawDeliveryOptionsData } from "./use-delivery-option-selection.js";
|
|
6
|
+
import { ComponentPropsWithRef } from "react";
|
|
7
|
+
//#region src/matter/delivery-options/delivery-options-accordion.d.ts
|
|
8
|
+
export type DeliveryOptionsAccordionProps = ComponentPropsWithRef<'button'> & {
|
|
9
|
+
/** Optional prefix shown before the summary value on the trigger row (e.g. "Forma de entrega"). */
|
|
10
|
+
label?: string;
|
|
11
|
+
/** Text shown on the trigger row while nothing is selected. */
|
|
12
|
+
placeholder?: string;
|
|
13
|
+
/** Separator between the selected option name and price on the trigger row. */
|
|
14
|
+
separator?: string;
|
|
15
|
+
/** Disclosure icon shown on the trigger. The compiler's per-route sprite is built from explicit
|
|
16
|
+
* `icon`-typed prop values in the schema, so a page must set this rather than rely on the default. */
|
|
17
|
+
icon?: string;
|
|
18
|
+
/** Overrides the default collapsible panel styling (height-animation + overflow clip). */
|
|
19
|
+
panelClassName?: string;
|
|
20
|
+
/** Shipping slice forwarded by the reactive runtime; `null` until shipping resolves. */
|
|
21
|
+
$data?: RawDeliveryOptionsData | null;
|
|
22
|
+
/** Compiler-injected action surface; carries `shipping.selectOption`. */
|
|
23
|
+
$actions?: ComponentActions;
|
|
24
|
+
/** Local/dev fallback rows, used only when the reactive fetch resolves no options. */
|
|
25
|
+
mockOptions?: ShippingOption[];
|
|
26
|
+
};
|
|
27
|
+
export declare const DeliveryOptionsAccordionDefinition: ComponentDefinition<DeliveryOptionsAccordionProps>;
|
|
28
|
+
export declare function DeliveryOptionsAccordion({ label, placeholder, separator, icon, panelClassName, $data, $actions, mockOptions, className, children, ...props }: DeliveryOptionsAccordionProps): import("react/jsx-runtime").JSX.Element;
|
|
29
|
+
//#endregion
|
|
30
|
+
//# sourceMappingURL=delivery-options-accordion.d.ts.map
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { defineComponent } from "../../core/dist/define-component.js";
|
|
3
|
+
import "../../core/dist/index.js";
|
|
4
|
+
import { Icon } from "../../particles/icon/icon.js";
|
|
5
|
+
import { RadioGroup, RadioRoot } from "../../particles/radio/radio.js";
|
|
6
|
+
import { OptionItemContext, ShippingSimulatorContext, ShippingSimulatorOptionName, ShippingSimulatorOptionPrice } from "../shipping-simulator/shipping-simulator.js";
|
|
7
|
+
import { useDeliveryOptionSelection } from "./use-delivery-option-selection.js";
|
|
8
|
+
import { AccordionHeader, AccordionItem, AccordionPanel, AccordionRoot, AccordionTrigger } from "../../particles/accordion/accordion.js";
|
|
9
|
+
import { useState } from "react";
|
|
10
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
//#region src/matter/delivery-options/delivery-options-accordion.tsx
|
|
12
|
+
/**
|
|
13
|
+
* `DeliveryOptionsAccordion` presents the whole-cart delivery-option list as a single summary/trigger
|
|
14
|
+
* row that expands the full list inline, then collapses it once an option is picked and the selection
|
|
15
|
+
* succeeds — with the trigger reflecting the chosen option's name + price (or a placeholder when
|
|
16
|
+
* nothing is selected yet).
|
|
17
|
+
* It is the inline (non-overlay) sibling of the `DeliveryOptionsController` Dialog/Drawer surfaces:
|
|
18
|
+
* same fragment, `$data` shape, selection rule, and reuse of the FSPG-832 option leaves as the per-option
|
|
19
|
+
* template placed as `children`, but the option list expands/collapses in the normal page flow
|
|
20
|
+
* directly below the trigger instead of surfacing in an overlay — no Portal, no Backdrop, no
|
|
21
|
+
* fixed/z-index positioning.
|
|
22
|
+
*
|
|
23
|
+
* The Accordion particle differs from Drawer/Dialog in the control surface this component adapts to:
|
|
24
|
+
* it has no `open`/`onOpenChange` boolean; Base UI models disclosure as a controlled *array* of open
|
|
25
|
+
* item values (`value` + `onValueChange`), so a single-open accordion is `[]` (collapsed) or
|
|
26
|
+
* `[ACCORDION_ITEM_VALUE]` (expanded). There is no overlay chrome (title bar, close button, swipe
|
|
27
|
+
* edge), so those props are dropped; the panel collapse is a height animation rather than a slide.
|
|
28
|
+
*
|
|
29
|
+
* It owns the expand/collapse state and the selection→collapse coordination internally (neither is
|
|
30
|
+
* expressible by composing `Accordion` + `DeliveryOptionsRoot` in a schema), and shares the selection
|
|
31
|
+
* engine with `DeliveryOptionsRoot` via `useDeliveryOptionSelection`. Real options dispatch
|
|
32
|
+
* `$actions.shipping.selectOption` and the panel collapses only once the mutation resolves without a
|
|
33
|
+
* `userError` — a rejected option keeps the panel open with an inline `role="alert"` (US-4);
|
|
34
|
+
* `mockOptions` update local state only and collapse immediately.
|
|
35
|
+
*/
|
|
36
|
+
const fragment = `
|
|
37
|
+
fragment DeliveryOptionsAccordionData on Query {
|
|
38
|
+
shipping {
|
|
39
|
+
id
|
|
40
|
+
options {
|
|
41
|
+
id
|
|
42
|
+
name
|
|
43
|
+
channel
|
|
44
|
+
shippingEstimate {
|
|
45
|
+
value
|
|
46
|
+
unit
|
|
47
|
+
}
|
|
48
|
+
price {
|
|
49
|
+
amount
|
|
50
|
+
currencyCode
|
|
51
|
+
}
|
|
52
|
+
listPrice {
|
|
53
|
+
amount
|
|
54
|
+
currencyCode
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
selectedOptionId
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
`;
|
|
61
|
+
const ACCORDION_ITEM_VALUE = "delivery-options";
|
|
62
|
+
const DEFAULT_PANEL_CLASS = "overflow-hidden transition-[height] duration-200 ease-out h-[var(--accordion-panel-height)] data-starting-style:h-0 data-ending-style:h-0";
|
|
63
|
+
const DeliveryOptionsAccordionDefinition = defineComponent({
|
|
64
|
+
name: "DeliveryOptionsAccordion",
|
|
65
|
+
importPath: "@vtex/faststore/components",
|
|
66
|
+
component: DeliveryOptionsAccordion,
|
|
67
|
+
fragment,
|
|
68
|
+
fetchStrategy: "reactive",
|
|
69
|
+
actions: { shipping: ["selectOption"] },
|
|
70
|
+
editor: {
|
|
71
|
+
label: "Delivery Options Accordion",
|
|
72
|
+
category: "commerce"
|
|
73
|
+
},
|
|
74
|
+
schema: {
|
|
75
|
+
label: {
|
|
76
|
+
type: "string",
|
|
77
|
+
label: "Trigger label prefix"
|
|
78
|
+
},
|
|
79
|
+
placeholder: {
|
|
80
|
+
type: "string",
|
|
81
|
+
default: "Selecionar forma de entrega",
|
|
82
|
+
label: "Placeholder"
|
|
83
|
+
},
|
|
84
|
+
separator: {
|
|
85
|
+
type: "string",
|
|
86
|
+
default: " — ",
|
|
87
|
+
label: "Summary separator"
|
|
88
|
+
},
|
|
89
|
+
icon: {
|
|
90
|
+
type: "icon",
|
|
91
|
+
default: "caret-down",
|
|
92
|
+
label: "Disclosure icon"
|
|
93
|
+
},
|
|
94
|
+
mockOptions: {
|
|
95
|
+
type: "array",
|
|
96
|
+
label: "Mock options (local/dev fallback, ignored once real data has options)"
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
providesContext: ["shipping-simulator", "shipping-simulator-option"],
|
|
100
|
+
guideline: "Collapsed delivery-option picker: a single summary row that expands the whole-cart option list inline (an accordion, not an overlay) and collapses it the moment a row is picked, echoing the choice (name + price) back on the trigger or a placeholder when nothing is selected. Reuses the FSPG-832 option leaves (ShippingSimulatorOption, OptionName, OptionEstimate, OptionPrice, OptionFreeBadge) as the per-option template placed as children, exactly like DeliveryOptionsRoot. Selecting a row dispatches $actions.shipping.selectOption; mockOptions is a local/dev-only fallback whose selection stays local. Use instead of a DeliveryOptionsController overlay (Dialog/Drawer) when the picker should expand in the page flow rather than surface in an overlay."
|
|
101
|
+
});
|
|
102
|
+
function DeliveryOptionsAccordion({ label, placeholder = "Selecionar forma de entrega", separator = " — ", icon = "caret-down", panelClassName = DEFAULT_PANEL_CLASS, $data, $actions, mockOptions, className, children, ...props }) {
|
|
103
|
+
const { options, selectedOptionId, selectionError, selectOption, contextValue } = useDeliveryOptionSelection({
|
|
104
|
+
$data,
|
|
105
|
+
$actions,
|
|
106
|
+
mockOptions
|
|
107
|
+
});
|
|
108
|
+
const [open, setOpen] = useState(false);
|
|
109
|
+
const selectedOption = options.find((option) => option.id === selectedOptionId) ?? null;
|
|
110
|
+
function handleValueChange(optionId) {
|
|
111
|
+
selectOption(optionId, { onSettled: (ok) => {
|
|
112
|
+
if (ok) setOpen(false);
|
|
113
|
+
} });
|
|
114
|
+
}
|
|
115
|
+
return /* @__PURE__ */ jsx(ShippingSimulatorContext, {
|
|
116
|
+
value: contextValue,
|
|
117
|
+
children: /* @__PURE__ */ jsx(AccordionRoot, {
|
|
118
|
+
openMultiple: false,
|
|
119
|
+
value: open ? [ACCORDION_ITEM_VALUE] : [],
|
|
120
|
+
onValueChange: (value) => setOpen(value.length > 0),
|
|
121
|
+
"data-fs-delivery-options-accordion": "",
|
|
122
|
+
children: /* @__PURE__ */ jsxs(AccordionItem, {
|
|
123
|
+
value: ACCORDION_ITEM_VALUE,
|
|
124
|
+
children: [/* @__PURE__ */ jsx(AccordionHeader, {
|
|
125
|
+
className: "m-0",
|
|
126
|
+
children: /* @__PURE__ */ jsxs(AccordionTrigger, {
|
|
127
|
+
...props,
|
|
128
|
+
className,
|
|
129
|
+
"data-fs-delivery-options-accordion-trigger": "",
|
|
130
|
+
children: [
|
|
131
|
+
label ? /* @__PURE__ */ jsx("span", {
|
|
132
|
+
"data-fs-delivery-options-accordion-label": "",
|
|
133
|
+
children: label
|
|
134
|
+
}) : null,
|
|
135
|
+
selectedOption ? /* @__PURE__ */ jsx(OptionItemContext, {
|
|
136
|
+
value: selectedOption,
|
|
137
|
+
children: /* @__PURE__ */ jsxs("span", {
|
|
138
|
+
"data-fs-delivery-options-accordion-value": "",
|
|
139
|
+
children: [
|
|
140
|
+
/* @__PURE__ */ jsx(ShippingSimulatorOptionName, {}),
|
|
141
|
+
/* @__PURE__ */ jsx("span", {
|
|
142
|
+
"data-fs-delivery-options-accordion-separator": "",
|
|
143
|
+
children: separator
|
|
144
|
+
}),
|
|
145
|
+
/* @__PURE__ */ jsx(ShippingSimulatorOptionPrice, {})
|
|
146
|
+
]
|
|
147
|
+
})
|
|
148
|
+
}) : /* @__PURE__ */ jsx("span", {
|
|
149
|
+
"data-fs-delivery-options-accordion-placeholder": "",
|
|
150
|
+
children: placeholder
|
|
151
|
+
}),
|
|
152
|
+
/* @__PURE__ */ jsx("span", {
|
|
153
|
+
"data-fs-delivery-options-accordion-icon": "",
|
|
154
|
+
children: /* @__PURE__ */ jsx(Icon, { name: icon })
|
|
155
|
+
})
|
|
156
|
+
]
|
|
157
|
+
})
|
|
158
|
+
}), /* @__PURE__ */ jsx(AccordionPanel, {
|
|
159
|
+
className: panelClassName,
|
|
160
|
+
"data-fs-delivery-options-accordion-panel": "",
|
|
161
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
162
|
+
"data-fs-delivery-options": "",
|
|
163
|
+
className: "pt-3",
|
|
164
|
+
children: [selectionError ? /* @__PURE__ */ jsx("div", {
|
|
165
|
+
role: "alert",
|
|
166
|
+
"data-fs-delivery-options-error": "",
|
|
167
|
+
children: selectionError
|
|
168
|
+
}) : null, options.length > 0 ? /* @__PURE__ */ jsx(RadioGroup, {
|
|
169
|
+
value: selectedOptionId ?? "",
|
|
170
|
+
onValueChange: handleValueChange,
|
|
171
|
+
className: "flex flex-col gap-3",
|
|
172
|
+
children: options.map((option) => /* @__PURE__ */ jsx(OptionItemContext, {
|
|
173
|
+
value: option,
|
|
174
|
+
children: /* @__PURE__ */ jsx(RadioRoot, {
|
|
175
|
+
value: option.id,
|
|
176
|
+
children
|
|
177
|
+
})
|
|
178
|
+
}, option.id))
|
|
179
|
+
}) : null]
|
|
180
|
+
})
|
|
181
|
+
})]
|
|
182
|
+
})
|
|
183
|
+
})
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
//#endregion
|
|
187
|
+
export { DeliveryOptionsAccordion, DeliveryOptionsAccordionDefinition };
|
|
188
|
+
|
|
189
|
+
//# sourceMappingURL=delivery-options-accordion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delivery-options-accordion.js","names":[],"sources":["../../../src/matter/delivery-options/delivery-options-accordion.tsx"],"sourcesContent":["'use client';\n\nimport { defineComponent } from '@vtex/fs-core';\nimport type { ComponentPropsWithRef } from 'react';\nimport { useState } from 'react';\nimport {\n AccordionHeader,\n AccordionItem,\n AccordionPanel,\n AccordionRoot,\n AccordionTrigger,\n} from '../../particles/accordion/accordion.js';\nimport { Icon } from '../../particles/icon/icon.js';\nimport { RadioGroup, RadioRoot } from '../../particles/radio/radio.js';\nimport type { ComponentActions } from '../../sdk/actions/types.js';\nimport {\n OptionItemContext,\n type ShippingOption,\n ShippingSimulatorContext,\n ShippingSimulatorOptionName,\n ShippingSimulatorOptionPrice,\n} from '../shipping-simulator/shipping-simulator.js';\nimport { type RawDeliveryOptionsData, useDeliveryOptionSelection } from './use-delivery-option-selection.js';\n\n/**\n * `DeliveryOptionsAccordion` presents the whole-cart delivery-option list as a single summary/trigger\n * row that expands the full list inline, then collapses it once an option is picked and the selection\n * succeeds — with the trigger reflecting the chosen option's name + price (or a placeholder when\n * nothing is selected yet).\n * It is the inline (non-overlay) sibling of the `DeliveryOptionsController` Dialog/Drawer surfaces:\n * same fragment, `$data` shape, selection rule, and reuse of the FSPG-832 option leaves as the per-option\n * template placed as `children`, but the option list expands/collapses in the normal page flow\n * directly below the trigger instead of surfacing in an overlay — no Portal, no Backdrop, no\n * fixed/z-index positioning.\n *\n * The Accordion particle differs from Drawer/Dialog in the control surface this component adapts to:\n * it has no `open`/`onOpenChange` boolean; Base UI models disclosure as a controlled *array* of open\n * item values (`value` + `onValueChange`), so a single-open accordion is `[]` (collapsed) or\n * `[ACCORDION_ITEM_VALUE]` (expanded). There is no overlay chrome (title bar, close button, swipe\n * edge), so those props are dropped; the panel collapse is a height animation rather than a slide.\n *\n * It owns the expand/collapse state and the selection→collapse coordination internally (neither is\n * expressible by composing `Accordion` + `DeliveryOptionsRoot` in a schema), and shares the selection\n * engine with `DeliveryOptionsRoot` via `useDeliveryOptionSelection`. Real options dispatch\n * `$actions.shipping.selectOption` and the panel collapses only once the mutation resolves without a\n * `userError` — a rejected option keeps the panel open with an inline `role=\"alert\"` (US-4);\n * `mockOptions` update local state only and collapse immediately.\n */\n\nconst fragment = /* GraphQL */ `\n fragment DeliveryOptionsAccordionData on Query {\n shipping {\n id\n options {\n id\n name\n channel\n shippingEstimate {\n value\n unit\n }\n price {\n amount\n currencyCode\n }\n listPrice {\n amount\n currencyCode\n }\n }\n selectedOptionId\n }\n }\n`;\n\n// Stable value identifying the single accordion item; the controlled open state is `[]` (collapsed)\n// or `[ACCORDION_ITEM_VALUE]` (expanded).\nconst ACCORDION_ITEM_VALUE = 'delivery-options';\n\n// Base UI drives the collapse with the `--accordion-panel-height` CSS var it sets on the panel, so\n// the list expands/collapses in flow with a height transition (overflow-hidden clips it mid-animation).\nconst DEFAULT_PANEL_CLASS =\n 'overflow-hidden transition-[height] duration-200 ease-out h-[var(--accordion-panel-height)] data-starting-style:h-0 data-ending-style:h-0';\n\nexport type DeliveryOptionsAccordionProps = ComponentPropsWithRef<'button'> & {\n /** Optional prefix shown before the summary value on the trigger row (e.g. \"Forma de entrega\"). */\n label?: string;\n /** Text shown on the trigger row while nothing is selected. */\n placeholder?: string;\n /** Separator between the selected option name and price on the trigger row. */\n separator?: string;\n /** Disclosure icon shown on the trigger. The compiler's per-route sprite is built from explicit\n * `icon`-typed prop values in the schema, so a page must set this rather than rely on the default. */\n icon?: string;\n /** Overrides the default collapsible panel styling (height-animation + overflow clip). */\n panelClassName?: string;\n /** Shipping slice forwarded by the reactive runtime; `null` until shipping resolves. */\n $data?: RawDeliveryOptionsData | null;\n /** Compiler-injected action surface; carries `shipping.selectOption`. */\n $actions?: ComponentActions;\n /** Local/dev fallback rows, used only when the reactive fetch resolves no options. */\n mockOptions?: ShippingOption[];\n};\n\nexport const DeliveryOptionsAccordionDefinition = defineComponent<DeliveryOptionsAccordionProps>({\n name: 'DeliveryOptionsAccordion',\n importPath: '@vtex/faststore/components',\n component: DeliveryOptionsAccordion,\n fragment,\n fetchStrategy: 'reactive',\n actions: { shipping: ['selectOption'] },\n editor: { label: 'Delivery Options Accordion', category: 'commerce' },\n schema: {\n label: { type: 'string', label: 'Trigger label prefix' },\n placeholder: { type: 'string', default: 'Selecionar forma de entrega', label: 'Placeholder' },\n separator: { type: 'string', default: ' — ', label: 'Summary separator' },\n icon: { type: 'icon', default: 'caret-down', label: 'Disclosure icon' },\n mockOptions: { type: 'array', label: 'Mock options (local/dev fallback, ignored once real data has options)' },\n },\n // Re-provides the reused option leaves' runtime contexts (Decision 2): `shipping-simulator-option`\n // for the leaves composed as direct children here, plus the outer `shipping-simulator` this\n // accordion also provides at runtime.\n providesContext: ['shipping-simulator', 'shipping-simulator-option'],\n guideline:\n 'Collapsed delivery-option picker: a single summary row that expands the whole-cart option list inline (an accordion, not an overlay) and collapses it the moment a row is picked, echoing the choice (name + price) back on the trigger or a placeholder when nothing is selected. Reuses the FSPG-832 option leaves (ShippingSimulatorOption, OptionName, OptionEstimate, OptionPrice, OptionFreeBadge) as the per-option template placed as children, exactly like DeliveryOptionsRoot. Selecting a row dispatches $actions.shipping.selectOption; mockOptions is a local/dev-only fallback whose selection stays local. Use instead of a DeliveryOptionsController overlay (Dialog/Drawer) when the picker should expand in the page flow rather than surface in an overlay.',\n});\n\nexport function DeliveryOptionsAccordion({\n label,\n placeholder = 'Selecionar forma de entrega',\n separator = ' — ',\n icon = 'caret-down',\n panelClassName = DEFAULT_PANEL_CLASS,\n $data,\n $actions,\n mockOptions,\n className,\n children,\n ...props\n}: DeliveryOptionsAccordionProps) {\n const { options, selectedOptionId, selectionError, selectOption, contextValue } = useDeliveryOptionSelection({\n $data,\n $actions,\n mockOptions,\n });\n const [open, setOpen] = useState(false);\n const selectedOption = options.find((option) => option.id === selectedOptionId) ?? null;\n\n function handleValueChange(optionId: string) {\n selectOption(optionId, {\n onSettled: (ok) => {\n if (ok) setOpen(false);\n },\n });\n }\n\n return (\n <ShippingSimulatorContext value={contextValue}>\n <AccordionRoot\n openMultiple={false}\n value={open ? [ACCORDION_ITEM_VALUE] : []}\n onValueChange={(value) => setOpen(value.length > 0)}\n data-fs-delivery-options-accordion=\"\"\n >\n <AccordionItem value={ACCORDION_ITEM_VALUE}>\n <AccordionHeader className=\"m-0\">\n <AccordionTrigger {...props} className={className} data-fs-delivery-options-accordion-trigger=\"\">\n {label ? <span data-fs-delivery-options-accordion-label=\"\">{label}</span> : null}\n {selectedOption ? (\n <OptionItemContext value={selectedOption}>\n <span data-fs-delivery-options-accordion-value=\"\">\n <ShippingSimulatorOptionName />\n <span data-fs-delivery-options-accordion-separator=\"\">{separator}</span>\n <ShippingSimulatorOptionPrice />\n </span>\n </OptionItemContext>\n ) : (\n <span data-fs-delivery-options-accordion-placeholder=\"\">{placeholder}</span>\n )}\n <span data-fs-delivery-options-accordion-icon=\"\">\n <Icon name={icon} />\n </span>\n </AccordionTrigger>\n </AccordionHeader>\n <AccordionPanel className={panelClassName} data-fs-delivery-options-accordion-panel=\"\">\n <div data-fs-delivery-options=\"\" className=\"pt-3\">\n {selectionError ? (\n <div role=\"alert\" data-fs-delivery-options-error=\"\">\n {selectionError}\n </div>\n ) : null}\n {options.length > 0 ? (\n <RadioGroup\n value={selectedOptionId ?? ''}\n onValueChange={handleValueChange}\n className=\"flex flex-col gap-3\"\n >\n {options.map((option) => (\n <OptionItemContext key={option.id} value={option}>\n <RadioRoot value={option.id}>{children}</RadioRoot>\n </OptionItemContext>\n ))}\n </RadioGroup>\n ) : null}\n </div>\n </AccordionPanel>\n </AccordionItem>\n </AccordionRoot>\n </ShippingSimulatorContext>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { ComponentDefinition } from "../../core/dist/define-component.js";
|
|
2
|
+
import "../../core/dist/index.js";
|
|
3
|
+
import { ShippingOption } from "../shipping-simulator/shipping-simulator.js";
|
|
4
|
+
import { ComponentActions } from "../../sdk/actions/types.js";
|
|
5
|
+
import { RawDeliveryOptionsData } from "./use-delivery-option-selection.js";
|
|
6
|
+
import { ComponentPropsWithRef, ReactNode } from "react";
|
|
7
|
+
//#region src/matter/delivery-options/delivery-options-controller.d.ts
|
|
8
|
+
export type DeliveryOptionsContextValue = Readonly<{
|
|
9
|
+
/** Resolved option rows (real when the fetch has any, else the `mockOptions` fallback). */
|
|
10
|
+
options: ShippingOption[];
|
|
11
|
+
/** Group value: the persisted `selectedOptionId` for real data, local state under mock. */
|
|
12
|
+
selectedOptionId: string | null;
|
|
13
|
+
/** First `userError` message from the latest real selection, or `null`. */
|
|
14
|
+
selectionError: string | null;
|
|
15
|
+
/** Selects an option and closes the surface once the selection resolves without a `userError`. */
|
|
16
|
+
selectOption: (optionId: string) => void;
|
|
17
|
+
}>;
|
|
18
|
+
/**
|
|
19
|
+
* Read the delivery-option selection state from the nearest `DeliveryOptionsController`. Throws when
|
|
20
|
+
* called outside a controller subtree.
|
|
21
|
+
*/
|
|
22
|
+
export declare function useDeliveryOptions(): DeliveryOptionsContextValue;
|
|
23
|
+
export type DeliveryOptionsControllerProps = {
|
|
24
|
+
/** Shipping slice forwarded by the reactive runtime; `null` until shipping resolves. */
|
|
25
|
+
$data?: RawDeliveryOptionsData | null;
|
|
26
|
+
/** Compiler-injected action surface; carries `shipping.selectOption`. */
|
|
27
|
+
$actions?: ComponentActions;
|
|
28
|
+
/** Local/dev fallback rows, used only when the reactive fetch resolves no options. */
|
|
29
|
+
mockOptions?: ShippingOption[];
|
|
30
|
+
/** The single overlay `Root` to control — a `DialogRoot` (modal) or `DrawerRoot` (slide-in). */
|
|
31
|
+
children?: ReactNode;
|
|
32
|
+
};
|
|
33
|
+
export type DeliveryOptionsSummaryProps = ComponentPropsWithRef<'span'> & {
|
|
34
|
+
/** Optional prefix shown before the summary value (e.g. "Forma de entrega"). */
|
|
35
|
+
label?: string;
|
|
36
|
+
/** Text shown while nothing is selected. */
|
|
37
|
+
placeholder?: string;
|
|
38
|
+
/** Separator between the selected option name and price. */
|
|
39
|
+
separator?: string;
|
|
40
|
+
};
|
|
41
|
+
export type DeliveryOptionsListProps = ComponentPropsWithRef<'div'>;
|
|
42
|
+
export declare const DeliveryOptionsControllerDefinition: ComponentDefinition<DeliveryOptionsControllerProps>;
|
|
43
|
+
export declare const DeliveryOptionsSummaryDefinition: ComponentDefinition<DeliveryOptionsSummaryProps>;
|
|
44
|
+
export declare const DeliveryOptionsListDefinition: ComponentDefinition<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>>;
|
|
45
|
+
export declare function DeliveryOptionsController({ $data, $actions, mockOptions, children }: DeliveryOptionsControllerProps): string | number | bigint | boolean | import("react/jsx-runtime").JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | null | undefined;
|
|
46
|
+
export declare function DeliveryOptionsSummary({ label, placeholder, separator, className, ...props }: DeliveryOptionsSummaryProps): import("react/jsx-runtime").JSX.Element;
|
|
47
|
+
export declare function DeliveryOptionsList({ className, children, ...props }: DeliveryOptionsListProps): import("react/jsx-runtime").JSX.Element;
|
|
48
|
+
//#endregion
|
|
49
|
+
//# sourceMappingURL=delivery-options-controller.d.ts.map
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { defineComponent } from "../../core/dist/define-component.js";
|
|
3
|
+
import "../../core/dist/index.js";
|
|
4
|
+
import { OptionItemContext, ShippingSimulatorContext, ShippingSimulatorOptionName, ShippingSimulatorOptionPrice } from "../shipping-simulator/shipping-simulator.js";
|
|
5
|
+
import { useDeliveryOptionSelection } from "./use-delivery-option-selection.js";
|
|
6
|
+
import { DeliveryOptionsListBody } from "./delivery-options.js";
|
|
7
|
+
import { cloneElement, createContext, isValidElement, useContext, useMemo, useState } from "react";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
//#region src/matter/delivery-options/delivery-options-controller.tsx
|
|
10
|
+
/**
|
|
11
|
+
* The collapsed delivery-option surfaces (centered modal / slide-in panel) as a controller +
|
|
12
|
+
* composed particles, replacing the former monolithic `DeliveryOptionsDialog` / `DeliveryOptionsDrawer`
|
|
13
|
+
* (Decision 8). The page composes a raw `DialogRoot` or `DrawerRoot` and each of its particles
|
|
14
|
+
* (`DialogTrigger` / `DialogBackdrop` / `DialogPopup` …) directly as `page.json` nodes, so every part
|
|
15
|
+
* is a swatch-addressable node with zero Tailwind baked into the package — the portaled backdrop/popup
|
|
16
|
+
* a descendant selector could not reach in the monolith are now first-class nodes (Decision 9).
|
|
17
|
+
*
|
|
18
|
+
* `DeliveryOptionsController` owns state only and renders no markup: it runs the shared
|
|
19
|
+
* `useDeliveryOptionSelection` engine, holds the open state, and provides both the FSPG-832
|
|
20
|
+
* `ShippingSimulatorContext` and a `DeliveryOptions` selection context to its subtree, then injects
|
|
21
|
+
* `open` / `onOpenChange` into its single overlay-`Root` child via `cloneElement` — the same mechanism
|
|
22
|
+
* as `CartOpenOnAdd` and `ShippingAddressSavedAddressDrawerController`. A single engine behind the
|
|
23
|
+
* context keeps the trigger echo (`DeliveryOptionsSummary`) and the option list (`DeliveryOptionsList`)
|
|
24
|
+
* on one selection state, so even a local `mockOptions` pick reflects on the trigger.
|
|
25
|
+
*
|
|
26
|
+
* Selection follows the shared rule (INV-10/11): a real pick dispatches `shipping.selectOption` and
|
|
27
|
+
* the surface closes only once it resolves without a `userError`; a rejected pick keeps it open with
|
|
28
|
+
* the inline `role="alert"`; a `mockOptions` pick updates local state and closes immediately.
|
|
29
|
+
*/
|
|
30
|
+
const fragment = `
|
|
31
|
+
fragment DeliveryOptionsControllerData on Query {
|
|
32
|
+
shipping {
|
|
33
|
+
id
|
|
34
|
+
options {
|
|
35
|
+
id
|
|
36
|
+
name
|
|
37
|
+
channel
|
|
38
|
+
shippingEstimate {
|
|
39
|
+
value
|
|
40
|
+
unit
|
|
41
|
+
}
|
|
42
|
+
price {
|
|
43
|
+
amount
|
|
44
|
+
currencyCode
|
|
45
|
+
}
|
|
46
|
+
listPrice {
|
|
47
|
+
amount
|
|
48
|
+
currencyCode
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
selectedOptionId
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
`;
|
|
55
|
+
const DELIVERY_OPTIONS_UNSET = Symbol("DeliveryOptionsContextUnset");
|
|
56
|
+
const DeliveryOptionsContextInternal = createContext(DELIVERY_OPTIONS_UNSET);
|
|
57
|
+
/**
|
|
58
|
+
* Read the delivery-option selection state from the nearest `DeliveryOptionsController`. Throws when
|
|
59
|
+
* called outside a controller subtree.
|
|
60
|
+
*/
|
|
61
|
+
function useDeliveryOptions() {
|
|
62
|
+
const ctx = useContext(DeliveryOptionsContextInternal);
|
|
63
|
+
if (ctx === DELIVERY_OPTIONS_UNSET) throw new Error("useDeliveryOptions() must be used inside a <DeliveryOptionsController> subtree.");
|
|
64
|
+
return ctx;
|
|
65
|
+
}
|
|
66
|
+
const DeliveryOptionsControllerDefinition = defineComponent({
|
|
67
|
+
name: "DeliveryOptionsController",
|
|
68
|
+
importPath: "@vtex/faststore/components",
|
|
69
|
+
component: DeliveryOptionsController,
|
|
70
|
+
fragment,
|
|
71
|
+
fetchStrategy: "reactive",
|
|
72
|
+
actions: { shipping: ["selectOption"] },
|
|
73
|
+
providesContext: [
|
|
74
|
+
"delivery-options",
|
|
75
|
+
"shipping-simulator",
|
|
76
|
+
"shipping-simulator-option"
|
|
77
|
+
],
|
|
78
|
+
editor: {
|
|
79
|
+
label: "Delivery Options Controller",
|
|
80
|
+
category: "commerce"
|
|
81
|
+
},
|
|
82
|
+
schema: { mockOptions: {
|
|
83
|
+
type: "array",
|
|
84
|
+
label: "Mock options (local/dev fallback, ignored once real data has options)"
|
|
85
|
+
} },
|
|
86
|
+
guideline: "State-only controller for a collapsed delivery-option picker: wrap a single DialogRoot (centered modal) or DrawerRoot (slide-in) child and it becomes controlled — the surface opens from its trigger and closes once a real selection succeeds; a userError keeps it open. Renders no markup and bakes no styling: compose the overlay particles (DialogTrigger/DialogPortal/DialogBackdrop/DialogPopup or the Drawer equivalents) directly as page nodes, place a DeliveryOptionsSummary inside the trigger (echoes the selected name + price, or a placeholder) and a DeliveryOptionsList inside the popup (the option radio group; put the reused ShippingSimulatorOption leaves as its children). Selection dispatches $actions.shipping.selectOption; mockOptions is a local/dev-only fallback. Mirrors the CartOpenOnAdd / ShippingAddressSavedAddressDrawerController pattern."
|
|
87
|
+
});
|
|
88
|
+
const DeliveryOptionsSummaryDefinition = defineComponent({
|
|
89
|
+
name: "DeliveryOptionsSummary",
|
|
90
|
+
importPath: "@vtex/faststore/components",
|
|
91
|
+
component: DeliveryOptionsSummary,
|
|
92
|
+
requiresContext: "delivery-options",
|
|
93
|
+
editor: {
|
|
94
|
+
label: "Delivery Options Summary",
|
|
95
|
+
category: "commerce"
|
|
96
|
+
},
|
|
97
|
+
schema: {
|
|
98
|
+
label: {
|
|
99
|
+
type: "string",
|
|
100
|
+
label: "Trigger label prefix"
|
|
101
|
+
},
|
|
102
|
+
placeholder: {
|
|
103
|
+
type: "string",
|
|
104
|
+
default: "Selecionar forma de entrega",
|
|
105
|
+
label: "Placeholder"
|
|
106
|
+
},
|
|
107
|
+
separator: {
|
|
108
|
+
type: "string",
|
|
109
|
+
default: " — ",
|
|
110
|
+
label: "Summary separator"
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
guideline: "The collapsed picker trigger echo: renders the selected option name + price (reusing the FSPG-832 option leaves), or a placeholder while nothing is selected. Place it inside the DialogTrigger / DrawerTrigger of a DeliveryOptionsController subtree. Reads the shared selection context, so it reflects the current pick — real or mockOptions. Must be inside DeliveryOptionsController."
|
|
114
|
+
});
|
|
115
|
+
const DeliveryOptionsListDefinition = defineComponent({
|
|
116
|
+
name: "DeliveryOptionsList",
|
|
117
|
+
importPath: "@vtex/faststore/components",
|
|
118
|
+
component: DeliveryOptionsList,
|
|
119
|
+
requiresContext: "delivery-options",
|
|
120
|
+
editor: {
|
|
121
|
+
label: "Delivery Options List",
|
|
122
|
+
category: "commerce"
|
|
123
|
+
},
|
|
124
|
+
schema: {},
|
|
125
|
+
guideline: "The collapsed picker body: the whole-cart option list as a radio group bound to the selected option, plus the inline selection error (role=\"alert\"). Place it inside the DialogPopup / DrawerPopup of a DeliveryOptionsController subtree, with the reused option leaves (ShippingSimulatorOption, OptionName, OptionEstimate, OptionPrice, OptionFreeBadge) as its children template. Picking a row dispatches the selection and closes the surface on success. Must be inside DeliveryOptionsController."
|
|
126
|
+
});
|
|
127
|
+
function DeliveryOptionsController({ $data, $actions, mockOptions, children }) {
|
|
128
|
+
const { options, selectedOptionId, selectionError, selectOption, contextValue } = useDeliveryOptionSelection({
|
|
129
|
+
$data,
|
|
130
|
+
$actions,
|
|
131
|
+
mockOptions
|
|
132
|
+
});
|
|
133
|
+
const [open, setOpen] = useState(false);
|
|
134
|
+
const delivery = useMemo(() => ({
|
|
135
|
+
options,
|
|
136
|
+
selectedOptionId,
|
|
137
|
+
selectionError,
|
|
138
|
+
selectOption: (optionId) => selectOption(optionId, { onSettled: (ok) => {
|
|
139
|
+
if (ok) setOpen(false);
|
|
140
|
+
} })
|
|
141
|
+
}), [
|
|
142
|
+
options,
|
|
143
|
+
selectedOptionId,
|
|
144
|
+
selectionError,
|
|
145
|
+
selectOption
|
|
146
|
+
]);
|
|
147
|
+
if (!isValidElement(children)) return children;
|
|
148
|
+
return /* @__PURE__ */ jsx(ShippingSimulatorContext, {
|
|
149
|
+
value: contextValue,
|
|
150
|
+
children: /* @__PURE__ */ jsx(DeliveryOptionsContextInternal, {
|
|
151
|
+
value: delivery,
|
|
152
|
+
children: cloneElement(children, {
|
|
153
|
+
open,
|
|
154
|
+
onOpenChange: (next) => setOpen(next)
|
|
155
|
+
})
|
|
156
|
+
})
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
function DeliveryOptionsSummary({ label, placeholder = "Selecionar forma de entrega", separator = " — ", className, ...props }) {
|
|
160
|
+
const { options, selectedOptionId } = useDeliveryOptions();
|
|
161
|
+
const selectedOption = options.find((option) => option.id === selectedOptionId) ?? null;
|
|
162
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
163
|
+
...props,
|
|
164
|
+
className,
|
|
165
|
+
"data-fs-delivery-options-summary": "",
|
|
166
|
+
children: [label ? /* @__PURE__ */ jsx("span", {
|
|
167
|
+
"data-fs-delivery-options-summary-label": "",
|
|
168
|
+
children: label
|
|
169
|
+
}) : null, selectedOption ? /* @__PURE__ */ jsx(OptionItemContext, {
|
|
170
|
+
value: selectedOption,
|
|
171
|
+
children: /* @__PURE__ */ jsxs("span", {
|
|
172
|
+
"data-fs-delivery-options-summary-value": "",
|
|
173
|
+
children: [
|
|
174
|
+
/* @__PURE__ */ jsx(ShippingSimulatorOptionName, {}),
|
|
175
|
+
/* @__PURE__ */ jsx("span", {
|
|
176
|
+
"data-fs-delivery-options-summary-separator": "",
|
|
177
|
+
children: separator
|
|
178
|
+
}),
|
|
179
|
+
/* @__PURE__ */ jsx(ShippingSimulatorOptionPrice, {})
|
|
180
|
+
]
|
|
181
|
+
})
|
|
182
|
+
}) : /* @__PURE__ */ jsx("span", {
|
|
183
|
+
"data-fs-delivery-options-summary-placeholder": "",
|
|
184
|
+
children: placeholder
|
|
185
|
+
})]
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
function DeliveryOptionsList({ className, children, ...props }) {
|
|
189
|
+
const { options, selectedOptionId, selectionError, selectOption } = useDeliveryOptions();
|
|
190
|
+
return /* @__PURE__ */ jsx(DeliveryOptionsListBody, {
|
|
191
|
+
...props,
|
|
192
|
+
className,
|
|
193
|
+
options,
|
|
194
|
+
selectedOptionId,
|
|
195
|
+
selectionError,
|
|
196
|
+
onSelectOption: selectOption,
|
|
197
|
+
children
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
//#endregion
|
|
201
|
+
export { DeliveryOptionsController, DeliveryOptionsControllerDefinition, DeliveryOptionsList, DeliveryOptionsListDefinition, DeliveryOptionsSummary, DeliveryOptionsSummaryDefinition, useDeliveryOptions };
|
|
202
|
+
|
|
203
|
+
//# sourceMappingURL=delivery-options-controller.js.map
|