@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,840 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { defineComponent } from "../../core/dist/define-component.js";
|
|
3
|
+
import "../../core/dist/index.js";
|
|
4
|
+
import { graphql } from "../../sdk/generated/gql.js";
|
|
5
|
+
import { useDataOverride } from "../../sdk/data/data-override-context.js";
|
|
6
|
+
import { publishedVariantIdFor, selectedVariantVar } from "../../sdk/state/variant-selector.js";
|
|
7
|
+
import { RadioGroup } from "../../particles/radio/radio.js";
|
|
8
|
+
import { useReactiveVar } from "@apollo/client/react";
|
|
9
|
+
import { createContext, useCallback, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
10
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
import { Radio } from "@base-ui/react/radio";
|
|
12
|
+
//#region src/matter/variant-selector/variant-selector.tsx
|
|
13
|
+
const useIsomorphicLayoutEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
|
|
14
|
+
const fragment = graphql(`
|
|
15
|
+
fragment VariantSelectorData on Query {
|
|
16
|
+
productBySlug(slug: $slug) {
|
|
17
|
+
__typename
|
|
18
|
+
id
|
|
19
|
+
options {
|
|
20
|
+
name
|
|
21
|
+
values
|
|
22
|
+
}
|
|
23
|
+
variants(first: 50) {
|
|
24
|
+
edges {
|
|
25
|
+
node {
|
|
26
|
+
__typename
|
|
27
|
+
id
|
|
28
|
+
name
|
|
29
|
+
sku
|
|
30
|
+
availableForSale
|
|
31
|
+
selectedOptions {
|
|
32
|
+
name
|
|
33
|
+
value
|
|
34
|
+
}
|
|
35
|
+
images(first: 1) {
|
|
36
|
+
edges {
|
|
37
|
+
node {
|
|
38
|
+
url
|
|
39
|
+
altText
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
`);
|
|
49
|
+
const VARIANT_SELECTOR_CONTEXT_UNSET = Symbol("VariantSelectorContextUnset");
|
|
50
|
+
const VariantSelectorContextInternal = createContext(VARIANT_SELECTOR_CONTEXT_UNSET);
|
|
51
|
+
/** Exposed for advanced composition and tests that mount group/option in isolation. */
|
|
52
|
+
const VariantSelectorContext = VariantSelectorContextInternal;
|
|
53
|
+
const VariantSelectorGroupContext = createContext(null);
|
|
54
|
+
/** Carries the swatch-content component the active swatch list chose, read by `VariantSelectorOption`.
|
|
55
|
+
* Null when an option renders outside a swatch list, in which case the option degrades to a text label. */
|
|
56
|
+
const VariantSelectorSwatchContext = createContext(null);
|
|
57
|
+
function useVariantSelector() {
|
|
58
|
+
const ctx = useContext(VariantSelectorContextInternal);
|
|
59
|
+
if (ctx === VARIANT_SELECTOR_CONTEXT_UNSET) throw new Error("VariantSelector components must be used inside VariantSelectorRoot.");
|
|
60
|
+
return ctx;
|
|
61
|
+
}
|
|
62
|
+
function useVariantSelectorGroup() {
|
|
63
|
+
const ctx = useContext(VariantSelectorGroupContext);
|
|
64
|
+
if (ctx === null) throw new Error("VariantSelector group parts (Title, swatch lists, Overflow, Option) must be used inside VariantSelectorOptionGroup.");
|
|
65
|
+
return ctx;
|
|
66
|
+
}
|
|
67
|
+
function deriveVariants(data) {
|
|
68
|
+
return data.variants.edges.map(({ node }) => {
|
|
69
|
+
const options = {};
|
|
70
|
+
for (const selected of node.selectedOptions) options[selected.name] = selected.value;
|
|
71
|
+
const primaryImage = node.images.edges[0]?.node ?? null;
|
|
72
|
+
return {
|
|
73
|
+
id: node.id,
|
|
74
|
+
name: node.name,
|
|
75
|
+
sku: node.sku,
|
|
76
|
+
availableForSale: node.availableForSale,
|
|
77
|
+
options,
|
|
78
|
+
image: primaryImage ? {
|
|
79
|
+
url: primaryImage.url,
|
|
80
|
+
alt: primaryImage.altText
|
|
81
|
+
} : null
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Resolve the variant activated by setting `axisName` to `value` while keeping the current
|
|
87
|
+
* selection on the other axes. Mirrors the legacy `getSkuSlug` dominant-axis fallback: an exact
|
|
88
|
+
* match across every current selection wins; otherwise the first variant carrying `value` on the
|
|
89
|
+
* activated axis is used. String equality keeps `Size-7` distinct from `Size-7.5`.
|
|
90
|
+
*/
|
|
91
|
+
function resolveVariant(variants, currentSelection, axisName, value) {
|
|
92
|
+
const target = {
|
|
93
|
+
...currentSelection,
|
|
94
|
+
[axisName]: value
|
|
95
|
+
};
|
|
96
|
+
const exact = variants.find((variant) => Object.entries(target).every(([name, selected]) => variant.options[name] === selected));
|
|
97
|
+
if (exact) return exact;
|
|
98
|
+
return variants.find((variant) => variant.options[axisName] === value) ?? null;
|
|
99
|
+
}
|
|
100
|
+
function deriveAxes(data, variants, currentSelection) {
|
|
101
|
+
return data.options.map((option) => ({
|
|
102
|
+
name: option.name,
|
|
103
|
+
activeValue: currentSelection[option.name] ?? null,
|
|
104
|
+
options: option.values.map((value) => {
|
|
105
|
+
const resolved = resolveVariant(variants, currentSelection, option.name, value);
|
|
106
|
+
const swatch = resolved?.image ? {
|
|
107
|
+
imageUrl: resolved.image.url,
|
|
108
|
+
alt: resolved.image.alt ?? void 0
|
|
109
|
+
} : void 0;
|
|
110
|
+
return {
|
|
111
|
+
value,
|
|
112
|
+
available: resolved?.availableForSale ?? false,
|
|
113
|
+
variantId: resolved?.id ?? null,
|
|
114
|
+
swatch
|
|
115
|
+
};
|
|
116
|
+
})
|
|
117
|
+
}));
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Swatch inference for the auto swatch list `VariantSelectorSwatches` (legacy `useDefineVariant`): `color`
|
|
121
|
+
* when every option carries a `hexColor`; `image` when a single option has an image, or when image sources
|
|
122
|
+
* differ across options; `label` otherwise. Never returns `radio` — that look is explicit only.
|
|
123
|
+
*/
|
|
124
|
+
function inferDisplayMode(options) {
|
|
125
|
+
if (options.length > 0 && options.every((option) => Boolean(option.swatch?.hexColor))) return "color";
|
|
126
|
+
const imageUrls = options.map((option) => option.swatch?.imageUrl).filter((url) => Boolean(url));
|
|
127
|
+
if (imageUrls.length === 1) return "image";
|
|
128
|
+
const firstImageUrl = imageUrls[0];
|
|
129
|
+
const sourcesDiffer = imageUrls.some((url) => url !== firstImageUrl);
|
|
130
|
+
if (firstImageUrl !== void 0 && sourcesDiffer) return "image";
|
|
131
|
+
return "label";
|
|
132
|
+
}
|
|
133
|
+
function DefaultVariantImage({ src, alt }) {
|
|
134
|
+
return /* @__PURE__ */ jsx("img", {
|
|
135
|
+
src,
|
|
136
|
+
alt,
|
|
137
|
+
"data-fs-variant-selector-option-image": ""
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
/** Plain text body: the value label, hooked as `data-fs-variant-selector-option-label` so an option's
|
|
141
|
+
* value text is styleable through the same selector everywhere (matching the radio swatch's label). */
|
|
142
|
+
function LabelSwatchContent({ value }) {
|
|
143
|
+
return /* @__PURE__ */ jsx("span", {
|
|
144
|
+
"data-fs-variant-selector-option-label": "",
|
|
145
|
+
"aria-hidden": "true",
|
|
146
|
+
children: value
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
/** Image body: the variant thumbnail, degrading to the value label when no image source is present. */
|
|
150
|
+
function ImageSwatchContent({ swatch, value, Image }) {
|
|
151
|
+
if (swatch?.imageUrl) return /* @__PURE__ */ jsx("span", {
|
|
152
|
+
"aria-hidden": "true",
|
|
153
|
+
children: /* @__PURE__ */ jsx(Image, {
|
|
154
|
+
src: swatch.imageUrl,
|
|
155
|
+
alt: swatch.alt ?? value
|
|
156
|
+
})
|
|
157
|
+
});
|
|
158
|
+
return /* @__PURE__ */ jsx(LabelSwatchContent, {
|
|
159
|
+
swatch,
|
|
160
|
+
value,
|
|
161
|
+
Image
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Color body: a color chip, degrading gracefully when the value lacks a hex source. `hexColor` has no
|
|
166
|
+
* Core Graph origin (see `VariantSelectorSwatch`), so a `color` group authored from a design may resolve
|
|
167
|
+
* to values with no color: paint the chip when a hex is present, else fall back to the variant image,
|
|
168
|
+
* else the value label — never an empty chip.
|
|
169
|
+
*/
|
|
170
|
+
function ColorSwatchContent({ swatch, value, Image }) {
|
|
171
|
+
if (swatch?.hexColor) return /* @__PURE__ */ jsx("span", {
|
|
172
|
+
"aria-hidden": "true",
|
|
173
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
174
|
+
"data-fs-variant-selector-option-color": "",
|
|
175
|
+
title: value,
|
|
176
|
+
style: { "--fs-variant-selector-option-color-bkg-color": swatch.hexColor }
|
|
177
|
+
})
|
|
178
|
+
});
|
|
179
|
+
return /* @__PURE__ */ jsx(ImageSwatchContent, {
|
|
180
|
+
swatch,
|
|
181
|
+
value,
|
|
182
|
+
Image
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Radio body: a classic radio row — a control circle holding Base UI's indicator (the dot, shown when
|
|
187
|
+
* checked) next to the value label. Both are direct children of the option root (no wrapper span) so the
|
|
188
|
+
* group's `flex` on `data-fs-variant-selector-option` lays the control and label out as a row; each is
|
|
189
|
+
* `aria-hidden` because the sibling sr-only span already owns the accessible name. Style `-control` as
|
|
190
|
+
* the ring and `-indicator` as the dot.
|
|
191
|
+
*/
|
|
192
|
+
function RadioSwatchContent({ value }) {
|
|
193
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
|
|
194
|
+
"data-fs-variant-selector-option-control": "",
|
|
195
|
+
"aria-hidden": "true",
|
|
196
|
+
children: /* @__PURE__ */ jsx(Radio.Indicator, { "data-fs-variant-selector-option-indicator": "" })
|
|
197
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
198
|
+
"data-fs-variant-selector-option-label": "",
|
|
199
|
+
"aria-hidden": "true",
|
|
200
|
+
children: value
|
|
201
|
+
})] });
|
|
202
|
+
}
|
|
203
|
+
const LABEL_SWATCH = {
|
|
204
|
+
mode: "label",
|
|
205
|
+
SwatchContent: LabelSwatchContent
|
|
206
|
+
};
|
|
207
|
+
const IMAGE_SWATCH = {
|
|
208
|
+
mode: "image",
|
|
209
|
+
SwatchContent: ImageSwatchContent
|
|
210
|
+
};
|
|
211
|
+
const COLOR_SWATCH = {
|
|
212
|
+
mode: "color",
|
|
213
|
+
SwatchContent: ColorSwatchContent
|
|
214
|
+
};
|
|
215
|
+
const RADIO_SWATCH = {
|
|
216
|
+
mode: "radio",
|
|
217
|
+
SwatchContent: RadioSwatchContent
|
|
218
|
+
};
|
|
219
|
+
/**
|
|
220
|
+
* The swatch kinds the auto swatch list `VariantSelectorSwatches` can land on. `auto` is a runtime
|
|
221
|
+
* decision — it cannot be a static component reference — so the inferred mode is mapped back to its kind
|
|
222
|
+
* here. The explicit swatch lists bypass this entirely. `inferDisplayMode` never returns `radio`, but the
|
|
223
|
+
* `Record` stays exhaustive over `ResolvedDisplayMode` so the lookup is total.
|
|
224
|
+
*/
|
|
225
|
+
const SWATCH_BY_INFERRED_MODE = {
|
|
226
|
+
label: LABEL_SWATCH,
|
|
227
|
+
image: IMAGE_SWATCH,
|
|
228
|
+
color: COLOR_SWATCH,
|
|
229
|
+
radio: RADIO_SWATCH
|
|
230
|
+
};
|
|
231
|
+
/**
|
|
232
|
+
* Normalizes an axis name for matching: strips accents and case and collapses whitespace. This is a
|
|
233
|
+
* deterministic normalization, not a linguistic guess — it only bridges trivial casing/accent/spacing
|
|
234
|
+
* differences between an authored `optionName` and the catalog `ProductOption.name` (e.g. "cólor" vs
|
|
235
|
+
* "Color"). Anything beyond that — translations, paraphrases, singular/plural — is resolved at
|
|
236
|
+
* authoring time via `optionIndex`, which the schema author reads from the axis' visual order. The
|
|
237
|
+
* runtime deliberately does no morphology. See variant-selector.md.
|
|
238
|
+
*/
|
|
239
|
+
function normalizeAxisName(name) {
|
|
240
|
+
return name.normalize("NFD").replaceAll(/[\u0300-\u036f]/g, "").toLowerCase().trim().replaceAll(/\s+/g, " ");
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Finds the axis an `optionName` refers to via a normalized (case/accent/whitespace-insensitive)
|
|
244
|
+
* match, and only when it is unambiguous (exactly one axis), so a match can never silently bind to
|
|
245
|
+
* the wrong axis. Non-trivial label differences are handled by `optionIndex`, never guessed here.
|
|
246
|
+
*/
|
|
247
|
+
function findAxisByName(axes, optionName) {
|
|
248
|
+
const exact = axes.find((axis) => axis.name === optionName);
|
|
249
|
+
if (exact) return exact;
|
|
250
|
+
const target = normalizeAxisName(optionName);
|
|
251
|
+
const matches = axes.filter((axis) => normalizeAxisName(axis.name) === target);
|
|
252
|
+
return matches.length === 1 ? matches[0] ?? null : null;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Resolves the axis a group binds to. `optionName` (tolerant) takes precedence; `optionIndex`
|
|
256
|
+
* (zero-based position) is the fallback so a generated schema can bind by visual order when the
|
|
257
|
+
* localized label does not match the catalog name. Returns `null` when neither resolves.
|
|
258
|
+
*/
|
|
259
|
+
function resolveAxis(axes, optionName, optionIndex) {
|
|
260
|
+
if (optionName !== void 0) {
|
|
261
|
+
const byName = findAxisByName(axes, optionName);
|
|
262
|
+
if (byName) return byName;
|
|
263
|
+
}
|
|
264
|
+
if (optionIndex !== void 0 && Number.isInteger(optionIndex) && optionIndex >= 0 && optionIndex < axes.length) return axes[optionIndex] ?? null;
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Resolves the swatch kind a swatch list renders: an explicit kind passes through; `'auto'` infers from
|
|
269
|
+
* the axis' options (and falls back to `label` for an unresolved axis).
|
|
270
|
+
*/
|
|
271
|
+
function resolveSwatchKind(swatch, axis) {
|
|
272
|
+
if (swatch !== "auto") return swatch;
|
|
273
|
+
return axis ? SWATCH_BY_INFERRED_MODE[inferDisplayMode(axis.options)] : LABEL_SWATCH;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Computes the swatches to render under an effective `cap` (the count that fits the measured row, resolved
|
|
277
|
+
* upstream). Collapses to the first `cap` options while always keeping the active swatch visible. `cap` is
|
|
278
|
+
* by construction the most that fit one line, so when the active swatch sits past it we **swap** it for the
|
|
279
|
+
* last head swatch (`cap - 1` head + active = `cap`) instead of appending (`cap + 1`, which would wrap or
|
|
280
|
+
* overflow). Dropping the *last* head swatch keeps the leading options stable across selections and never
|
|
281
|
+
* hides the primary (first) option. A `null` cap (measurement unavailable, no trigger, or expanded) shows
|
|
282
|
+
* every swatch.
|
|
283
|
+
*/
|
|
284
|
+
function getVisibleOptions(axis, cap, expanded) {
|
|
285
|
+
if (cap === null || cap <= 0 || expanded || axis.options.length <= cap) return {
|
|
286
|
+
visibleOptions: axis.options,
|
|
287
|
+
hiddenCount: 0,
|
|
288
|
+
overflowing: false
|
|
289
|
+
};
|
|
290
|
+
const head = axis.options.slice(0, cap);
|
|
291
|
+
const activeOption = axis.activeValue !== null && !head.some((option) => option.value === axis.activeValue) && axis.options.some((option) => option.value === axis.activeValue) ? axis.options.find((option) => option.value === axis.activeValue) : void 0;
|
|
292
|
+
const visibleOptions = activeOption ? [...head.slice(0, cap - 1), activeOption] : head;
|
|
293
|
+
const hiddenCount = axis.options.length - visibleOptions.length;
|
|
294
|
+
return {
|
|
295
|
+
visibleOptions,
|
|
296
|
+
hiddenCount,
|
|
297
|
+
overflowing: hiddenCount > 0
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Pure fit math: given each option's outer width, the row `gap`, the list's available inner width, and an
|
|
302
|
+
* optional `triggerWidth` to reserve for the "+N more" control, return how many options fit on one line.
|
|
303
|
+
* By default the trigger is a sibling of the swatch list (its own space), so `triggerWidth` is 0 and the
|
|
304
|
+
* swatches get the full width; pass the trigger's width when it sits inline at the end of the swatch row so
|
|
305
|
+
* it stays on the line. When every option fits it returns the full count; otherwise the prefix that fits,
|
|
306
|
+
* floored at 1 so an oversized single swatch never yields zero. Isolated from the DOM so the algorithm is
|
|
307
|
+
* unit-testable with plain numbers.
|
|
308
|
+
*/
|
|
309
|
+
function computeVisibleCount(optionWidths, gap, available, triggerWidth = 0) {
|
|
310
|
+
const total = optionWidths.length;
|
|
311
|
+
if (total === 0) return 0;
|
|
312
|
+
let full = 0;
|
|
313
|
+
for (const w of optionWidths) full += w;
|
|
314
|
+
full += gap * (total - 1);
|
|
315
|
+
if (full <= available) return total;
|
|
316
|
+
const budget = triggerWidth > 0 ? available - triggerWidth - gap : available;
|
|
317
|
+
let used = 0;
|
|
318
|
+
let count = 0;
|
|
319
|
+
for (const w of optionWidths) {
|
|
320
|
+
const next = w + (count > 0 ? gap : 0);
|
|
321
|
+
if (used + next > budget) break;
|
|
322
|
+
used += next;
|
|
323
|
+
count++;
|
|
324
|
+
}
|
|
325
|
+
return Math.max(1, count);
|
|
326
|
+
}
|
|
327
|
+
/** Reads the swatch list's content-box inner width (the space the swatches actually lay out in) and the
|
|
328
|
+
* resolved horizontal row gap, from a single `getComputedStyle`. `clientWidth` includes horizontal padding,
|
|
329
|
+
* so a list styled with `px-*` would otherwise overestimate the space and fit one extra swatch. `columnGap`
|
|
330
|
+
* already resolves to a px value when `gap` is set (else `"normal"` → 0). */
|
|
331
|
+
function readRowMetrics(el) {
|
|
332
|
+
const style = getComputedStyle(el);
|
|
333
|
+
const px = (value) => {
|
|
334
|
+
const parsed = Number.parseFloat(value);
|
|
335
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
336
|
+
};
|
|
337
|
+
return {
|
|
338
|
+
available: el.clientWidth - px(style.paddingLeft) - px(style.paddingRight),
|
|
339
|
+
gap: px(style.columnGap)
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Measures how many swatches fit the list's width and returns that count, or `null` when measurement is
|
|
344
|
+
* unavailable (collapse disabled, no trigger composed, no element, zero width, or no `ResizeObserver` — SSR
|
|
345
|
+
* and jsdom) so the caller shows every swatch. Recomputes on `ResizeObserver` resize.
|
|
346
|
+
*
|
|
347
|
+
* The option-width cache is refreshed only while the full set is on screen (count `null` → all shown); once
|
|
348
|
+
* collapsed we can no longer see every swatch, so a later resize recomputes from the cached widths.
|
|
349
|
+
*
|
|
350
|
+
* When `reserveTriggerSpace` is set (the author placed the "+N more" trigger inline at the end of the swatch
|
|
351
|
+
* row), the sibling trigger's width is reserved from the fit. The trigger only mounts after the first
|
|
352
|
+
* collapse, so a second pass (keyed on `count`) folds its width in; the trigger width is accumulated
|
|
353
|
+
* monotonically so a shrinking "+N more" label can never flip-flop the fitting count.
|
|
354
|
+
*/
|
|
355
|
+
function useMeasuredVisibleCount({ listEl, optionCount, hasOverflow, enabled, reserveTriggerSpace }) {
|
|
356
|
+
const [count, setCount] = useState(null);
|
|
357
|
+
const widthsRef = useRef([]);
|
|
358
|
+
const triggerWidthRef = useRef(0);
|
|
359
|
+
const measureRef = useRef(() => {});
|
|
360
|
+
useIsomorphicLayoutEffect(() => {
|
|
361
|
+
if (!enabled || !hasOverflow || !listEl || typeof ResizeObserver === "undefined") {
|
|
362
|
+
widthsRef.current = [];
|
|
363
|
+
triggerWidthRef.current = 0;
|
|
364
|
+
measureRef.current = () => {};
|
|
365
|
+
setCount(null);
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
widthsRef.current = [];
|
|
369
|
+
triggerWidthRef.current = 0;
|
|
370
|
+
const measure = () => {
|
|
371
|
+
const { available, gap } = readRowMetrics(listEl);
|
|
372
|
+
if (available <= 0) {
|
|
373
|
+
setCount(null);
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
const optionEls = Array.from(listEl.querySelectorAll("[data-fs-variant-selector-option]"));
|
|
377
|
+
if (optionCount > 0 && optionEls.length === optionCount) widthsRef.current = optionEls.map((el) => el.offsetWidth);
|
|
378
|
+
if (reserveTriggerSpace) {
|
|
379
|
+
const triggerEl = listEl.parentElement?.querySelector("[data-fs-variant-selector-overflow-trigger]");
|
|
380
|
+
triggerWidthRef.current = Math.max(triggerWidthRef.current, triggerEl?.offsetWidth ?? 0);
|
|
381
|
+
}
|
|
382
|
+
const widths = widthsRef.current;
|
|
383
|
+
if (widths.length === 0) {
|
|
384
|
+
setCount(null);
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
const next = computeVisibleCount(widths, gap, available, triggerWidthRef.current);
|
|
388
|
+
setCount((prev) => prev === next ? prev : next);
|
|
389
|
+
};
|
|
390
|
+
measureRef.current = measure;
|
|
391
|
+
measure();
|
|
392
|
+
const observer = new ResizeObserver(() => measure());
|
|
393
|
+
observer.observe(listEl);
|
|
394
|
+
return () => observer.disconnect();
|
|
395
|
+
}, [
|
|
396
|
+
listEl,
|
|
397
|
+
optionCount,
|
|
398
|
+
hasOverflow,
|
|
399
|
+
enabled,
|
|
400
|
+
reserveTriggerSpace
|
|
401
|
+
]);
|
|
402
|
+
useIsomorphicLayoutEffect(() => {
|
|
403
|
+
measureRef.current();
|
|
404
|
+
}, [count]);
|
|
405
|
+
return count;
|
|
406
|
+
}
|
|
407
|
+
const warnedUnresolvedAxes = /* @__PURE__ */ new Set();
|
|
408
|
+
function warnUnresolvedAxis(optionName, optionIndex, axes) {
|
|
409
|
+
if (process.env.NODE_ENV === "production") return;
|
|
410
|
+
const available = axes.map((axis) => axis.name);
|
|
411
|
+
const key = `${optionName ?? ""}\u0000${optionIndex ?? ""}\u0000${available.join("")}`;
|
|
412
|
+
if (warnedUnresolvedAxes.has(key)) return;
|
|
413
|
+
warnedUnresolvedAxes.add(key);
|
|
414
|
+
const list = available.length > 0 ? available.map((name, index) => `${index}:"${name}"`).join(", ") : "(none)";
|
|
415
|
+
console.warn(`[VariantSelector] Could not resolve an option axis for ${optionName === void 0 ? `optionIndex ${optionIndex}` : `optionName "${optionName}"`}. Available axes (index:name): ${list}. optionName must reference a catalog ProductOption.name (matched ignoring case and accents only); otherwise set optionIndex to the axis position (0-based, in the product option order).`);
|
|
416
|
+
}
|
|
417
|
+
const VariantSelectorRootDefinition = defineComponent({
|
|
418
|
+
name: "VariantSelectorRoot",
|
|
419
|
+
importPath: "@vtex/faststore/components",
|
|
420
|
+
component: VariantSelectorRoot,
|
|
421
|
+
fragment,
|
|
422
|
+
fetchStrategy: "reactive",
|
|
423
|
+
editor: {
|
|
424
|
+
label: "Variant Selector",
|
|
425
|
+
category: "commerce"
|
|
426
|
+
},
|
|
427
|
+
schema: { selectedVariantId: {
|
|
428
|
+
type: "string",
|
|
429
|
+
label: "Selected Variant ID"
|
|
430
|
+
} },
|
|
431
|
+
providesContext: "variant-selector",
|
|
432
|
+
guideline: "Root container for PDP variant swatches — derives option axes and availability from the product variants and publishes the selected variant for sibling components. Wraps one VariantSelectorOptionGroup per axis. The selectedVariantId prop pre-selects the viewed SKU before the shopper interacts; the live selection wins once a swatch is activated."
|
|
433
|
+
});
|
|
434
|
+
const VariantSelectorOptionGroupDefinition = defineComponent({
|
|
435
|
+
name: "VariantSelectorOptionGroup",
|
|
436
|
+
importPath: "@vtex/faststore/components",
|
|
437
|
+
component: VariantSelectorOptionGroup,
|
|
438
|
+
editor: {
|
|
439
|
+
label: "Variant Option Group",
|
|
440
|
+
category: "commerce"
|
|
441
|
+
},
|
|
442
|
+
schema: {
|
|
443
|
+
optionName: {
|
|
444
|
+
type: "string",
|
|
445
|
+
label: "Option axis name (catalog ProductOption.name)"
|
|
446
|
+
},
|
|
447
|
+
optionIndex: {
|
|
448
|
+
type: "number",
|
|
449
|
+
label: "Option axis index (0-based; fallback for optionName)"
|
|
450
|
+
},
|
|
451
|
+
reserveTriggerSpace: {
|
|
452
|
+
type: "boolean",
|
|
453
|
+
default: false,
|
|
454
|
+
label: "Reserve space for the \"+N more\" trigger"
|
|
455
|
+
}
|
|
456
|
+
},
|
|
457
|
+
requiresContext: "variant-selector",
|
|
458
|
+
providesContext: "variant-selector-group",
|
|
459
|
+
guideline: "One option axis (e.g. Color) inside a VariantSelectorRoot. A container only — it binds the axis and owns the collapse/expand state, then renders whatever you compose inside it. Fill it, in any order, with: a VariantSelectorGroupTitle (the axis name) and optionally a VariantSelectorGroupValue beside it to echo the selection, exactly one swatch list (VariantSelectorSwatches to auto-infer the look, or VariantSelectorColorSwatches / VariantSelectorImageSwatches / VariantSelectorLabelSwatches / VariantSelectorRadioSwatches to fix it), and optionally a VariantSelectorOverflow (\"+N more\") to collapse a row that does not fit its width. Because the parts read the group via context, you can place them freely — e.g. the title in an accordion header and the swatch list in its panel. Bind the axis with optionIndex (0-based, in the product's option order — the reliable choice when authoring from an image, since groups are placed in visual order) or, when the exact catalog option name is known, optionName (matched case/accent-insensitively, no plural/translation guessing). Compose a VariantSelectorOverflow to opt into automatic space-based collapse: the group measures the swatch row and keeps only the swatches that fit on one line, revealing the rest via the trigger — no cap prop. The trigger sits in its own space by default; set reserveTriggerSpace when it is styled inline at the end of the swatch row, so its width is reserved and it stays on the line."
|
|
460
|
+
});
|
|
461
|
+
const VariantSelectorGroupTitleDefinition = defineComponent({
|
|
462
|
+
name: "VariantSelectorGroupTitle",
|
|
463
|
+
importPath: "@vtex/faststore/components",
|
|
464
|
+
component: VariantSelectorGroupTitle,
|
|
465
|
+
editor: {
|
|
466
|
+
label: "Variant Group Title",
|
|
467
|
+
category: "commerce"
|
|
468
|
+
},
|
|
469
|
+
schema: { label: {
|
|
470
|
+
type: "string",
|
|
471
|
+
label: "Axis name override (defaults to the catalog axis name)"
|
|
472
|
+
} },
|
|
473
|
+
requiresContext: "variant-selector-group",
|
|
474
|
+
guideline: "The axis name inside a VariantSelectorOptionGroup (e.g. \"Color\"). Reads the axis from context, so it stays correct even when placed apart from the swatches (e.g. in an accordion header). Set label to match a design prompt (\"Selecione a cor\") without changing the axis binding. It renders the name only — to echo the selected value place a VariantSelectorGroupValue beside it (e.g. both inside a Container); the separator (a colon), the value weight, and the spacing are brand styling on the data-fs hooks, not props."
|
|
475
|
+
});
|
|
476
|
+
const VariantSelectorGroupValueDefinition = defineComponent({
|
|
477
|
+
name: "VariantSelectorGroupValue",
|
|
478
|
+
importPath: "@vtex/faststore/components",
|
|
479
|
+
component: VariantSelectorGroupValue,
|
|
480
|
+
editor: {
|
|
481
|
+
label: "Variant Group Value",
|
|
482
|
+
category: "commerce"
|
|
483
|
+
},
|
|
484
|
+
schema: {},
|
|
485
|
+
requiresContext: "variant-selector-group",
|
|
486
|
+
guideline: "The live selected value of a VariantSelectorOptionGroup (e.g. \"Red\"), as its own placeable part. Compose it beside a VariantSelectorGroupTitle — typically both inside a Container — to render \"Color: Red\", where the colon and the value weight are styling on the data-fs hooks. Omit it entirely when the design shows only the axis name (e.g. above a radio list, whose selected dot already conveys the choice). It is decorative (aria-hidden): the selection is announced per option, so the group is named by the axis alone."
|
|
487
|
+
});
|
|
488
|
+
const VariantSelectorSwatchesDefinition = defineComponent({
|
|
489
|
+
name: "VariantSelectorSwatches",
|
|
490
|
+
importPath: "@vtex/faststore/components",
|
|
491
|
+
component: VariantSelectorSwatches,
|
|
492
|
+
editor: {
|
|
493
|
+
label: "Variant Swatches (auto)",
|
|
494
|
+
category: "commerce"
|
|
495
|
+
},
|
|
496
|
+
schema: {},
|
|
497
|
+
requiresContext: "variant-selector-group",
|
|
498
|
+
guideline: "The swatch list inside a VariantSelectorOptionGroup, auto-inferring the look from the option data: color when every value has a hex color, image when values resolve to differing variant images, else label (it never infers radio). Renders one swatch per option automatically — do not author VariantSelectorOption children. To fix the look instead of inferring it, use a sibling list: VariantSelectorColorSwatches / VariantSelectorImageSwatches / VariantSelectorLabelSwatches / VariantSelectorRadioSwatches. Swatch shape (square vs circle) is styling. Use exactly one swatch list per group."
|
|
499
|
+
});
|
|
500
|
+
const VariantSelectorLabelSwatchesDefinition = defineComponent({
|
|
501
|
+
name: "VariantSelectorLabelSwatches",
|
|
502
|
+
importPath: "@vtex/faststore/components",
|
|
503
|
+
component: VariantSelectorLabelSwatches,
|
|
504
|
+
editor: {
|
|
505
|
+
label: "Variant Label Swatches",
|
|
506
|
+
category: "commerce"
|
|
507
|
+
},
|
|
508
|
+
schema: {},
|
|
509
|
+
requiresContext: "variant-selector-group",
|
|
510
|
+
guideline: "Swatch list rendered as text-label swatches (size pills, materials, voltages, any axis that should read as text). Use inside a VariantSelectorOptionGroup when the look must always be text regardless of the data (auto can resolve a size axis to image when its values map to differing variant photos). Renders its options automatically. Use exactly one swatch list per group."
|
|
511
|
+
});
|
|
512
|
+
const VariantSelectorImageSwatchesDefinition = defineComponent({
|
|
513
|
+
name: "VariantSelectorImageSwatches",
|
|
514
|
+
importPath: "@vtex/faststore/components",
|
|
515
|
+
component: VariantSelectorImageSwatches,
|
|
516
|
+
editor: {
|
|
517
|
+
label: "Variant Image Swatches",
|
|
518
|
+
category: "commerce"
|
|
519
|
+
},
|
|
520
|
+
schema: {},
|
|
521
|
+
requiresContext: "variant-selector-group",
|
|
522
|
+
guideline: "Swatch list rendered as image (thumbnail) swatches; each shows the variant's primary image, degrading to the value label when no image is available. Use inside a VariantSelectorOptionGroup; prefer binding that group by optionName so the photo pairs with its intended axis — a positionally-bound group with an image list can hijack a text axis (e.g. sizes shown as clothing photos) when the live product exposes fewer or reordered axes than the design. Renders its options automatically. Use exactly one swatch list per group."
|
|
523
|
+
});
|
|
524
|
+
const VariantSelectorColorSwatchesDefinition = defineComponent({
|
|
525
|
+
name: "VariantSelectorColorSwatches",
|
|
526
|
+
importPath: "@vtex/faststore/components",
|
|
527
|
+
component: VariantSelectorColorSwatches,
|
|
528
|
+
editor: {
|
|
529
|
+
label: "Variant Color Swatches",
|
|
530
|
+
category: "commerce"
|
|
531
|
+
},
|
|
532
|
+
schema: {},
|
|
533
|
+
requiresContext: "variant-selector-group",
|
|
534
|
+
guideline: "Swatch list rendered as color-chip swatches. Use inside a VariantSelectorOptionGroup when the design shows solid color chips. A value with no hex color (hexColor has no catalog source and is injection-only) degrades per value to its variant image, then to the value label, so a chip is never empty — choosing this from a design's colored swatches is always safe. Shape (circle vs square) is styling. Renders its options automatically. Use exactly one swatch list per group."
|
|
535
|
+
});
|
|
536
|
+
const VariantSelectorRadioSwatchesDefinition = defineComponent({
|
|
537
|
+
name: "VariantSelectorRadioSwatches",
|
|
538
|
+
importPath: "@vtex/faststore/components",
|
|
539
|
+
component: VariantSelectorRadioSwatches,
|
|
540
|
+
editor: {
|
|
541
|
+
label: "Variant Radio Swatches",
|
|
542
|
+
category: "commerce"
|
|
543
|
+
},
|
|
544
|
+
schema: {},
|
|
545
|
+
requiresContext: "variant-selector-group",
|
|
546
|
+
guideline: "Swatch list rendered as a radio-dot list — a control circle showing a dot when selected, beside the value label (common for voltage/material lists). Use inside a VariantSelectorOptionGroup; auto never picks this look, so reference it directly when the design shows a radio list. A square control or a checkmark is styling. Typically pair with a VariantSelectorGroupTitle (the axis name) and omit the VariantSelectorGroupValue, since the selected dot already conveys the choice. Renders its options automatically. Use exactly one swatch list per group."
|
|
547
|
+
});
|
|
548
|
+
const VariantSelectorOverflowDefinition = defineComponent({
|
|
549
|
+
name: "VariantSelectorOverflow",
|
|
550
|
+
importPath: "@vtex/faststore/components",
|
|
551
|
+
component: VariantSelectorOverflow,
|
|
552
|
+
editor: {
|
|
553
|
+
label: "Variant Overflow Trigger",
|
|
554
|
+
category: "commerce"
|
|
555
|
+
},
|
|
556
|
+
schema: {},
|
|
557
|
+
requiresContext: "variant-selector-group",
|
|
558
|
+
guideline: "The \"+N more\" trigger inside a VariantSelectorOptionGroup. Composing it opts the group into automatic space-based collapse: the group measures the swatch row and, when the swatches do not fit on one line, collapses the extras behind this trigger, which expands them in place when clicked. It renders only while the row actually overflows. Author it after the swatch list; omit it when the row should never collapse."
|
|
559
|
+
});
|
|
560
|
+
const VariantSelectorOptionDefinition = defineComponent({
|
|
561
|
+
name: "VariantSelectorOption",
|
|
562
|
+
importPath: "@vtex/faststore/components",
|
|
563
|
+
component: VariantSelectorOption,
|
|
564
|
+
editor: {
|
|
565
|
+
label: "Variant Option",
|
|
566
|
+
category: "commerce"
|
|
567
|
+
},
|
|
568
|
+
schema: {},
|
|
569
|
+
requiresContext: "variant-selector-group",
|
|
570
|
+
guideline: "One swatch within a swatch list; reflects checked/disabled states and activates the matching variant on selection. Rendered automatically by the swatch list from the product data — do not author it directly."
|
|
571
|
+
});
|
|
572
|
+
function VariantSelectorRoot({ $data: $dataProp, selectedVariantId, className, children, ...props }) {
|
|
573
|
+
const $data = useDataOverride($dataProp);
|
|
574
|
+
const publishedSelection = useReactiveVar(selectedVariantVar);
|
|
575
|
+
const activeVariantId = publishedVariantIdFor(publishedSelection, $data?.id ?? null) ?? selectedVariantId ?? null;
|
|
576
|
+
let contextValue = null;
|
|
577
|
+
if ($data) {
|
|
578
|
+
const productId = $data.id;
|
|
579
|
+
const variants = deriveVariants($data);
|
|
580
|
+
const selectedVariant = variants.find((variant) => variant.id === activeVariantId) ?? variants[0] ?? null;
|
|
581
|
+
const currentSelection = selectedVariant?.options ?? {};
|
|
582
|
+
contextValue = {
|
|
583
|
+
axes: deriveAxes($data, variants, currentSelection),
|
|
584
|
+
selectedVariantId: selectedVariant?.id ?? null,
|
|
585
|
+
select: (axisName, value) => {
|
|
586
|
+
const resolved = resolveVariant(variants, currentSelection, axisName, value);
|
|
587
|
+
if (resolved) selectedVariantVar({
|
|
588
|
+
productId,
|
|
589
|
+
variantId: resolved.id
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
};
|
|
593
|
+
}
|
|
594
|
+
return /* @__PURE__ */ jsx(VariantSelectorContextInternal, {
|
|
595
|
+
value: contextValue,
|
|
596
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
597
|
+
...props,
|
|
598
|
+
className,
|
|
599
|
+
"data-fs-variant-selector": "",
|
|
600
|
+
children
|
|
601
|
+
})
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
/** Axis container: binds the axis and owns the collapse/expand state, then renders whatever the author
|
|
605
|
+
* composes inside it (title, a swatch list, an overflow trigger). The parts read the axis and overflow
|
|
606
|
+
* state from the group context it provides, so they can be placed freely. */
|
|
607
|
+
function VariantSelectorOptionGroup({ optionName, optionIndex, reserveTriggerSpace = false, ImageComponent = DefaultVariantImage, className, children, ...props }) {
|
|
608
|
+
const [expanded, setExpanded] = useState(false);
|
|
609
|
+
const [titleCount, setTitleCount] = useState(0);
|
|
610
|
+
const [overflowCount, setOverflowCount] = useState(0);
|
|
611
|
+
const [listEl, setListEl] = useState(null);
|
|
612
|
+
const titleId = useId();
|
|
613
|
+
const ctx = useVariantSelector();
|
|
614
|
+
const axis = ctx ? resolveAxis(ctx.axes, optionName, optionIndex) : null;
|
|
615
|
+
const registerTitle = useCallback(() => {
|
|
616
|
+
setTitleCount((count) => count + 1);
|
|
617
|
+
return () => setTitleCount((count) => count - 1);
|
|
618
|
+
}, []);
|
|
619
|
+
const hasTitle = titleCount > 0;
|
|
620
|
+
const registerOverflow = useCallback(() => {
|
|
621
|
+
setOverflowCount((count) => count + 1);
|
|
622
|
+
return () => setOverflowCount((count) => count - 1);
|
|
623
|
+
}, []);
|
|
624
|
+
const hasOverflow = overflowCount > 0;
|
|
625
|
+
const registerListElement = useCallback((el) => setListEl(el), []);
|
|
626
|
+
const measuredVisibleCount = useMeasuredVisibleCount({
|
|
627
|
+
listEl,
|
|
628
|
+
optionCount: axis?.options.length ?? 0,
|
|
629
|
+
hasOverflow,
|
|
630
|
+
enabled: hasOverflow && !expanded,
|
|
631
|
+
reserveTriggerSpace
|
|
632
|
+
});
|
|
633
|
+
const effectiveCap = expanded || !hasOverflow ? null : measuredVisibleCount;
|
|
634
|
+
const groupContextValue = useMemo(() => {
|
|
635
|
+
if (!ctx || !axis) return null;
|
|
636
|
+
const { visibleOptions, hiddenCount, overflowing } = getVisibleOptions(axis, effectiveCap, expanded);
|
|
637
|
+
return {
|
|
638
|
+
axis,
|
|
639
|
+
titleId,
|
|
640
|
+
hasTitle,
|
|
641
|
+
registerTitle,
|
|
642
|
+
registerOverflow,
|
|
643
|
+
hasOverflow,
|
|
644
|
+
registerListElement,
|
|
645
|
+
visibleOptions,
|
|
646
|
+
hiddenCount,
|
|
647
|
+
overflowing,
|
|
648
|
+
expand: () => setExpanded(true),
|
|
649
|
+
select: (value) => ctx.select(axis.name, value),
|
|
650
|
+
ImageComponent
|
|
651
|
+
};
|
|
652
|
+
}, [
|
|
653
|
+
ctx,
|
|
654
|
+
axis,
|
|
655
|
+
effectiveCap,
|
|
656
|
+
expanded,
|
|
657
|
+
titleId,
|
|
658
|
+
hasTitle,
|
|
659
|
+
registerTitle,
|
|
660
|
+
registerOverflow,
|
|
661
|
+
hasOverflow,
|
|
662
|
+
registerListElement,
|
|
663
|
+
ImageComponent
|
|
664
|
+
]);
|
|
665
|
+
if (!groupContextValue) {
|
|
666
|
+
if (ctx) warnUnresolvedAxis(optionName, optionIndex, ctx.axes);
|
|
667
|
+
return null;
|
|
668
|
+
}
|
|
669
|
+
return /* @__PURE__ */ jsx(VariantSelectorGroupContext.Provider, {
|
|
670
|
+
value: groupContextValue,
|
|
671
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
672
|
+
...props,
|
|
673
|
+
className,
|
|
674
|
+
"data-fs-variant-selector-group": "",
|
|
675
|
+
"data-fs-variant-selector-group-overflow": groupContextValue.overflowing ? "true" : "false",
|
|
676
|
+
children
|
|
677
|
+
})
|
|
678
|
+
});
|
|
679
|
+
}
|
|
680
|
+
/** The axis name (the catalog axis name or `label`). Reads the axis from group context, so it reflects
|
|
681
|
+
* the bound axis wherever it is placed (including an accordion header). It is a `<span>`, not a `<label>`:
|
|
682
|
+
* it names the radiogroup via `aria-labelledby`, not a single control. Compose a `VariantSelectorGroupValue`
|
|
683
|
+
* beside it to echo the selection; the separator and value weight are styling on the `data-fs-*` hooks. */
|
|
684
|
+
function VariantSelectorGroupTitle({ label, className, ...props }) {
|
|
685
|
+
const { axis, titleId, registerTitle } = useVariantSelectorGroup();
|
|
686
|
+
useEffect(() => registerTitle(), [registerTitle]);
|
|
687
|
+
return /* @__PURE__ */ jsx("span", {
|
|
688
|
+
...props,
|
|
689
|
+
id: titleId,
|
|
690
|
+
className,
|
|
691
|
+
"data-fs-variant-selector-group-title": "",
|
|
692
|
+
children: label ?? axis.name
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
/** The live selected value of the group's axis, as a standalone placeable part. Decorative (`aria-hidden`):
|
|
696
|
+
* the selection is announced per option, so it never participates in the group's accessible name. */
|
|
697
|
+
function VariantSelectorGroupValue({ className, ...props }) {
|
|
698
|
+
const { axis } = useVariantSelectorGroup();
|
|
699
|
+
return /* @__PURE__ */ jsx("span", {
|
|
700
|
+
...props,
|
|
701
|
+
"aria-hidden": "true",
|
|
702
|
+
className,
|
|
703
|
+
"data-fs-variant-selector-group-value": "",
|
|
704
|
+
children: axis.activeValue ?? ""
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
/** Internal: the swatch list shared by every kind, parametrized by the swatch it renders. The public
|
|
708
|
+
* lists fix `swatch` — `VariantSelectorSwatches` to `'auto'` and the explicit ones to a concrete kind.
|
|
709
|
+
* Provides the resolved swatch component to its options via context. Not registered in the catalog. */
|
|
710
|
+
function VariantSelectorSwatchesBase({ swatch, className, ref: consumerRef, ...props }) {
|
|
711
|
+
const group = useVariantSelectorGroup();
|
|
712
|
+
const { registerListElement } = group;
|
|
713
|
+
const resolvedSwatch = resolveSwatchKind(swatch, group.axis);
|
|
714
|
+
const setListRef = useCallback((el) => {
|
|
715
|
+
registerListElement(el);
|
|
716
|
+
if (typeof consumerRef === "function") consumerRef(el);
|
|
717
|
+
else if (consumerRef) consumerRef.current = el;
|
|
718
|
+
}, [registerListElement, consumerRef]);
|
|
719
|
+
return /* @__PURE__ */ jsx(VariantSelectorSwatchContext.Provider, {
|
|
720
|
+
value: resolvedSwatch.SwatchContent,
|
|
721
|
+
children: /* @__PURE__ */ jsx(RadioGroup, {
|
|
722
|
+
...props,
|
|
723
|
+
ref: setListRef,
|
|
724
|
+
className,
|
|
725
|
+
"aria-labelledby": group.hasTitle ? group.titleId : void 0,
|
|
726
|
+
"aria-label": group.axis.name,
|
|
727
|
+
value: group.axis.activeValue ?? "",
|
|
728
|
+
onValueChange: group.select,
|
|
729
|
+
"data-fs-variant-selector-group-list": "",
|
|
730
|
+
"data-fs-variant-selector-group-mode": resolvedSwatch.mode,
|
|
731
|
+
children: group.visibleOptions.map((option) => /* @__PURE__ */ jsx(VariantSelectorOption, { value: option.value }, option.value))
|
|
732
|
+
})
|
|
733
|
+
});
|
|
734
|
+
}
|
|
735
|
+
/** Auto-inferring swatch list: derives the look from the option data (color/image/label, never radio).
|
|
736
|
+
* Use an explicit sibling list to fix the look instead of inferring it. */
|
|
737
|
+
function VariantSelectorSwatches(props) {
|
|
738
|
+
return /* @__PURE__ */ jsx(VariantSelectorSwatchesBase, {
|
|
739
|
+
swatch: "auto",
|
|
740
|
+
...props
|
|
741
|
+
});
|
|
742
|
+
}
|
|
743
|
+
/** Swatch list with text-label swatches. */
|
|
744
|
+
function VariantSelectorLabelSwatches(props) {
|
|
745
|
+
return /* @__PURE__ */ jsx(VariantSelectorSwatchesBase, {
|
|
746
|
+
swatch: LABEL_SWATCH,
|
|
747
|
+
...props
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
/** Swatch list with image (thumbnail) swatches. */
|
|
751
|
+
function VariantSelectorImageSwatches(props) {
|
|
752
|
+
return /* @__PURE__ */ jsx(VariantSelectorSwatchesBase, {
|
|
753
|
+
swatch: IMAGE_SWATCH,
|
|
754
|
+
...props
|
|
755
|
+
});
|
|
756
|
+
}
|
|
757
|
+
/** Swatch list with color-chip swatches (degrades per value to image, then label). */
|
|
758
|
+
function VariantSelectorColorSwatches(props) {
|
|
759
|
+
return /* @__PURE__ */ jsx(VariantSelectorSwatchesBase, {
|
|
760
|
+
swatch: COLOR_SWATCH,
|
|
761
|
+
...props
|
|
762
|
+
});
|
|
763
|
+
}
|
|
764
|
+
/** Swatch list rendered as a radio-dot list (control circle + dot + label). */
|
|
765
|
+
function VariantSelectorRadioSwatches(props) {
|
|
766
|
+
return /* @__PURE__ */ jsx(VariantSelectorSwatchesBase, {
|
|
767
|
+
swatch: RADIO_SWATCH,
|
|
768
|
+
...props
|
|
769
|
+
});
|
|
770
|
+
}
|
|
771
|
+
/** The "+N more" trigger: composing it opts the group into space-based collapse (via `registerOverflow`),
|
|
772
|
+
* and it renders only while the row overflows, expanding it in place when clicked. Registers in a
|
|
773
|
+
* layout effect so the group can measure and collapse before the browser paints (no full-row flash). */
|
|
774
|
+
function VariantSelectorOverflow({ className, ...props }) {
|
|
775
|
+
const group = useVariantSelectorGroup();
|
|
776
|
+
const { registerOverflow } = group;
|
|
777
|
+
useIsomorphicLayoutEffect(() => registerOverflow(), [registerOverflow]);
|
|
778
|
+
if (!group.overflowing) return null;
|
|
779
|
+
return /* @__PURE__ */ jsxs("button", {
|
|
780
|
+
...props,
|
|
781
|
+
type: "button",
|
|
782
|
+
onClick: group.expand,
|
|
783
|
+
className,
|
|
784
|
+
"data-fs-variant-selector-overflow-trigger": "",
|
|
785
|
+
"data-fs-variant-selector-overflow-count": group.hiddenCount,
|
|
786
|
+
children: [
|
|
787
|
+
"+",
|
|
788
|
+
group.hiddenCount,
|
|
789
|
+
" more"
|
|
790
|
+
]
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
function VariantSelectorOption({ value, ImageComponent, className }) {
|
|
794
|
+
const group = useVariantSelectorGroup();
|
|
795
|
+
const SwatchContent = useContext(VariantSelectorSwatchContext) ?? LabelSwatchContent;
|
|
796
|
+
const option = group.axis.options.find((candidate) => candidate.value === value) ?? null;
|
|
797
|
+
if (!option) return null;
|
|
798
|
+
const checked = group.axis.activeValue === value;
|
|
799
|
+
const disabled = !option.available;
|
|
800
|
+
const Image = ImageComponent ?? group.ImageComponent;
|
|
801
|
+
return /* @__PURE__ */ jsxs(Radio.Root, {
|
|
802
|
+
value,
|
|
803
|
+
disabled,
|
|
804
|
+
title: value,
|
|
805
|
+
className,
|
|
806
|
+
"data-fs-variant-selector-option": "",
|
|
807
|
+
"data-fs-variant-selector-option-checked": checked ? "true" : "false",
|
|
808
|
+
"data-fs-variant-selector-option-disabled": disabled ? "true" : "false",
|
|
809
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
810
|
+
"data-fs-sr-only": "",
|
|
811
|
+
className: "sr-only",
|
|
812
|
+
children: [
|
|
813
|
+
group.axis.name,
|
|
814
|
+
": ",
|
|
815
|
+
value
|
|
816
|
+
]
|
|
817
|
+
}), /* @__PURE__ */ jsx(SwatchContent, {
|
|
818
|
+
swatch: option.swatch,
|
|
819
|
+
value,
|
|
820
|
+
Image
|
|
821
|
+
})]
|
|
822
|
+
});
|
|
823
|
+
}
|
|
824
|
+
const VariantSelector = {
|
|
825
|
+
Root: VariantSelectorRoot,
|
|
826
|
+
OptionGroup: VariantSelectorOptionGroup,
|
|
827
|
+
Title: VariantSelectorGroupTitle,
|
|
828
|
+
Value: VariantSelectorGroupValue,
|
|
829
|
+
Swatches: VariantSelectorSwatches,
|
|
830
|
+
LabelSwatches: VariantSelectorLabelSwatches,
|
|
831
|
+
ImageSwatches: VariantSelectorImageSwatches,
|
|
832
|
+
ColorSwatches: VariantSelectorColorSwatches,
|
|
833
|
+
RadioSwatches: VariantSelectorRadioSwatches,
|
|
834
|
+
Overflow: VariantSelectorOverflow,
|
|
835
|
+
Option: VariantSelectorOption
|
|
836
|
+
};
|
|
837
|
+
//#endregion
|
|
838
|
+
export { VariantSelector, VariantSelectorColorSwatches, VariantSelectorColorSwatchesDefinition, VariantSelectorContext, VariantSelectorGroupContext, VariantSelectorGroupTitle, VariantSelectorGroupTitleDefinition, VariantSelectorGroupValue, VariantSelectorGroupValueDefinition, VariantSelectorImageSwatches, VariantSelectorImageSwatchesDefinition, VariantSelectorLabelSwatches, VariantSelectorLabelSwatchesDefinition, VariantSelectorOption, VariantSelectorOptionDefinition, VariantSelectorOptionGroup, VariantSelectorOptionGroupDefinition, VariantSelectorOverflow, VariantSelectorOverflowDefinition, VariantSelectorRadioSwatches, VariantSelectorRadioSwatchesDefinition, VariantSelectorRoot, VariantSelectorRootDefinition, VariantSelectorSwatches, VariantSelectorSwatchesDefinition, computeVisibleCount, inferDisplayMode };
|
|
839
|
+
|
|
840
|
+
//# sourceMappingURL=variant-selector.js.map
|