@vtex/faststore 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +99 -0
- package/dist/actions.json +152 -1
- package/dist/catalog.json +2541 -1278
- package/dist/cli/UnreachableCaseError-Crd168Vu.js +10 -0
- package/dist/cli/UnreachableCaseError-Crd168Vu.js.map +1 -0
- package/dist/cli/cacheControl-CEojH_TM.js +158 -0
- package/dist/cli/cacheControl-CEojH_TM.js.map +1 -0
- package/dist/cli/cachePolicy-m2vASMRW.js +26 -0
- package/dist/cli/cachePolicy-m2vASMRW.js.map +1 -0
- package/dist/cli/computeCoreSchemaHash-DPJZj-qJ.js +10 -0
- package/dist/cli/computeCoreSchemaHash-DPJZj-qJ.js.map +1 -0
- package/dist/cli/default-BCQHcwbL.js +253 -0
- package/dist/cli/default-BCQHcwbL.js.map +1 -0
- package/dist/cli/disableSuggestions-yO9UqiWn.js +21 -0
- package/dist/cli/disableSuggestions-yO9UqiWn.js.map +1 -0
- package/dist/cli/dist-C1JhdHfo.js +2001 -0
- package/dist/cli/dist-C1JhdHfo.js.map +1 -0
- package/dist/cli/graphql-DG9thCDG.js +14589 -0
- package/dist/cli/graphql-DG9thCDG.js.map +1 -0
- package/dist/cli/index.d.ts +799 -0
- package/dist/cli/index.js +36459 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/index.min-BsIHDfFK.js +613 -0
- package/dist/cli/index.min-BsIHDfFK.js.map +1 -0
- package/dist/cli/inlineTrace-uLgOJ3TH.js +52 -0
- package/dist/cli/inlineTrace-uLgOJ3TH.js.map +1 -0
- package/dist/cli/internalPlugin-DnuwN4_4.js +11 -0
- package/dist/cli/internalPlugin-DnuwN4_4.js.map +1 -0
- package/dist/cli/packageVersion-DQAnIEil.js +6 -0
- package/dist/cli/packageVersion-DQAnIEil.js.map +1 -0
- package/dist/cli/rolldown-runtime-BMI-E3GI.js +44 -0
- package/dist/cli/schemaIsSubgraph-DoGh3OYj.js +17 -0
- package/dist/cli/schemaIsSubgraph-DoGh3OYj.js.map +1 -0
- package/dist/cli/schemaReporting-K-me-3-v.js +199 -0
- package/dist/cli/schemaReporting-K-me-3-v.js.map +1 -0
- package/dist/cli/server-runtime.js +49879 -0
- package/dist/cli/server-runtime.js.map +1 -0
- package/dist/cli/traceTreeBuilder-BIcV2U7b.js +9118 -0
- package/dist/cli/traceTreeBuilder-BIcV2U7b.js.map +1 -0
- package/dist/cli/usageReporting-Bpl8vSZX.js +10201 -0
- package/dist/cli/usageReporting-Bpl8vSZX.js.map +1 -0
- package/dist/cli/v4-CBhFvC49.js +42 -0
- package/dist/cli/v4-CBhFvC49.js.map +1 -0
- package/dist/client.d.ts +5 -1
- package/dist/client.js +5 -1
- package/dist/components.d.ts +38 -9
- package/dist/components.js +42 -13
- package/dist/content-types.json +616 -0
- package/dist/core/dist/define-component.d.ts +43 -1
- package/dist/core/dist/index.d.ts +2 -2
- package/dist/docs/account-access-gate.md +4 -4
- package/dist/docs/account-address-book.md +519 -0
- package/dist/docs/account-entry-point.md +1 -1
- package/dist/docs/account-menu-identity.md +160 -0
- package/dist/docs/account-menu.md +107 -24
- package/dist/docs/alert-dialog.md +2 -2
- package/dist/docs/avatar.md +103 -0
- package/dist/docs/billing-address.md +17 -9
- package/dist/docs/card-entry.md +37 -6
- package/dist/docs/cardholder-document.md +16 -14
- package/dist/docs/cart-item.md +1 -1
- package/dist/docs/cart.md +8 -8
- package/dist/docs/client-profile-fieldset.md +7 -5
- package/dist/docs/copy-text.md +84 -0
- package/dist/docs/document-field.md +8 -8
- package/dist/docs/footer-link-group.md +2 -2
- package/dist/docs/header-root.md +1 -1
- package/dist/docs/incentives.md +2 -2
- package/dist/docs/logo.md +5 -5
- package/dist/docs/my-account-profile.md +5 -5
- package/dist/docs/navigation-link-list.md +2 -2
- package/dist/docs/navigation-link.md +3 -3
- package/dist/docs/order-cancel.md +52 -0
- package/dist/docs/order-delivery-address.md +63 -0
- package/dist/docs/order-delivery-group.md +83 -0
- package/dist/docs/order-details-back.md +41 -0
- package/dist/docs/order-details-header.md +48 -0
- package/dist/docs/order-list-row.md +46 -0
- package/dist/docs/order-list-search.md +101 -0
- package/dist/docs/order-list-views.md +97 -0
- package/dist/docs/order-list.md +94 -0
- package/dist/docs/order-payment.md +94 -0
- package/dist/docs/order-placed-date.md +49 -0
- package/dist/docs/order-placed-payment-summary.md +13 -15
- package/dist/docs/order-placed.md +225 -0
- package/dist/docs/order-progress.md +88 -0
- package/dist/docs/order-status-badge.md +91 -0
- package/dist/docs/order-summary.md +53 -0
- package/dist/docs/payment-method-badges.md +14 -3
- package/dist/docs/place-order.md +13 -9
- package/dist/docs/product-shelf.md +20 -13
- package/dist/docs/saved-cards.md +2 -2
- package/dist/docs/select.md +19 -6
- package/dist/docs/session.md +1 -1
- package/dist/docs/shipping-address.md +1 -1
- package/dist/docs/sign-in-redirect.md +6 -6
- package/dist/docs/toast.md +7 -3
- package/dist/index.d.ts +7 -3
- package/dist/index.js +2 -1
- package/dist/internal/client.d.ts +6 -1
- package/dist/internal/client.js +8 -3
- package/dist/internal/content.d.ts +2 -2
- package/dist/internal/server.d.ts +8 -1
- package/dist/internal/server.js +8 -1
- package/dist/matter/account-access-gate/account-access-gate.d.ts +2 -1
- package/dist/matter/account-access-gate/account-access-gate.js +19 -16
- package/dist/matter/account-access-gate/account-access-gate.js.map +1 -1
- package/dist/matter/account-address-book/account-address-book-delete.d.ts +60 -0
- package/dist/matter/account-address-book/account-address-book-delete.js +184 -0
- package/dist/matter/account-address-book/account-address-book-delete.js.map +1 -0
- package/dist/matter/account-address-book/account-address-book-deliverability.d.ts +19 -0
- package/dist/matter/account-address-book/account-address-book-deliverability.js +50 -0
- package/dist/matter/account-address-book/account-address-book-deliverability.js.map +1 -0
- package/dist/matter/account-address-book/account-address-book-form-parts.d.ts +42 -0
- package/dist/matter/account-address-book/account-address-book-form-parts.js +146 -0
- package/dist/matter/account-address-book/account-address-book-form-parts.js.map +1 -0
- package/dist/matter/account-address-book/account-address-book-profile-notice.d.ts +25 -0
- package/dist/matter/account-address-book/account-address-book-profile-notice.js +72 -0
- package/dist/matter/account-address-book/account-address-book-profile-notice.js.map +1 -0
- package/dist/matter/account-address-book/account-address-book.d.ts +120 -0
- package/dist/matter/account-address-book/account-address-book.js +469 -0
- package/dist/matter/account-address-book/account-address-book.js.map +1 -0
- package/dist/matter/account-address-book/account-address-country-switch.js +59 -0
- package/dist/matter/account-address-book/account-address-country-switch.js.map +1 -0
- package/dist/matter/account-address-book/account-address-country.d.ts +36 -0
- package/dist/matter/account-address-book/account-address-country.js +151 -0
- package/dist/matter/account-address-book/account-address-country.js.map +1 -0
- package/dist/matter/account-address-book/account-address-first-line.js +11 -0
- package/dist/matter/account-address-book/account-address-first-line.js.map +1 -0
- package/dist/matter/account-address-book/account-address-form-context.d.ts +55 -0
- package/dist/matter/account-address-book/account-address-form-context.js +14 -0
- package/dist/matter/account-address-book/account-address-form-context.js.map +1 -0
- package/dist/matter/account-address-book/account-address-form.d.ts +85 -0
- package/dist/matter/account-address-book/account-address-form.js +946 -0
- package/dist/matter/account-address-book/account-address-form.js.map +1 -0
- package/dist/matter/account-address-book/account-address-postal-autofill.js +189 -0
- package/dist/matter/account-address-book/account-address-postal-autofill.js.map +1 -0
- package/dist/matter/account-address-book/account-address-record.d.ts +26 -0
- package/dist/matter/account-address-book/account-address-record.js +138 -0
- package/dist/matter/account-address-book/account-address-record.js.map +1 -0
- package/dist/matter/account-entry-point/account-entry-point.js +11 -11
- package/dist/matter/account-entry-point/account-entry-point.js.map +1 -1
- package/dist/matter/account-menu/account-menu.d.ts +77 -3
- package/dist/matter/account-menu/account-menu.js +252 -19
- package/dist/matter/account-menu/account-menu.js.map +1 -1
- package/dist/matter/account-menu/sign-out-failure.js +50 -0
- package/dist/matter/account-menu/sign-out-failure.js.map +1 -0
- package/dist/matter/account-menu-identity/account-menu-identity.d.ts +21 -0
- package/dist/matter/account-menu-identity/account-menu-identity.js +88 -0
- package/dist/matter/account-menu-identity/account-menu-identity.js.map +1 -0
- package/dist/matter/billing-address/billing-address.d.ts +30 -17
- package/dist/matter/billing-address/billing-address.js +128 -33
- package/dist/matter/billing-address/billing-address.js.map +1 -1
- package/dist/matter/breadcrumb/breadcrumb.js +2 -2
- package/dist/matter/breadcrumb/breadcrumb.js.map +1 -1
- package/dist/matter/card-entry/card-capture.js +4 -3
- package/dist/matter/card-entry/card-capture.js.map +1 -1
- package/dist/matter/card-entry/card-entry.d.ts +5 -3
- package/dist/matter/card-entry/card-entry.js +78 -27
- package/dist/matter/card-entry/card-entry.js.map +1 -1
- package/dist/matter/cardholder-document/cardholder-document.d.ts +10 -9
- package/dist/matter/cardholder-document/cardholder-document.js +36 -16
- package/dist/matter/cardholder-document/cardholder-document.js.map +1 -1
- package/dist/matter/cart/cart.d.ts +7 -2
- package/dist/matter/cart/cart.js +29 -26
- package/dist/matter/cart/cart.js.map +1 -1
- package/dist/matter/cart-item/cart-item.js +2 -2
- package/dist/matter/cart-item/cart-item.js.map +1 -1
- package/dist/matter/client-preferences/client-preferences-fieldset.js +2 -2
- package/dist/matter/client-profile-form/client-profile-fieldset.js +9 -6
- package/dist/matter/client-profile-form/client-profile-fieldset.js.map +1 -1
- package/dist/matter/identity-edit/identity-edit.js +3 -3
- package/dist/matter/identity-edit/identity-edit.js.map +1 -1
- package/dist/matter/identity-summary/identity-summary.js +4 -3
- package/dist/matter/identity-summary/identity-summary.js.map +1 -1
- package/dist/matter/my-account-profile/my-account-profile.d.ts +6 -3
- package/dist/matter/my-account-profile/my-account-profile.js +6 -5
- package/dist/matter/my-account-profile/my-account-profile.js.map +1 -1
- package/dist/matter/order-cancel/order-cancel.d.ts +110 -0
- package/dist/matter/order-cancel/order-cancel.js +344 -0
- package/dist/matter/order-cancel/order-cancel.js.map +1 -0
- package/dist/matter/order-delivery-address/order-delivery-address.d.ts +73 -0
- package/dist/matter/order-delivery-address/order-delivery-address.js +172 -0
- package/dist/matter/order-delivery-address/order-delivery-address.js.map +1 -0
- package/dist/matter/order-delivery-group/order-delivery-group.d.ts +128 -0
- package/dist/matter/order-delivery-group/order-delivery-group.js +408 -0
- package/dist/matter/order-delivery-group/order-delivery-group.js.map +1 -0
- package/dist/matter/order-details-header/order-details-header.d.ts +104 -0
- package/dist/matter/order-details-header/order-details-header.js +190 -0
- package/dist/matter/order-details-header/order-details-header.js.map +1 -0
- package/dist/matter/order-list/customer-orders-filter.d.ts +12 -0
- package/dist/matter/order-list/customer-orders-filter.js +30 -0
- package/dist/matter/order-list/customer-orders-filter.js.map +1 -0
- package/dist/matter/order-list/order-list.d.ts +121 -0
- package/dist/matter/order-list/order-list.js +395 -0
- package/dist/matter/order-list/order-list.js.map +1 -0
- package/dist/matter/order-list-row/order-list-row.d.ts +44 -0
- package/dist/matter/order-list-row/order-list-row.js +127 -0
- package/dist/matter/order-list-row/order-list-row.js.map +1 -0
- package/dist/matter/order-list-search/order-list-search.d.ts +72 -0
- package/dist/matter/order-list-search/order-list-search.js +296 -0
- package/dist/matter/order-list-search/order-list-search.js.map +1 -0
- package/dist/matter/order-list-views/order-list-views.d.ts +65 -0
- package/dist/matter/order-list-views/order-list-views.js +154 -0
- package/dist/matter/order-list-views/order-list-views.js.map +1 -0
- package/dist/matter/order-payment/order-payment.d.ts +83 -0
- package/dist/matter/order-payment/order-payment.js +258 -0
- package/dist/matter/order-payment/order-payment.js.map +1 -0
- package/dist/matter/order-placed/order-placed-deliveries.d.ts +145 -0
- package/dist/matter/order-placed/order-placed-deliveries.js +380 -0
- package/dist/matter/order-placed/order-placed-deliveries.js.map +1 -0
- package/dist/matter/order-placed/order-placed.d.ts +122 -0
- package/dist/matter/order-placed/order-placed.js +452 -0
- package/dist/matter/order-placed/order-placed.js.map +1 -0
- package/dist/matter/order-placed-date/order-placed-date.d.ts +45 -0
- package/dist/matter/order-placed-date/order-placed-date.js +92 -0
- package/dist/matter/order-placed-date/order-placed-date.js.map +1 -0
- package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.d.ts +5 -8
- package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js +29 -81
- package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js.map +1 -1
- package/dist/matter/order-progress/order-progress.d.ts +85 -0
- package/dist/matter/order-progress/order-progress.js +203 -0
- package/dist/matter/order-progress/order-progress.js.map +1 -0
- package/dist/matter/order-summary/order-summary.d.ts +81 -0
- package/dist/matter/order-summary/order-summary.js +192 -0
- package/dist/matter/order-summary/order-summary.js.map +1 -0
- package/dist/matter/payment/cardholder-document-rule.d.ts +35 -0
- package/dist/matter/payment/cardholder-document-rule.js +35 -0
- package/dist/matter/payment/cardholder-document-rule.js.map +1 -0
- package/dist/matter/payment/payment-card-capture.js +38 -23
- package/dist/matter/payment/payment-card-capture.js.map +1 -1
- package/dist/matter/payment/payment-controller.js +12 -0
- package/dist/matter/payment/payment-controller.js.map +1 -1
- package/dist/matter/payment/payment-method-badges.js +4 -2
- package/dist/matter/payment/payment-method-badges.js.map +1 -1
- package/dist/matter/payment/payment.js +12 -0
- package/dist/matter/payment/payment.js.map +1 -1
- package/dist/matter/payment/use-payment-method-selection.d.ts +39 -0
- package/dist/matter/payment/use-payment-method-selection.js +30 -2
- package/dist/matter/payment/use-payment-method-selection.js.map +1 -1
- package/dist/matter/payment/use-payment-submit-gate.d.ts +16 -2
- package/dist/matter/payment/use-payment-submit-gate.js +42 -14
- package/dist/matter/payment/use-payment-submit-gate.js.map +1 -1
- package/dist/matter/place-order/place-order.d.ts +12 -7
- package/dist/matter/place-order/place-order.js +126 -103
- package/dist/matter/place-order/place-order.js.map +1 -1
- package/dist/matter/pricing/pricing.js +5 -5
- package/dist/matter/pricing/pricing.js.map +1 -1
- package/dist/matter/product-shelf/product-shelf.d.ts +61 -31
- package/dist/matter/product-shelf/product-shelf.js +157 -57
- package/dist/matter/product-shelf/product-shelf.js.map +1 -1
- package/dist/matter/region/region.js +1 -1
- package/dist/matter/saved-cards/saved-cards.js +27 -15
- package/dist/matter/saved-cards/saved-cards.js.map +1 -1
- package/dist/matter/session/session.js +2 -2
- package/dist/matter/session/session.js.map +1 -1
- package/dist/matter/shipping-address/country-descriptors.d.ts +1 -0
- package/dist/matter/shipping-address/country-descriptors.js +23 -1
- package/dist/matter/shipping-address/country-descriptors.js.map +1 -1
- package/dist/matter/shipping-address/shipping-address.js +63 -15
- package/dist/matter/shipping-address/shipping-address.js.map +1 -1
- package/dist/matter/shipping-simulator/shipping-simulator.d.ts +1 -1
- package/dist/matter/shipping-simulator/shipping-simulator.js.map +1 -1
- package/dist/matter/sign-in-redirect/sign-in-redirect.js +48 -10
- package/dist/matter/sign-in-redirect/sign-in-redirect.js.map +1 -1
- package/dist/matter/variant-selector/variant-selector.js +2 -2
- package/dist/matter/variant-selector/variant-selector.js.map +1 -1
- package/dist/particles/address-summary/address-summary.js +2 -2
- package/dist/particles/address-summary/address-summary.js.map +1 -1
- package/dist/particles/alert-dialog/alert-dialog.d.ts +5 -1
- package/dist/particles/alert-dialog/alert-dialog.js +5 -2
- package/dist/particles/alert-dialog/alert-dialog.js.map +1 -1
- package/dist/particles/avatar/avatar.d.ts +17 -0
- package/dist/particles/avatar/avatar.js +65 -0
- package/dist/particles/avatar/avatar.js.map +1 -0
- package/dist/particles/copy-text/copy-text.d.ts +28 -0
- package/dist/particles/copy-text/copy-text.js +140 -0
- package/dist/particles/copy-text/copy-text.js.map +1 -0
- package/dist/particles/document-field/document-field.d.ts +34 -5
- package/dist/particles/document-field/document-field.js +115 -19
- package/dist/particles/document-field/document-field.js.map +1 -1
- package/dist/particles/field/field.js +1 -1
- package/dist/particles/field/field.js.map +1 -1
- package/dist/particles/footer-link-group/footer-link-group.d.ts +6 -2
- package/dist/particles/footer-link-group/footer-link-group.js +18 -7
- package/dist/particles/footer-link-group/footer-link-group.js.map +1 -1
- package/dist/particles/incentives/incentives.d.ts +6 -2
- package/dist/particles/incentives/incentives.js +7 -2
- package/dist/particles/incentives/incentives.js.map +1 -1
- package/dist/particles/logo/logo.d.ts +3 -2
- package/dist/particles/logo/logo.js +20 -8
- package/dist/particles/logo/logo.js.map +1 -1
- package/dist/particles/navigation-link/navigation-link.d.ts +2 -3
- package/dist/particles/navigation-link/navigation-link.js +4 -4
- package/dist/particles/navigation-link/navigation-link.js.map +1 -1
- package/dist/particles/navigation-link-list/navigation-link-list.d.ts +6 -2
- package/dist/particles/navigation-link-list/navigation-link-list.js +18 -7
- package/dist/particles/navigation-link-list/navigation-link-list.js.map +1 -1
- package/dist/particles/order-details-back/order-details-back.d.ts +28 -0
- package/dist/particles/order-details-back/order-details-back.js +52 -0
- package/dist/particles/order-details-back/order-details-back.js.map +1 -0
- package/dist/particles/order-status-badge/order-status-badge.d.ts +19 -0
- package/dist/particles/order-status-badge/order-status-badge.js +50 -0
- package/dist/particles/order-status-badge/order-status-badge.js.map +1 -0
- package/dist/particles/phone-field/phone-field.js +2 -2
- package/dist/particles/phone-field/phone-field.js.map +1 -1
- package/dist/particles/select/select.js +6 -6
- package/dist/particles/select/select.js.map +1 -1
- package/dist/particles/toast/toast.d.ts +1 -1
- package/dist/particles/toast/toast.js +32 -6
- package/dist/particles/toast/toast.js.map +1 -1
- package/dist/schema.graphql +1079 -54
- package/dist/sdk/actions/address-action-provider.d.ts +16 -0
- package/dist/sdk/actions/address-action-provider.js +20 -0
- package/dist/sdk/actions/address-action-provider.js.map +1 -0
- package/dist/sdk/actions/analytics-action-provider.js +1 -1
- package/dist/sdk/actions/index.d.ts +3 -1
- package/dist/sdk/actions/index.js +3 -1
- package/dist/sdk/actions/order-action-provider.d.ts +12 -0
- package/dist/sdk/actions/order-action-provider.js +16 -0
- package/dist/sdk/actions/order-action-provider.js.map +1 -0
- package/dist/sdk/actions/types.d.ts +6 -2
- package/dist/sdk/address/address-fields.js +38 -0
- package/dist/sdk/address/address-fields.js.map +1 -0
- package/dist/sdk/address/checkout-readiness.js +17 -0
- package/dist/sdk/address/checkout-readiness.js.map +1 -0
- package/dist/sdk/address/constants.js +60 -0
- package/dist/sdk/address/constants.js.map +1 -0
- package/dist/sdk/address/country-display.js +19 -0
- package/dist/sdk/address/country-display.js.map +1 -0
- package/dist/sdk/address/country-rules.js +30 -0
- package/dist/sdk/address/country-rules.js.map +1 -0
- package/dist/sdk/address/format-address.js +18 -0
- package/dist/sdk/address/format-address.js.map +1 -0
- package/dist/sdk/address/iso-countries.js +262 -0
- package/dist/sdk/address/iso-countries.js.map +1 -0
- package/dist/sdk/address/layouts.js +56 -0
- package/dist/sdk/address/layouts.js.map +1 -0
- package/dist/sdk/address/messages.js +97 -0
- package/dist/sdk/address/messages.js.map +1 -0
- package/dist/sdk/address/operations.d.ts +54 -0
- package/dist/sdk/address/operations.js +83 -0
- package/dist/sdk/address/operations.js.map +1 -0
- package/dist/sdk/address/postal-code-lookup-operations.js +23 -0
- package/dist/sdk/address/postal-code-lookup-operations.js.map +1 -0
- package/dist/sdk/address/postal-code.js +11 -0
- package/dist/sdk/address/postal-code.js.map +1 -0
- package/dist/sdk/address/schema.js +14 -0
- package/dist/sdk/address/schema.js.map +1 -0
- package/dist/sdk/address/server-fields.js +25 -0
- package/dist/sdk/address/server-fields.js.map +1 -0
- package/dist/sdk/address/switch-country.js +57 -0
- package/dist/sdk/address/switch-country.js.map +1 -0
- package/dist/sdk/address/types.d.ts +26 -0
- package/dist/sdk/address/use-address-actions.d.ts +29 -0
- package/dist/sdk/address/use-address-actions.js +247 -0
- package/dist/sdk/address/use-address-actions.js.map +1 -0
- package/dist/sdk/address/use-address-by-postal-code.js +57 -0
- package/dist/sdk/address/use-address-by-postal-code.js.map +1 -0
- package/dist/sdk/address/validate-address.js +62 -0
- package/dist/sdk/address/validate-address.js.map +1 -0
- package/dist/sdk/analytics/use-analytics-actions.js +2 -1
- package/dist/sdk/analytics/use-analytics-actions.js.map +1 -1
- package/dist/sdk/cache/storefront-cache.js +29 -4
- package/dist/sdk/cache/storefront-cache.js.map +1 -1
- package/dist/sdk/cart/use-cart-actions.js +9 -8
- package/dist/sdk/cart/use-cart-actions.js.map +1 -1
- package/dist/sdk/cart/use-cart-validate-on-open.js +2 -1
- package/dist/sdk/cart/use-cart-validate-on-open.js.map +1 -1
- package/dist/sdk/client/fetch-page-data.d.ts +11 -0
- package/dist/sdk/client/fetch-page-data.js +12 -1
- package/dist/sdk/client/fetch-page-data.js.map +1 -1
- package/dist/sdk/content/create-content-runtime.d.ts +22 -1
- package/dist/sdk/content/create-content-runtime.js +90 -9
- package/dist/sdk/content/create-content-runtime.js.map +1 -1
- package/dist/sdk/data/empty-content-value.js +16 -0
- package/dist/sdk/data/empty-content-value.js.map +1 -0
- package/dist/sdk/data/failed-fields.js +23 -0
- package/dist/sdk/data/failed-fields.js.map +1 -0
- package/dist/sdk/data/hot-data-provider.js +2 -1
- package/dist/sdk/data/hot-data-provider.js.map +1 -1
- package/dist/sdk/data/index.js +1 -1
- package/dist/sdk/data/page-reactive-data-root.d.ts +45 -7
- package/dist/sdk/data/page-reactive-data-root.js +88 -12
- package/dist/sdk/data/page-reactive-data-root.js.map +1 -1
- package/dist/sdk/data/variables-from-content.d.ts +43 -0
- package/dist/sdk/data/variables-from-content.js +57 -0
- package/dist/sdk/data/variables-from-content.js.map +1 -0
- package/dist/sdk/generated/fragment-types.js +2 -0
- package/dist/sdk/generated/fragment-types.js.map +1 -1
- package/dist/sdk/generated/gql.js +4 -1
- package/dist/sdk/generated/gql.js.map +1 -1
- package/dist/sdk/generated/graphql.d.ts +8 -0
- package/dist/sdk/generated/graphql.js +296 -1
- package/dist/sdk/generated/graphql.js.map +1 -1
- package/dist/sdk/i18n/messages/en-US.js +138 -1
- package/dist/sdk/i18n/messages/en-US.json +138 -1
- package/dist/sdk/i18n/messages/en-US.json.d.ts +137 -0
- package/dist/sdk/i18n/messages/es-ES.js +138 -1
- package/dist/sdk/i18n/messages/es-ES.json +138 -1
- package/dist/sdk/i18n/messages/pt-BR.js +138 -1
- package/dist/sdk/i18n/messages/pt-BR.json +138 -1
- package/dist/sdk/identity/use-identity-actions.js +5 -4
- package/dist/sdk/identity/use-identity-actions.js.map +1 -1
- package/dist/sdk/navigation/current-page.js +30 -0
- package/dist/sdk/navigation/current-page.js.map +1 -0
- package/dist/sdk/navigation/not-found-log.d.ts +28 -0
- package/dist/sdk/navigation/not-found-log.js +133 -0
- package/dist/sdk/navigation/not-found-log.js.map +1 -0
- package/dist/sdk/navigation/path.js +25 -0
- package/dist/sdk/navigation/path.js.map +1 -0
- package/dist/sdk/navigation/redirect.d.ts +11 -0
- package/dist/sdk/navigation/redirect.js +22 -0
- package/dist/sdk/navigation/redirect.js.map +1 -0
- package/dist/sdk/navigation/report.js +70 -0
- package/dist/sdk/navigation/report.js.map +1 -0
- package/dist/sdk/navigation/resolve-storefront-href.d.ts +12 -0
- package/dist/sdk/navigation/resolve-storefront-href.js +214 -0
- package/dist/sdk/navigation/resolve-storefront-href.js.map +1 -0
- package/dist/sdk/navigation/route-identity-provider.d.ts +11 -0
- package/dist/sdk/navigation/route-identity-provider.js +20 -0
- package/dist/sdk/navigation/route-identity-provider.js.map +1 -0
- package/dist/sdk/navigation/route-map-provider.d.ts +19 -0
- package/dist/sdk/navigation/route-map-provider.js +29 -0
- package/dist/sdk/navigation/route-map-provider.js.map +1 -0
- package/dist/sdk/navigation/storefront-link.d.ts +16 -0
- package/dist/sdk/navigation/storefront-link.js +66 -0
- package/dist/sdk/navigation/storefront-link.js.map +1 -0
- package/dist/sdk/navigation/types.d.ts +45 -0
- package/dist/sdk/navigation/use-storefront-navigation.d.ts +26 -0
- package/dist/sdk/navigation/use-storefront-navigation.js +73 -0
- package/dist/sdk/navigation/use-storefront-navigation.js.map +1 -0
- package/dist/sdk/navigation/use-storefront-route.d.ts +26 -0
- package/dist/sdk/navigation/use-storefront-route.js +87 -0
- package/dist/sdk/navigation/use-storefront-route.js.map +1 -0
- package/dist/sdk/navigation/use-storefront-search-params.d.ts +11 -0
- package/dist/sdk/navigation/use-storefront-search-params.js +16 -0
- package/dist/sdk/navigation/use-storefront-search-params.js.map +1 -0
- package/dist/sdk/orders/completion-badge.d.ts +8 -0
- package/dist/sdk/orders/completion-badge.js +47 -0
- package/dist/sdk/orders/completion-badge.js.map +1 -0
- package/dist/sdk/orders/order-operations.d.ts +19 -0
- package/dist/sdk/orders/order-operations.js +21 -0
- package/dist/sdk/orders/order-operations.js.map +1 -0
- package/dist/sdk/orders/use-order-actions.d.ts +23 -0
- package/dist/sdk/orders/use-order-actions.js +62 -0
- package/dist/sdk/orders/use-order-actions.js.map +1 -0
- package/dist/sdk/payment/gateway-origin.js +26 -13
- package/dist/sdk/payment/gateway-origin.js.map +1 -1
- package/dist/sdk/payment/gateway.d.ts +14 -2
- package/dist/sdk/payment/gateway.js +32 -14
- package/dist/sdk/payment/gateway.js.map +1 -1
- package/dist/sdk/payment/operations.js +11 -0
- package/dist/sdk/payment/operations.js.map +1 -1
- package/dist/sdk/payment/submission-registry.d.ts +2 -1
- package/dist/sdk/payment/submission-registry.js +12 -8
- package/dist/sdk/payment/submission-registry.js.map +1 -1
- package/dist/sdk/payment/use-payment-actions.d.ts +5 -3
- package/dist/sdk/payment/use-payment-actions.js +6 -3
- package/dist/sdk/payment/use-payment-actions.js.map +1 -1
- package/dist/sdk/payment/use-place-order.d.ts +6 -3
- package/dist/sdk/payment/use-place-order.js +334 -144
- package/dist/sdk/payment/use-place-order.js.map +1 -1
- package/dist/sdk/region/use-region-actions.js +2 -1
- package/dist/sdk/region/use-region-actions.js.map +1 -1
- package/dist/sdk/seo/page-alternates.d.ts +55 -0
- package/dist/sdk/seo/page-alternates.js +132 -0
- package/dist/sdk/seo/page-alternates.js.map +1 -0
- package/dist/sdk/session/read-server-session.d.ts +21 -0
- package/dist/sdk/session/read-server-session.js +61 -0
- package/dist/sdk/session/read-server-session.js.map +1 -0
- package/dist/sdk/session/use-session-actions.js +5 -4
- package/dist/sdk/session/use-session-actions.js.map +1 -1
- package/dist/sdk/session/use-session-revalidation.js +2 -1
- package/dist/sdk/session/use-session-revalidation.js.map +1 -1
- package/dist/sdk/shipping/use-shipping-actions.js +3 -2
- package/dist/sdk/shipping/use-shipping-actions.js.map +1 -1
- package/dist/utils/own-value.js +19 -0
- package/dist/utils/own-value.js.map +1 -0
- package/dist/utils/safe-href.d.ts +11 -0
- package/dist/utils/safe-href.js +31 -22
- package/dist/utils/safe-href.js.map +1 -1
- package/package.json +17 -2
- package/skills/storefront-asset/SKILL.md +111 -0
- package/skills/storefront-asset/references/api-side.md +153 -0
- package/skills/storefront-asset/references/findings.md +40 -0
- package/skills/storefront-asset/references/ui-side.md +94 -0
- package/src/styles/tailwind.css +27 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"phone-field.js","names":["BaseField"],"sources":["../../../src/particles/phone-field/phone-field.tsx"],"sourcesContent":["'use client';\nimport { Field as BaseField } from '@base-ui/react/field';\nimport { defineComponent } from '@vtex/fs-core';\nimport type { ChangeEvent, FocusEvent, ReactNode, Ref } from 'react';\nimport { createContext, useContext, useMemo, useState } from 'react';\nimport { useFormContext, useFormState } from 'react-hook-form';\nimport {\n FieldBinding,\n type FieldContract,\n type FieldRule,\n mergeFieldValidator,\n TEXT_FIELD_VALUE,\n useBoundField,\n useField,\n} from '../field/field.js';\nimport { Input } from '../input/input.js';\nimport { useComposedRef } from '../shared/compose-refs.js';\n\n// ---------------------------------------------------------------------------\n// Country masks\n// ---------------------------------------------------------------------------\n\n/**\n * Country codes supported by PhoneField.\n * Only US and BR are implemented; every other ISO-2 code falls back to the US\n * format (Gap-06 in the PhoneField spec).\n */\nexport type PhoneCountry = 'US' | 'BR';\n\n/**\n * Returns true when `value` starts with the E.164 or bare country-code prefix\n * for the given country.\n *\n * US country code: 1 → \"+1…\" or \"1…\"\n * BR country code: 55 → \"+55…\" or \"55…\"\n */\nfunction isValidCountryCode(value: string, country: PhoneCountry): boolean {\n switch (country) {\n case 'US':\n return value.startsWith('+1') || value.startsWith('1');\n case 'BR':\n return value.startsWith('+55') || value.startsWith('55');\n default:\n return false;\n }\n}\n\n/**\n * Strips phone mask formatting from `value`.\n *\n * When the raw string carries a valid country-code prefix (e.g. \"+55…\"), the\n * returned value preserves the leading \"+\" so callers can detect E.164 intent.\n * Otherwise only digits are returned.\n *\n * `removePhoneMask(applyPhoneMask(raw, country), country) === raw` for all\n * valid raw values that do NOT carry a country-code prefix.\n */\nexport function removePhoneMask(value: string, country: PhoneCountry): string {\n const onlyDigits = value.replace(/\\D/g, '');\n\n // Only treat as E.164 when the raw string explicitly carries a \"+\" prefix.\n // A bare digit string that starts with the country-code digits (e.g. \"1234567890\"\n // starting with \"1\") is a local number, not a country-code-prefixed one.\n if (value.startsWith('+') && isValidCountryCode(value, country)) {\n return `+${onlyDigits}`;\n }\n\n return onlyDigits;\n}\n\n/**\n * Formats `value` into the mask pattern for `country`, applying as many mask\n * characters as the digit count allows (progressive masking while typing).\n *\n * US: (123) 456-7890 or +1 (123) 456-7890\n * BR: (11) 99999-9999 or +55 (11) 99999-9999\n *\n * Non-US/BR countries fall back to the US mask.\n */\nexport function applyPhoneMask(value: string, country: PhoneCountry): string {\n switch (country) {\n case 'US':\n return applyUSPhoneMask(value);\n case 'BR':\n return applyBRPhoneMask(value);\n default:\n return applyUSPhoneMask(value);\n }\n}\n\nfunction applyUSPhoneMask(value: string): string {\n const onlyDigits = value.replace(/\\D/g, '');\n\n // E.164 with explicit \"+\" prefix and full country code\n if (value.startsWith('+1') && onlyDigits.length >= 11) {\n const local = value.replace('+1', '').replace(/\\D/g, '');\n return `+1 ${formatUSNumber(local)}`;\n }\n\n // Bare country-code prefix (e.g. \"11234567890\")\n if (onlyDigits.startsWith('1') && onlyDigits.length === 11) {\n return `+1 ${formatUSNumber(onlyDigits.substring(1))}`;\n }\n\n return formatUSNumber(onlyDigits);\n}\n\nfunction formatUSNumber(digits: string): string {\n // US local numbers cap at 10 digits — drop the overflow instead of growing the mask unbounded.\n const local = digits.slice(0, 10);\n if (local.length === 0) return '';\n if (local.length <= 3) return `(${local}`;\n if (local.length <= 6) return `(${local.slice(0, 3)}) ${local.slice(3)}`;\n return `(${local.slice(0, 3)}) ${local.slice(3, 6)}-${local.slice(6)}`;\n}\n\nfunction applyBRPhoneMask(value: string): string {\n const onlyDigits = value.replace(/\\D/g, '');\n\n // E.164 with explicit \"+55\" prefix. 12 digits is a landline (+55 + 10 local),\n // 13 is a mobile (+55 + 11 local); both strip the \"55\" country code.\n if (value.startsWith('+55') && onlyDigits.length >= 12) {\n const local = value.replace('+55', '').replace(/\\D/g, '');\n return `+55 ${formatBRNumber(local)}`;\n }\n\n // Bare country-code prefix (e.g. \"5511999998888\" mobile, \"551133334444\" landline)\n if (onlyDigits.startsWith('55') && (onlyDigits.length === 12 || onlyDigits.length === 13)) {\n return `+55 ${formatBRNumber(onlyDigits.substring(2))}`;\n }\n\n return formatBRNumber(onlyDigits);\n}\n\nfunction formatBRNumber(digits: string): string {\n // BR local numbers cap at 11 digits (mobile) — drop the overflow instead of growing the mask unbounded.\n const local = digits.slice(0, 11);\n if (local.length === 0) return '';\n if (local.length <= 2) return `(${local}`;\n if (local.length <= 6) return `(${local.slice(0, 2)}) ${local.slice(2)}`;\n // 7-10 digits: landline format (XX) XXXX-XXXX\n if (local.length <= 10) return `(${local.slice(0, 2)}) ${local.slice(2, 6)}-${local.slice(6)}`;\n // 11 digits: mobile format (XX) XXXXX-XXXX\n return `(${local.slice(0, 2)}) ${local.slice(2, 7)}-${local.slice(7)}`;\n}\n\n// ---------------------------------------------------------------------------\n// Validation\n// ---------------------------------------------------------------------------\n\n/**\n * BR local part: 10 digits is a landline; 11 digits is a mobile, which must carry the mandatory\n * ninth digit \"9\" right after the two-digit DDD (the `phone` library rule the spec's Gap-05\n * reimplements — \"11899998888\" is mobile-shaped but not a real BR number).\n */\nfunction isValidBRLocal(digits: string): boolean {\n if (digits.length === 10) return true;\n return digits.length === 11 && digits[2] === '9';\n}\n\n/**\n * Validates a raw (unmasked) phone number string for the given country.\n *\n * NOTE: The spec (KD-3) calls for using the `phone` npm library for validation.\n * The library is listed in Gap-05 as a new dependency to add when available.\n * Until that dependency is installed, this implements an equivalent\n * digit-count validation that covers all spec key-scenarios for US and BR.\n * Country-code and non-country-code inputs are both handled.\n *\n * US valid forms:\n * - 10 digits (local, e.g. \"1234567890\")\n * - 11 raw digits with country code \"1\" (e.g. \"11234567890\")\n * - E.164 \"+1\" + 10 digits (e.g. \"+11234567890\")\n *\n * BR valid forms:\n * - 10 digits (landline, e.g. \"1133334444\")\n * - 11 digits (mobile, e.g. \"11999998888\"; the ninth digit after the DDD must be \"9\")\n * - E.164 \"+55\" + 10 or 11 digits (e.g. \"+5511999998888\")\n */\nexport function validatePhoneNumber(input: string, country: PhoneCountry): boolean {\n if (!input || !input.trim()) return false;\n\n const digits = input.replace(/\\D/g, '');\n\n if (isValidCountryCode(input, country)) {\n // Country-code branch: validate digit count including the country code digits.\n if (country === 'US') {\n // \"+1\" or \"1\" prefix + exactly 10 local digits = 11 raw digits\n if (digits.length === 11) return true;\n // Fall through: could be a 10-digit local number that starts with \"1\"\n } else {\n // BR: \"+55\" or \"55\" prefix + 10 or 11 local digits = 12 or 13 raw digits\n if (digits.length === 12 || digits.length === 13) return isValidBRLocal(digits.slice(2));\n // Fall through: could be local digits that happen to start with \"55\"\n }\n }\n\n // Local (no country code) validation\n if (country === 'US') {\n return digits.length === 10;\n }\n\n return isValidBRLocal(digits);\n}\n\n/**\n * Normalizes a valid raw phone value to E.164 for persistence (legacy checkout parity): the\n * particle emits local digits (\"2015551234\") or a \"+\"-prefixed string; the profile stores\n * \"+12015551234\". Only call this on values `validatePhoneNumber` has already accepted — shared by\n * every binding that persists a phone value (`ClientProfilePhoneControl`, `ClientProfileFieldset`)\n * so there is exactly one normalization implementation.\n */\nexport function toE164(raw: string, country: PhoneCountry): string {\n const unmasked = removePhoneMask(raw, country);\n if (unmasked.startsWith('+')) return unmasked;\n const code = country === 'BR' ? '55' : '1';\n const localMax = country === 'BR' ? 11 : 10;\n // A bare country-code prefix (\"12015551234\", \"5511999998888\") only needs the \"+\".\n return unmasked.startsWith(code) && unmasked.length > localMax ? `+${unmasked}` : `+${code}${unmasked}`;\n}\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ntype PhoneFieldRequirement = 'mandatory' | 'optional';\n\nexport type PhoneFieldProps = {\n /** Controlled raw (unmasked) phone value. Unused on the bound path — react-hook-form owns the value. */\n value?: string;\n /** Uncontrolled initial raw value. Unused on the bound path — the field contract's `defaultValue` seeds it instead. */\n defaultValue?: string;\n /** Called with the raw (unmasked) value on every change. */\n onValueChange?: (value: string) => void;\n /** Selects the phone mask and validation rule. */\n country?: PhoneCountry;\n /**\n * Visible field label. No signature default (Decision 5 of the wrapped-field-particles spec) — an\n * omitted label falls back to the field contract's `label` when bound, and to `'Phone'` when not.\n */\n label?: string;\n /** Disables the field when true. Falls back to the field contract's `disabled` when bound. */\n isDisabled?: boolean;\n /** Input placeholder text. Falls back to the field contract's `placeholder` when bound. */\n placeholder?: string;\n /**\n * Externally-controlled invalid state. When provided, overrides the\n * particle's internal blur-triggered validation result.\n */\n invalid?: boolean;\n /**\n * Externally-supplied error message. When provided, overrides the\n * particle's internal error string.\n */\n error?: string;\n /** Error string shown when the input format is invalid. */\n errorInvalid?: string;\n /** Error string shown when the mandatory field is left empty. */\n errorRequired?: string;\n /**\n * Raises the field to required. It only ever raises: bound to a fieldset whose rule already says\n * required, `'optional'` does not lower it.\n *\n * - `'mandatory'`: empty input blocks submission.\n * - `'optional'`: empty input is allowed; format is still checked when a\n * value is present.\n * - unset: no opinion, so a phone with no baseline is optional.\n */\n requirement?: PhoneFieldRequirement;\n /** Called after the field loses focus (post-validation). */\n onBlur?: () => void;\n /** Additional class applied to the root element. */\n className?: string;\n /**\n * Lands on the masked `<input type=\"tel\">` the particle renders. Composed with react-hook-form's own\n * ref on the bound path — a caller ref and react-hook-form's ref are both honoured.\n */\n ref?: Ref<HTMLInputElement>;\n /**\n * Given, replaces the default `Field.Label` + `PhoneFieldInput` + `Field.Error` anatomy — any order,\n * any subset. `PhoneFieldInput` is the one part that carries the mask, the composed ref and the\n * particle's own value/handlers; a composed generic `Field.Control` would call `useController` a\n * second time for the same name (RFC's named, accepted double-binder hole).\n */\n children?: ReactNode;\n};\n\n// ---------------------------------------------------------------------------\n// Definition\n// ---------------------------------------------------------------------------\n\nexport const PhoneFieldDefinition = defineComponent<PhoneFieldProps>({\n name: 'PhoneField',\n importPath: '@vtex/faststore/components',\n component: PhoneField,\n providesContext: 'phone-field',\n editor: { label: 'Phone Field', category: 'action' },\n schema: {\n country: { type: 'string', default: 'US', label: 'Country (US or BR)' },\n label: { type: 'string', default: 'Phone', label: 'Label' },\n // No default: an unset requirement is no opinion, not a raise to mandatory.\n requirement: { type: ['mandatory', 'optional'] as const, label: 'Requirement' },\n errorInvalid: { type: 'string', default: 'Invalid phone number', label: 'Invalid error message' },\n errorRequired: { type: 'string', default: 'Phone number is required', label: 'Required error message' },\n },\n guideline:\n 'Locale-aware, business-agnostic phone number input composed from the field + input particles. Applies country masking, validates on blur, and exposes its value via onValueChange. Bind it to a data source (e.g. ClientProfilePhoneControl for checkout) to persist the value. Recomposable (RFC:503): given children, they replace the default Field.Label + PhoneFieldInput + Field.Error anatomy, in any order.',\n});\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\n/**\n * Presentational, business-agnostic phone field. Composes the `field` and `input` particles: the\n * `Field.Root` owns the invalid/disabled state and the `Field.Error match` slot, while the `Input`\n * particle renders the masked `<tel>` control. The particle stays reusable (checkout binding today,\n * MyAccount / extensions later); a binding owns the data source and persistence.\n *\n * US/BR masking, blur validation, and the `data-fs-phone-field*` attributes (plus the country variant\n * attribute) are kept; error strings remain props (a documented i18n divergence — the country tables\n * are internal, the copy is owner-supplied).\n *\n * Reads the field contract through `useField()` and `useFormContext()` and dispatches to a bound or an\n * unbound sub-component — \"bound\" means both are present. Every react-hook-form hook lives in\n * `BoundPhoneField`, so hook order never changes under a mounted component. Both sub-components render\n * the same `PhoneFieldView`, so the two paths cannot drift into different DOM.\n */\nexport function PhoneField({ requirement, ...props }: PhoneFieldProps): ReactNode {\n const contract = useField();\n const formContext = useFormContext();\n\n if (contract && formContext) {\n return <BoundPhoneField {...props} requirement={requirement} contract={contract} />;\n }\n\n return <UnboundPhoneField {...props} requirement={requirement} />;\n}\n\n// ---------------------------------------------------------------------------\n// Input part — catalogued, placeable (Decision 4). Carries the mask, the composed ref, and the\n// particle's own onChange/onBlur; a generic Field.Control cannot be this part, because the mask and\n// the country/requirement validator belong to PhoneField, not to react-hook-form's own registration.\n// ---------------------------------------------------------------------------\n\ntype PhoneFieldInputContextValue = {\n ref?: Ref<HTMLInputElement>;\n value: string;\n placeholder?: string;\n /** Resolved by the binder, threaded here because this part is not the one that binds. */\n required: boolean;\n onChange: (event: ChangeEvent<HTMLInputElement>) => void;\n onBlur: (event: FocusEvent<HTMLInputElement>) => void;\n};\n\nconst PhoneFieldInputContext = createContext<PhoneFieldInputContextValue | null>(null);\n\nfunction usePhoneFieldInputContext(): PhoneFieldInputContextValue {\n const context = useContext(PhoneFieldInputContext);\n if (!context) {\n throw new Error('PhoneFieldInput must be a descendant of PhoneField.');\n }\n return context;\n}\n\nexport type PhoneFieldInputProps = { className?: string };\n\nexport const PhoneFieldInputDefinition = defineComponent<PhoneFieldInputProps>({\n name: 'PhoneFieldInput',\n importPath: '@vtex/faststore/components',\n component: PhoneFieldInput,\n requiresContext: 'phone-field',\n editor: { label: 'Phone Field Input', category: 'action' },\n schema: {},\n guideline:\n \"The masked <input type=\\\"tel\\\"> PhoneField owns. Must sit inside PhoneField, in either the default anatomy or an author's composed children. Carries the country mask, the composed ref, and PhoneField's own onChange/onBlur — a composed Field.Control here instead re-registers the field with react-hook-form and loses the mask (unsupported, RFC's named double-binder hole).\",\n});\n\n/** Renders the masked `<input>`, reading its value/handlers/ref from the enclosing `PhoneField`. */\nexport function PhoneFieldInput({ className }: PhoneFieldInputProps): ReactNode {\n const { ref, value, placeholder, required, onChange, onBlur } = usePhoneFieldInputContext();\n\n return (\n <Input\n ref={ref}\n data-fs-phone-field-input=\"\"\n type=\"tel\"\n inputMode=\"numeric\"\n // `aria-required`, not native `required`, for the reason password-field.tsx:89-91 records:\n // `Input` is a Base UI `Field.Control`, and native constraint tracking would flip\n // `aria-invalid` on its own, ahead of react-hook-form's own validation.\n aria-required={required || undefined}\n value={value}\n onChange={onChange}\n onBlur={onBlur}\n placeholder={placeholder}\n className={className}\n />\n );\n}\n\n// ---------------------------------------------------------------------------\n// Shared view — identical DOM whether bound or unbound\n// ---------------------------------------------------------------------------\n\ntype PhoneFieldViewProps = {\n ref?: Ref<HTMLInputElement>;\n country: PhoneCountry;\n className?: string;\n label: string;\n isDisabled: boolean;\n placeholder?: string;\n required: boolean;\n maskedValue: string;\n effectiveInvalid: boolean;\n effectiveError: string;\n onChange: (event: ChangeEvent<HTMLInputElement>) => void;\n onBlur: (event: FocusEvent<HTMLInputElement>) => void;\n children?: ReactNode;\n};\n\nfunction PhoneFieldView({\n ref,\n country,\n className,\n label,\n isDisabled,\n placeholder,\n required,\n maskedValue,\n effectiveInvalid,\n effectiveError,\n onChange,\n onBlur,\n children,\n}: PhoneFieldViewProps) {\n const inputContext = useMemo<PhoneFieldInputContextValue>(\n () => ({ ref, value: maskedValue, placeholder, required, onChange, onBlur }),\n [ref, maskedValue, placeholder, required, onChange, onBlur],\n );\n\n return (\n // Deliberately the RAW Base UI Field primitives, not this package's own Field.Root/Label/Error\n // wrapper, for the default anatomy: this reproduces exactly what rendered before Decision 3\n // (when FieldContractBoundary shielded this subtree from the ambient contract) — the resolved\n // `label`/`effectiveError` text renders unconditionally, and Field.Root's own dirty/touched\n // fallback tracking stays in charge, rather than react-hook-form's. Composed children, below,\n // use the package's own Field.* parts on purpose — that is what makes a childless Field.Label /\n // Field.Error resolve real text (FR-5).\n <BaseField.Root\n data-fs-phone-field-root=\"\"\n data-fs-phone-field-root-country={country}\n data-fs-field-root=\"\"\n className={className}\n invalid={effectiveInvalid}\n disabled={isDisabled}\n >\n <PhoneFieldInputContext.Provider value={inputContext}>\n {children ?? (\n <>\n <BaseField.Label data-fs-phone-field-label=\"\" data-fs-field-label=\"\">\n {label}\n </BaseField.Label>\n <PhoneFieldInput />\n {effectiveError ? (\n <BaseField.Error match data-fs-phone-field-error=\"\" data-fs-field-error=\"\">\n {effectiveError}\n </BaseField.Error>\n ) : null}\n </>\n )}\n </PhoneFieldInputContext.Provider>\n </BaseField.Root>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Unbound — today's body, moved verbatim\n// ---------------------------------------------------------------------------\n\ntype UnboundPhoneFieldProps = PhoneFieldProps;\n\nfunction UnboundPhoneField({\n value,\n defaultValue = '',\n onValueChange,\n country = 'US',\n label,\n isDisabled = false,\n placeholder,\n invalid,\n error,\n errorInvalid = 'Invalid phone number',\n errorRequired = 'Phone number is required',\n requirement,\n onBlur,\n className,\n ref,\n children,\n}: UnboundPhoneFieldProps) {\n const isControlled = value !== undefined;\n\n const [internalRaw, setInternalRaw] = useState(defaultValue);\n const [localInvalid, setLocalInvalid] = useState(false);\n const [localError, setLocalError] = useState('');\n\n // Clear local validation state when country changes so the next blur re-validates against the new\n // country's rules. The comparison baseline lives in state, not a ref, and the compare-and-set runs\n // during render (before paint), so a render React abandons without committing — a suspended\n // transition, a Suspense retry — never leaves a stale baseline behind the way a ref write would.\n const [prevCountry, setPrevCountry] = useState(country);\n if (prevCountry !== country) {\n setPrevCountry(country);\n setLocalInvalid(false);\n setLocalError('');\n }\n\n const rawValue = isControlled ? (value as string) : internalRaw;\n const maskedValue = applyPhoneMask(rawValue, country);\n const resolvedLabel = label ?? 'Phone';\n\n // External props take precedence over internal validation state.\n // When `invalid` is externally controlled, the error display is also fully\n // controlled: use the explicit `error` prop, or fall back to empty string so\n // no stale local error leaks through when the parent says the field is valid.\n const effectiveInvalid = invalid !== undefined ? invalid : localInvalid;\n const effectiveError = error !== undefined ? error : effectiveInvalid ? localError : '';\n\n function handleChange(event: ChangeEvent<HTMLInputElement>) {\n if (isDisabled) return;\n const raw = removePhoneMask(event.target.value, country);\n if (!isControlled) {\n setInternalRaw(raw);\n }\n onValueChange?.(raw);\n }\n\n function handleBlur(_event: FocusEvent<HTMLInputElement>) {\n if (isDisabled) return;\n\n let isFieldInvalid = false;\n let fieldError = '';\n\n if (requirement === 'mandatory' && !rawValue.trim()) {\n isFieldInvalid = true;\n fieldError = errorRequired;\n } else if (rawValue.trim()) {\n const valid = validatePhoneNumber(rawValue, country);\n isFieldInvalid = !valid;\n fieldError = valid ? '' : errorInvalid;\n }\n // optional + empty → no error, keep isFieldInvalid = false / fieldError = ''\n\n setLocalInvalid(isFieldInvalid);\n setLocalError(fieldError);\n onBlur?.();\n }\n\n return (\n <PhoneFieldView\n ref={ref}\n country={country}\n className={className}\n label={resolvedLabel}\n isDisabled={isDisabled}\n placeholder={placeholder}\n required={requirement === 'mandatory'}\n maskedValue={maskedValue}\n effectiveInvalid={effectiveInvalid}\n effectiveError={effectiveError}\n onChange={handleChange}\n onBlur={handleBlur}\n >\n {children}\n </PhoneFieldView>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Bound — reads the field contract, binds through useController\n// ---------------------------------------------------------------------------\n\ntype BoundPhoneFieldProps = UnboundPhoneFieldProps & { contract: FieldContract };\n\nfunction BoundPhoneField({\n value: _value,\n defaultValue: _defaultValue,\n onValueChange,\n country = 'US',\n label,\n isDisabled,\n placeholder,\n invalid,\n error,\n errorInvalid = 'Invalid phone number',\n errorRequired = 'Phone number is required',\n requirement,\n onBlur,\n className,\n ref: callerRef,\n contract,\n children,\n}: BoundPhoneFieldProps) {\n // Format only. Requiredness is not decided here: `useBoundField` resolves it from the fieldset's\n // baseline and the raise below, and installs the blank check, so the announcement and the\n // validation cannot disagree. The check composes alongside whatever the fieldset validates —\n // before this merge, any contract validator discarded the particle's own validation whole.\n const rule = useMemo<FieldRule>(\n () =>\n mergeFieldValidator(contract.rule, 'phoneFormat', (rawValue) => {\n const raw = typeof rawValue === 'string' ? rawValue : String(rawValue ?? '');\n return !raw.trim() || validatePhoneNumber(raw, country) || errorInvalid;\n }),\n [contract.rule, errorInvalid, country],\n );\n\n const field = useBoundField(contract, TEXT_FIELD_VALUE, rule, {\n required: requirement === 'mandatory',\n message: errorRequired,\n });\n const { getFieldState } = useFormContext();\n const { invalid: rhfInvalid, error: rhfError } = getFieldState(contract.name, useFormState({ name: contract.name }));\n\n const composedRef = useComposedRef<HTMLInputElement>(callerRef, field.ref);\n\n const rawValue = typeof field.value === 'string' ? field.value : String(field.value ?? '');\n const maskedValue = applyPhoneMask(rawValue, country);\n const resolvedLabel = label ?? contract.label ?? 'Phone';\n const resolvedPlaceholder = placeholder ?? contract.placeholder;\n const resolvedIsDisabled = isDisabled ?? contract.disabled ?? false;\n\n const effectiveInvalid = invalid !== undefined ? invalid : rhfInvalid;\n const effectiveError = error !== undefined ? error : effectiveInvalid ? (rhfError?.message ?? '') : '';\n\n function handleChange(event: ChangeEvent<HTMLInputElement>) {\n const raw = removePhoneMask(event.target.value, country);\n field.onChange(raw);\n onValueChange?.(raw);\n }\n\n function handleBlur(_event: FocusEvent<HTMLInputElement>) {\n field.onBlur();\n onBlur?.();\n }\n\n return (\n // Decision 3: replaces the empty-contract FieldContractBoundary with a re-provided contract\n // carrying the RESOLVED name/label/placeholder — the values a composed childless Field.Label /\n // Field.Error actually need, as opposed to the raw (possibly-undefined) ones the ambient\n // contract from the enclosing FieldBinding carries. useBoundField above remains the sole binder\n // for contract.name; this FieldBinding never registers anything itself.\n <FieldBinding\n name={contract.name}\n label={resolvedLabel}\n placeholder={resolvedPlaceholder}\n defaultValue={contract.defaultValue}\n rule={contract.rule}\n options={contract.options}\n disabled={resolvedIsDisabled}\n readOnly={contract.readOnly}\n autoComplete={contract.autoComplete}\n inputMode={contract.inputMode}\n >\n <PhoneFieldView\n ref={composedRef}\n country={country}\n className={className}\n label={resolvedLabel}\n isDisabled={resolvedIsDisabled}\n placeholder={resolvedPlaceholder}\n required={field.required}\n maskedValue={maskedValue}\n effectiveInvalid={effectiveInvalid}\n effectiveError={effectiveError}\n onChange={handleChange}\n onBlur={handleBlur}\n >\n {children}\n </PhoneFieldView>\n </FieldBinding>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"phone-field.js","names":["BaseField"],"sources":["../../../src/particles/phone-field/phone-field.tsx"],"sourcesContent":["'use client';\nimport { Field as BaseField } from '@base-ui/react/field';\nimport { defineComponent } from '@vtex/fs-core';\nimport type { ChangeEvent, FocusEvent, ReactNode, Ref } from 'react';\nimport { createContext, useContext, useMemo, useState } from 'react';\nimport { useFormContext, useFormState } from 'react-hook-form';\nimport {\n FieldBinding,\n type FieldContract,\n type FieldRule,\n mergeFieldValidator,\n TEXT_FIELD_VALUE,\n useBoundField,\n useField,\n} from '../field/field.js';\nimport { Input } from '../input/input.js';\nimport { useComposedRef } from '../shared/compose-refs.js';\n\n// ---------------------------------------------------------------------------\n// Country masks\n// ---------------------------------------------------------------------------\n\n/**\n * Country codes supported by PhoneField.\n * Only US and BR are implemented; every other ISO-2 code falls back to the US\n * format (Gap-06 in the PhoneField spec).\n */\nexport type PhoneCountry = 'US' | 'BR';\n\n/**\n * Returns true when `value` starts with the E.164 or bare country-code prefix\n * for the given country.\n *\n * US country code: 1 → \"+1…\" or \"1…\"\n * BR country code: 55 → \"+55…\" or \"55…\"\n */\nfunction isValidCountryCode(value: string, country: PhoneCountry): boolean {\n switch (country) {\n case 'US':\n return value.startsWith('+1') || value.startsWith('1');\n case 'BR':\n return value.startsWith('+55') || value.startsWith('55');\n default:\n return false;\n }\n}\n\n/**\n * Strips phone mask formatting from `value`.\n *\n * When the raw string carries a valid country-code prefix (e.g. \"+55…\"), the\n * returned value preserves the leading \"+\" so callers can detect E.164 intent.\n * Otherwise only digits are returned.\n *\n * `removePhoneMask(applyPhoneMask(raw, country), country) === raw` for all\n * valid raw values that do NOT carry a country-code prefix.\n */\nexport function removePhoneMask(value: string, country: PhoneCountry): string {\n const onlyDigits = value.replace(/\\D/g, '');\n\n // Only treat as E.164 when the raw string explicitly carries a \"+\" prefix.\n // A bare digit string that starts with the country-code digits (e.g. \"1234567890\"\n // starting with \"1\") is a local number, not a country-code-prefixed one.\n if (value.startsWith('+') && isValidCountryCode(value, country)) {\n return `+${onlyDigits}`;\n }\n\n return onlyDigits;\n}\n\n/**\n * Formats `value` into the mask pattern for `country`, applying as many mask\n * characters as the digit count allows (progressive masking while typing).\n *\n * US: (123) 456-7890 or +1 (123) 456-7890\n * BR: (11) 99999-9999 or +55 (11) 99999-9999\n *\n * Non-US/BR countries fall back to the US mask.\n */\nexport function applyPhoneMask(value: string, country: PhoneCountry): string {\n switch (country) {\n case 'US':\n return applyUSPhoneMask(value);\n case 'BR':\n return applyBRPhoneMask(value);\n default:\n return applyUSPhoneMask(value);\n }\n}\n\nfunction applyUSPhoneMask(value: string): string {\n const onlyDigits = value.replace(/\\D/g, '');\n\n // E.164 with explicit \"+\" prefix and full country code\n if (value.startsWith('+1') && onlyDigits.length >= 11) {\n const local = value.replace('+1', '').replace(/\\D/g, '');\n return `+1 ${formatUSNumber(local)}`;\n }\n\n // Bare country-code prefix (e.g. \"11234567890\")\n if (onlyDigits.startsWith('1') && onlyDigits.length === 11) {\n return `+1 ${formatUSNumber(onlyDigits.substring(1))}`;\n }\n\n return formatUSNumber(onlyDigits);\n}\n\nfunction formatUSNumber(digits: string): string {\n // US local numbers cap at 10 digits — drop the overflow instead of growing the mask unbounded.\n const local = digits.slice(0, 10);\n if (local.length === 0) return '';\n if (local.length <= 3) return `(${local}`;\n if (local.length <= 6) return `(${local.slice(0, 3)}) ${local.slice(3)}`;\n return `(${local.slice(0, 3)}) ${local.slice(3, 6)}-${local.slice(6)}`;\n}\n\nfunction applyBRPhoneMask(value: string): string {\n const onlyDigits = value.replace(/\\D/g, '');\n\n // E.164 with explicit \"+55\" prefix. 12 digits is a landline (+55 + 10 local),\n // 13 is a mobile (+55 + 11 local); both strip the \"55\" country code.\n if (value.startsWith('+55') && onlyDigits.length >= 12) {\n const local = value.replace('+55', '').replace(/\\D/g, '');\n return `+55 ${formatBRNumber(local)}`;\n }\n\n // Bare country-code prefix (e.g. \"5511999998888\" mobile, \"551133334444\" landline)\n if (onlyDigits.startsWith('55') && (onlyDigits.length === 12 || onlyDigits.length === 13)) {\n return `+55 ${formatBRNumber(onlyDigits.substring(2))}`;\n }\n\n return formatBRNumber(onlyDigits);\n}\n\nfunction formatBRNumber(digits: string): string {\n // BR local numbers cap at 11 digits (mobile) — drop the overflow instead of growing the mask unbounded.\n const local = digits.slice(0, 11);\n if (local.length === 0) return '';\n if (local.length <= 2) return `(${local}`;\n if (local.length <= 6) return `(${local.slice(0, 2)}) ${local.slice(2)}`;\n // 7-10 digits: landline format (XX) XXXX-XXXX\n if (local.length <= 10) return `(${local.slice(0, 2)}) ${local.slice(2, 6)}-${local.slice(6)}`;\n // 11 digits: mobile format (XX) XXXXX-XXXX\n return `(${local.slice(0, 2)}) ${local.slice(2, 7)}-${local.slice(7)}`;\n}\n\n// ---------------------------------------------------------------------------\n// Validation\n// ---------------------------------------------------------------------------\n\n/**\n * BR local part: 10 digits is a landline; 11 digits is a mobile, which must carry the mandatory\n * ninth digit \"9\" right after the two-digit DDD (the `phone` library rule the spec's Gap-05\n * reimplements — \"11899998888\" is mobile-shaped but not a real BR number).\n */\nfunction isValidBRLocal(digits: string): boolean {\n if (digits.length === 10) return true;\n return digits.length === 11 && digits[2] === '9';\n}\n\n/**\n * Validates a raw (unmasked) phone number string for the given country.\n *\n * NOTE: The spec (KD-3) calls for using the `phone` npm library for validation.\n * The library is listed in Gap-05 as a new dependency to add when available.\n * Until that dependency is installed, this implements an equivalent\n * digit-count validation that covers all spec key-scenarios for US and BR.\n * Country-code and non-country-code inputs are both handled.\n *\n * US valid forms:\n * - 10 digits (local, e.g. \"1234567890\")\n * - 11 raw digits with country code \"1\" (e.g. \"11234567890\")\n * - E.164 \"+1\" + 10 digits (e.g. \"+11234567890\")\n *\n * BR valid forms:\n * - 10 digits (landline, e.g. \"1133334444\")\n * - 11 digits (mobile, e.g. \"11999998888\"; the ninth digit after the DDD must be \"9\")\n * - E.164 \"+55\" + 10 or 11 digits (e.g. \"+5511999998888\")\n */\nexport function validatePhoneNumber(input: string, country: PhoneCountry): boolean {\n if (!input || !input.trim()) return false;\n\n const digits = input.replace(/\\D/g, '');\n\n if (isValidCountryCode(input, country)) {\n // Country-code branch: validate digit count including the country code digits.\n if (country === 'US') {\n // \"+1\" or \"1\" prefix + exactly 10 local digits = 11 raw digits\n if (digits.length === 11) return true;\n // Fall through: could be a 10-digit local number that starts with \"1\"\n } else {\n // BR: \"+55\" or \"55\" prefix + 10 or 11 local digits = 12 or 13 raw digits\n if (digits.length === 12 || digits.length === 13) return isValidBRLocal(digits.slice(2));\n // Fall through: could be local digits that happen to start with \"55\"\n }\n }\n\n // Local (no country code) validation\n if (country === 'US') {\n return digits.length === 10;\n }\n\n return isValidBRLocal(digits);\n}\n\n/**\n * Normalizes a valid raw phone value to E.164 for persistence (legacy checkout parity): the\n * particle emits local digits (\"2015551234\") or a \"+\"-prefixed string; the profile stores\n * \"+12015551234\". Only call this on values `validatePhoneNumber` has already accepted — shared by\n * every binding that persists a phone value (`ClientProfilePhoneControl`, `ClientProfileFieldset`)\n * so there is exactly one normalization implementation.\n */\nexport function toE164(raw: string, country: PhoneCountry): string {\n const unmasked = removePhoneMask(raw, country);\n if (unmasked.startsWith('+')) return unmasked;\n const code = country === 'BR' ? '55' : '1';\n const localMax = country === 'BR' ? 11 : 10;\n // A bare country-code prefix (\"12015551234\", \"5511999998888\") only needs the \"+\".\n return unmasked.startsWith(code) && unmasked.length > localMax ? `+${unmasked}` : `+${code}${unmasked}`;\n}\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ntype PhoneFieldRequirement = 'mandatory' | 'optional';\n\nexport type PhoneFieldProps = {\n /** Controlled raw (unmasked) phone value. Unused on the bound path — react-hook-form owns the value. */\n value?: string;\n /** Uncontrolled initial raw value. Unused on the bound path — the field contract's `defaultValue` seeds it instead. */\n defaultValue?: string;\n /** Called with the raw (unmasked) value on every change. */\n onValueChange?: (value: string) => void;\n /** Selects the phone mask and validation rule. */\n country?: PhoneCountry;\n /**\n * Visible field label. No signature default (Decision 5 of the wrapped-field-particles spec) — an\n * omitted label falls back to the field contract's `label` when bound, and to `'Phone'` when not.\n */\n label?: string;\n /** Disables the field when true. Falls back to the field contract's `disabled` when bound. */\n isDisabled?: boolean;\n /** Input placeholder text. Falls back to the field contract's `placeholder` when bound. */\n placeholder?: string;\n /**\n * Externally-controlled invalid state. When provided, overrides the\n * particle's internal blur-triggered validation result.\n */\n invalid?: boolean;\n /**\n * Externally-supplied error message. When provided, overrides the\n * particle's internal error string.\n */\n error?: string;\n /** Error string shown when the input format is invalid. */\n errorInvalid?: string;\n /** Error string shown when the mandatory field is left empty. */\n errorRequired?: string;\n /**\n * Raises the field to required. It only ever raises: bound to a fieldset whose rule already says\n * required, `'optional'` does not lower it.\n *\n * - `'mandatory'`: empty input blocks submission.\n * - `'optional'`: empty input is allowed; format is still checked when a\n * value is present.\n * - unset: no opinion, so a phone with no baseline is optional.\n */\n requirement?: PhoneFieldRequirement;\n /** Called after the field loses focus (post-validation). */\n onBlur?: () => void;\n /** Additional class applied to the root element. */\n className?: string;\n /**\n * Lands on the masked `<input type=\"tel\">` the particle renders. Composed with react-hook-form's own\n * ref on the bound path — a caller ref and react-hook-form's ref are both honoured.\n */\n ref?: Ref<HTMLInputElement>;\n /**\n * Given, replaces the default `Field.Label` + `PhoneFieldInput` + `Field.Error` anatomy — any order,\n * any subset. `PhoneFieldInput` is the one part that carries the mask, the composed ref and the\n * particle's own value/handlers; a composed generic `Field.Control` would call `useController` a\n * second time for the same name (RFC's named, accepted double-binder hole).\n */\n children?: ReactNode;\n};\n\n// ---------------------------------------------------------------------------\n// Definition\n// ---------------------------------------------------------------------------\n\nexport const PhoneFieldDefinition = defineComponent<PhoneFieldProps>({\n name: 'PhoneField',\n importPath: '@vtex/faststore/components',\n component: PhoneField,\n providesContext: 'phone-field',\n editor: { label: 'Phone Field', category: 'action' },\n schema: {\n country: { type: 'string', default: 'US', label: 'Country (US or BR)' },\n label: { type: 'string', default: 'Phone', label: 'Label' },\n // No default: an unset requirement is no opinion, not a raise to mandatory.\n requirement: { type: ['mandatory', 'optional'] as const, label: 'Requirement' },\n errorInvalid: { type: 'string', default: 'Invalid phone number', label: 'Invalid error message' },\n errorRequired: { type: 'string', default: 'Phone number is required', label: 'Required error message' },\n },\n guideline:\n 'Locale-aware, business-agnostic phone number input composed from the field + input particles. Applies country masking, validates on blur, and exposes its value via onValueChange. Bind it to a data source (e.g. ClientProfilePhoneControl for checkout) to persist the value. Recomposable (RFC:503): given children, they replace the default Field.Label + PhoneFieldInput + Field.Error anatomy, in any order.',\n});\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\n/**\n * Presentational, business-agnostic phone field. Composes the `field` and `input` particles: the\n * `Field.Root` owns the invalid/disabled state and the `Field.Error match` slot, while the `Input`\n * particle renders the masked `<tel>` control. The particle stays reusable (checkout binding today,\n * MyAccount / extensions later); a binding owns the data source and persistence.\n *\n * US/BR masking, blur validation, and the `data-fs-phone-field*` attributes (plus the country variant\n * attribute) are kept; error strings remain props (a documented i18n divergence — the country tables\n * are internal, the copy is owner-supplied).\n *\n * Reads the field contract through `useField()` and `useFormContext()` and dispatches to a bound or an\n * unbound sub-component — \"bound\" means both are present. Every react-hook-form hook lives in\n * `BoundPhoneField`, so hook order never changes under a mounted component. Both sub-components render\n * the same `PhoneFieldView`, so the two paths cannot drift into different DOM.\n */\nexport function PhoneField({ requirement, ...props }: PhoneFieldProps): ReactNode {\n const contract = useField();\n const formContext = useFormContext();\n\n if (contract && formContext) {\n return <BoundPhoneField {...props} requirement={requirement} contract={contract} />;\n }\n\n return <UnboundPhoneField {...props} requirement={requirement} />;\n}\n\n// ---------------------------------------------------------------------------\n// Input part — catalogued, placeable (Decision 4). Carries the mask, the composed ref, and the\n// particle's own onChange/onBlur; a generic Field.Control cannot be this part, because the mask and\n// the country/requirement validator belong to PhoneField, not to react-hook-form's own registration.\n// ---------------------------------------------------------------------------\n\ntype PhoneFieldInputContextValue = {\n ref?: Ref<HTMLInputElement>;\n value: string;\n placeholder?: string;\n /** Resolved by the binder, threaded here because this part is not the one that binds. */\n required: boolean;\n onChange: (event: ChangeEvent<HTMLInputElement>) => void;\n onBlur: (event: FocusEvent<HTMLInputElement>) => void;\n};\n\nconst PhoneFieldInputContext = createContext<PhoneFieldInputContextValue | null>(null);\n\nfunction usePhoneFieldInputContext(): PhoneFieldInputContextValue {\n const context = useContext(PhoneFieldInputContext);\n if (!context) {\n throw new Error('PhoneFieldInput must be a descendant of PhoneField.');\n }\n return context;\n}\n\nexport type PhoneFieldInputProps = { className?: string };\n\nexport const PhoneFieldInputDefinition = defineComponent<PhoneFieldInputProps>({\n name: 'PhoneFieldInput',\n importPath: '@vtex/faststore/components',\n component: PhoneFieldInput,\n requiresContext: 'phone-field',\n editor: { label: 'Phone Field Input', category: 'action' },\n schema: {},\n guideline:\n \"The masked <input type=\\\"tel\\\"> PhoneField owns. Must sit inside PhoneField, in either the default anatomy or an author's composed children. Carries the country mask, the composed ref, and PhoneField's own onChange/onBlur — a composed Field.Control here instead re-registers the field with react-hook-form and loses the mask (unsupported, RFC's named double-binder hole).\",\n});\n\n/** Renders the masked `<input>`, reading its value/handlers/ref from the enclosing `PhoneField`. */\nexport function PhoneFieldInput({ className }: PhoneFieldInputProps): ReactNode {\n const { ref, value, placeholder, required, onChange, onBlur } = usePhoneFieldInputContext();\n\n return (\n <Input\n ref={ref}\n data-fs-phone-field-input=\"\"\n type=\"tel\"\n inputMode=\"numeric\"\n // `aria-required`, not native `required`, for the reason password-field.tsx:89-91 records:\n // `Input` is a Base UI `Field.Control`, and native constraint tracking would flip\n // `aria-invalid` on its own, ahead of react-hook-form's own validation.\n aria-required={required || undefined}\n value={value}\n onChange={onChange}\n onBlur={onBlur}\n placeholder={placeholder}\n className={className}\n />\n );\n}\n\n// ---------------------------------------------------------------------------\n// Shared view — identical DOM whether bound or unbound\n// ---------------------------------------------------------------------------\n\ntype PhoneFieldViewProps = {\n ref?: Ref<HTMLInputElement>;\n country: PhoneCountry;\n className?: string;\n label: string;\n isDisabled: boolean;\n placeholder?: string;\n required: boolean;\n maskedValue: string;\n effectiveInvalid: boolean;\n effectiveError: string;\n onChange: (event: ChangeEvent<HTMLInputElement>) => void;\n onBlur: (event: FocusEvent<HTMLInputElement>) => void;\n children?: ReactNode;\n};\n\nfunction PhoneFieldView({\n ref,\n country,\n className,\n label,\n isDisabled,\n placeholder,\n required,\n maskedValue,\n effectiveInvalid,\n effectiveError,\n onChange,\n onBlur,\n children,\n}: PhoneFieldViewProps) {\n const inputContext = useMemo<PhoneFieldInputContextValue>(\n () => ({ ref, value: maskedValue, placeholder, required, onChange, onBlur }),\n [ref, maskedValue, placeholder, required, onChange, onBlur],\n );\n\n return (\n // Deliberately the RAW Base UI Field primitives, not this package's own Field.Root/Label/Error\n // wrapper, for the default anatomy: this reproduces exactly what rendered before Decision 3\n // (when FieldContractBoundary shielded this subtree from the ambient contract) — the resolved\n // `label`/`effectiveError` text renders unconditionally, and Field.Root's own dirty/touched\n // fallback tracking stays in charge, rather than react-hook-form's. Composed children, below,\n // use the package's own Field.* parts on purpose — that is what makes a childless Field.Label /\n // Field.Error resolve real text (FR-5).\n <BaseField.Root\n data-fs-phone-field-root=\"\"\n data-fs-phone-field-root-country={country}\n data-fs-field-root=\"\"\n className={className}\n invalid={effectiveInvalid}\n disabled={isDisabled}\n >\n <PhoneFieldInputContext.Provider value={inputContext}>\n {children ?? (\n <>\n <BaseField.Label data-fs-phone-field-label=\"\" data-fs-field-label=\"\">\n {label}\n </BaseField.Label>\n <PhoneFieldInput />\n {effectiveError ? (\n <BaseField.Error match data-fs-phone-field-error=\"\" data-fs-field-error=\"\">\n {effectiveError}\n </BaseField.Error>\n ) : null}\n </>\n )}\n </PhoneFieldInputContext.Provider>\n </BaseField.Root>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Unbound — today's body, moved verbatim\n// ---------------------------------------------------------------------------\n\ntype UnboundPhoneFieldProps = PhoneFieldProps;\n\nfunction UnboundPhoneField({\n value,\n defaultValue = '',\n onValueChange,\n country = 'US',\n label,\n isDisabled = false,\n placeholder,\n invalid,\n error,\n errorInvalid = 'Invalid phone number',\n errorRequired = 'Phone number is required',\n requirement,\n onBlur,\n className,\n ref,\n children,\n}: UnboundPhoneFieldProps) {\n const isControlled = value !== undefined;\n\n const [internalRaw, setInternalRaw] = useState(defaultValue);\n const [localInvalid, setLocalInvalid] = useState(false);\n const [localError, setLocalError] = useState('');\n\n // Clear local validation state when country changes so the next blur re-validates against the new\n // country's rules. The comparison baseline lives in state, not a ref, and the compare-and-set runs\n // during render (before paint), so a render React abandons without committing — a suspended\n // transition, a Suspense retry — never leaves a stale baseline behind the way a ref write would.\n const [prevCountry, setPrevCountry] = useState(country);\n if (prevCountry !== country) {\n setPrevCountry(country);\n setLocalInvalid(false);\n setLocalError('');\n }\n\n const rawValue = isControlled ? (value as string) : internalRaw;\n const maskedValue = applyPhoneMask(rawValue, country);\n const resolvedLabel = label ?? 'Phone';\n\n // External props take precedence over internal validation state.\n // When `invalid` is externally controlled, the error display is also fully\n // controlled: use the explicit `error` prop, or fall back to empty string so\n // no stale local error leaks through when the parent says the field is valid.\n const effectiveInvalid = invalid !== undefined ? invalid : localInvalid;\n const effectiveError = error !== undefined ? error : effectiveInvalid ? localError : '';\n\n function handleChange(event: ChangeEvent<HTMLInputElement>) {\n if (isDisabled) return;\n const raw = removePhoneMask(event.target.value, country);\n if (!isControlled) {\n setInternalRaw(raw);\n }\n onValueChange?.(raw);\n }\n\n function handleBlur(_event: FocusEvent<HTMLInputElement>) {\n if (isDisabled) return;\n\n let isFieldInvalid = false;\n let fieldError = '';\n\n if (requirement === 'mandatory' && !rawValue.trim()) {\n isFieldInvalid = true;\n fieldError = errorRequired;\n } else if (rawValue.trim()) {\n const valid = validatePhoneNumber(rawValue, country);\n isFieldInvalid = !valid;\n fieldError = valid ? '' : errorInvalid;\n }\n // optional + empty → no error, keep isFieldInvalid = false / fieldError = ''\n\n setLocalInvalid(isFieldInvalid);\n setLocalError(fieldError);\n onBlur?.();\n }\n\n return (\n <PhoneFieldView\n ref={ref}\n country={country}\n className={className}\n label={resolvedLabel}\n isDisabled={isDisabled}\n placeholder={placeholder}\n required={requirement === 'mandatory'}\n maskedValue={maskedValue}\n effectiveInvalid={effectiveInvalid}\n effectiveError={effectiveError}\n onChange={handleChange}\n onBlur={handleBlur}\n >\n {children}\n </PhoneFieldView>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Bound — reads the field contract, binds through useController\n// ---------------------------------------------------------------------------\n\ntype BoundPhoneFieldProps = UnboundPhoneFieldProps & { contract: FieldContract };\n\nfunction BoundPhoneField({\n value: _value,\n defaultValue: _defaultValue,\n onValueChange,\n country = 'US',\n label,\n isDisabled,\n placeholder,\n invalid,\n error,\n errorInvalid = 'Invalid phone number',\n errorRequired = 'Phone number is required',\n requirement,\n onBlur,\n className,\n ref: callerRef,\n contract,\n children,\n}: BoundPhoneFieldProps) {\n // Format only. Requiredness is not decided here: `useBoundField` resolves it from the fieldset's\n // baseline and the raise below, and installs the blank check, so the announcement and the\n // validation cannot disagree. The check composes alongside whatever the fieldset validates —\n // before this merge, any contract validator discarded the particle's own validation whole.\n const rule = useMemo<FieldRule>(\n () =>\n mergeFieldValidator(contract.rule, 'phoneFormat', (rawValue) => {\n const raw = typeof rawValue === 'string' ? rawValue : String(rawValue ?? '');\n return !raw.trim() || validatePhoneNumber(raw, country) || errorInvalid;\n }),\n [contract.rule, errorInvalid, country],\n );\n\n const field = useBoundField(contract, TEXT_FIELD_VALUE, rule, {\n required: requirement === 'mandatory',\n message: errorRequired,\n });\n const { getFieldState } = useFormContext();\n const { invalid: rhfInvalid, error: rhfError } = getFieldState(contract.name, useFormState({ name: contract.name }));\n\n const composedRef = useComposedRef<HTMLInputElement>(callerRef, field.ref);\n\n const rawValue = typeof field.value === 'string' ? field.value : String(field.value ?? '');\n const maskedValue = applyPhoneMask(rawValue, country);\n const resolvedLabel = label ?? contract.label ?? 'Phone';\n const resolvedPlaceholder = placeholder ?? contract.placeholder;\n const resolvedIsDisabled = isDisabled ?? contract.disabled ?? false;\n\n const effectiveInvalid = invalid !== undefined ? invalid : rhfInvalid;\n const effectiveError = error !== undefined ? error : effectiveInvalid ? (rhfError?.message ?? '') : '';\n\n function handleChange(event: ChangeEvent<HTMLInputElement>) {\n const raw = removePhoneMask(event.target.value, country);\n field.onChange(raw);\n onValueChange?.(raw);\n }\n\n function handleBlur(_event: FocusEvent<HTMLInputElement>) {\n field.onBlur();\n onBlur?.();\n }\n\n return (\n // Decision 3: replaces the empty-contract FieldContractBoundary with a re-provided contract\n // carrying the RESOLVED name/label/placeholder — the values a composed childless Field.Label /\n // Field.Error actually need, as opposed to the raw (possibly-undefined) ones the ambient\n // contract from the enclosing FieldBinding carries. useBoundField above remains the sole binder\n // for contract.name; this FieldBinding never registers anything itself.\n <FieldBinding\n name={contract.name}\n label={resolvedLabel}\n placeholder={resolvedPlaceholder}\n defaultValue={contract.defaultValue}\n rule={contract.rule}\n options={contract.options}\n disabled={resolvedIsDisabled}\n readOnly={contract.readOnly}\n autoComplete={contract.autoComplete}\n inputMode={contract.inputMode}\n >\n <PhoneFieldView\n ref={composedRef}\n country={country}\n className={className}\n label={resolvedLabel}\n isDisabled={resolvedIsDisabled}\n placeholder={resolvedPlaceholder}\n required={field.required}\n maskedValue={maskedValue}\n effectiveInvalid={effectiveInvalid}\n effectiveError={effectiveError}\n onChange={handleChange}\n onBlur={handleBlur}\n >\n {children}\n </PhoneFieldView>\n </FieldBinding>\n );\n}\n"],"mappings":"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"}
|
|
@@ -131,7 +131,7 @@ const SelectPositionerDefinition = defineComponent({
|
|
|
131
131
|
"center",
|
|
132
132
|
"end"
|
|
133
133
|
],
|
|
134
|
-
default: "
|
|
134
|
+
default: "start",
|
|
135
135
|
label: "Align"
|
|
136
136
|
},
|
|
137
137
|
sideOffset: {
|
|
@@ -141,11 +141,11 @@ const SelectPositionerDefinition = defineComponent({
|
|
|
141
141
|
},
|
|
142
142
|
alignItemWithTrigger: {
|
|
143
143
|
type: "boolean",
|
|
144
|
-
default:
|
|
144
|
+
default: false,
|
|
145
145
|
label: "Align Item With Trigger"
|
|
146
146
|
}
|
|
147
147
|
},
|
|
148
|
-
guideline: "Positions the popup relative to the trigger. Use side and align to control placement; alignItemWithTrigger=true
|
|
148
|
+
guideline: "Positions the popup relative to the trigger. Use side and align to control placement. The popup opens below the trigger by default; alignItemWithTrigger=true makes it cover the trigger to align the selected item with it."
|
|
149
149
|
});
|
|
150
150
|
const SelectScrollUpArrowDefinition = defineComponent({
|
|
151
151
|
name: "SelectScrollUpArrow",
|
|
@@ -171,7 +171,7 @@ const SelectPopupDefinition = defineComponent({
|
|
|
171
171
|
category: "layout"
|
|
172
172
|
},
|
|
173
173
|
schema: {},
|
|
174
|
-
guideline: "Visible container for the select list. Apply background, shadow, and border styles here."
|
|
174
|
+
guideline: "Visible container for the select list. Apply background, shadow, and border styles here. The base stylesheet bounds it to the viewport (max-height from --available-height, as a flex column) so the list scrolls inside it; a utility class such as max-h-60 overrides that bound."
|
|
175
175
|
});
|
|
176
176
|
const SelectArrowDefinition = defineComponent({
|
|
177
177
|
name: "SelectArrow",
|
|
@@ -193,7 +193,7 @@ const SelectListDefinition = defineComponent({
|
|
|
193
193
|
category: "layout"
|
|
194
194
|
},
|
|
195
195
|
schema: {},
|
|
196
|
-
guideline: "Scrollable container for all Select.Item elements.
|
|
196
|
+
guideline: "Scrollable container for all Select.Item elements. The base stylesheet makes it scroll (overflow-y: auto) inside the popup bound; an overflow-* utility class overrides that."
|
|
197
197
|
});
|
|
198
198
|
const SelectItemDefinition = defineComponent({
|
|
199
199
|
name: "SelectItem",
|
|
@@ -345,7 +345,7 @@ function SelectBackdrop({ className, children, ...props }) {
|
|
|
345
345
|
children
|
|
346
346
|
});
|
|
347
347
|
}
|
|
348
|
-
function SelectPositioner({ side = "bottom", align = "
|
|
348
|
+
function SelectPositioner({ side = "bottom", align = "start", sideOffset = 0, alignItemWithTrigger = false, className, children, ...props }) {
|
|
349
349
|
return /* @__PURE__ */ jsx(Select.Positioner, {
|
|
350
350
|
...props,
|
|
351
351
|
side,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.js","names":["BaseSelect","Select"],"sources":["../../../src/particles/select/select.tsx"],"sourcesContent":["'use client';\nimport { Select as BaseSelect } from '@base-ui/react/select';\nimport { defineComponent } from '@vtex/fs-core';\nimport type { ComponentPropsWithRef, ReactNode } from 'react';\n\nexport type SelectSide = 'top' | 'bottom' | 'left' | 'right';\nexport type SelectAlign = 'start' | 'center' | 'end';\n\nexport type SelectRootProps = {\n disabled?: boolean;\n modal?: boolean;\n required?: boolean;\n readOnly?: boolean;\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string | null) => void;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n name?: string;\n /** Forwarded to Base UI's hidden `<input>` — turns on browser autofill for the field. */\n autoComplete?: string;\n children?: ReactNode;\n};\n\nexport type SelectLabelProps = ComponentPropsWithRef<'div'>;\n\nexport type SelectTriggerProps = ComponentPropsWithRef<'button'> & {\n disabled?: boolean;\n};\n\nexport type SelectValueProps = Omit<ComponentPropsWithRef<'span'>, 'children'> & {\n placeholder?: string;\n /** Rendered content, or a render function receiving the current value (Base UI resolves the\n * matching item's label automatically when omitted, but only once that item has mounted at\n * least once — e.g. after the popup has been opened — so pass a render function when the\n * label must be correct before the shopper ever opens the dropdown). */\n children?: ReactNode | ((value: string | null) => ReactNode);\n};\n\nexport type SelectIconProps = ComponentPropsWithRef<'span'>;\n\nexport type SelectPortalProps = {\n children?: ReactNode;\n};\n\nexport type SelectBackdropProps = ComponentPropsWithRef<'div'>;\n\nexport type SelectPositionerProps = ComponentPropsWithRef<'div'> & {\n side?: SelectSide;\n align?: SelectAlign;\n sideOffset?: number;\n alignItemWithTrigger?: boolean;\n};\n\nexport type SelectScrollUpArrowProps = ComponentPropsWithRef<'div'> & {\n keepMounted?: boolean;\n};\n\nexport type SelectPopupProps = ComponentPropsWithRef<'div'>;\n\nexport type SelectArrowProps = ComponentPropsWithRef<'div'>;\n\nexport type SelectListProps = ComponentPropsWithRef<'div'>;\n\nexport type SelectItemProps = ComponentPropsWithRef<'div'> & {\n value?: string;\n disabled?: boolean;\n label?: string;\n};\n\nexport type SelectItemTextProps = ComponentPropsWithRef<'div'>;\n\nexport type SelectItemIndicatorProps = ComponentPropsWithRef<'span'> & {\n keepMounted?: boolean;\n};\n\nexport type SelectSeparatorProps = ComponentPropsWithRef<'div'>;\n\nexport type SelectGroupProps = ComponentPropsWithRef<'div'>;\n\nexport type SelectGroupLabelProps = ComponentPropsWithRef<'div'>;\n\nexport type SelectScrollDownArrowProps = ComponentPropsWithRef<'div'> & {\n keepMounted?: boolean;\n};\n\nexport const SelectRootDefinition = defineComponent<SelectRootProps>({\n name: 'SelectRoot',\n importPath: '@vtex/faststore/components',\n component: SelectRoot,\n editor: { label: 'Select Root', category: 'layout' },\n schema: {\n disabled: { type: 'boolean', default: false, label: 'Disabled' },\n modal: { type: 'boolean', default: true, label: 'Modal' },\n required: { type: 'boolean', default: false, label: 'Required' },\n readOnly: { type: 'boolean', default: false, label: 'Read Only' },\n },\n guideline:\n 'Root of a select dropdown. Manages selection state, modal overlay, and form integration. Compose as: SelectRoot > (SelectLabel + SelectTrigger > (SelectValue + SelectIcon) + SelectPortal > (SelectBackdrop + SelectPositioner > SelectPopup > (SelectScrollUpArrow + SelectList > [SelectItem > (SelectItemText + SelectItemIndicator)] + SelectScrollDownArrow))). Use SelectGroup > (SelectGroupLabel + [SelectItem]) for grouped options. Set modal=false to allow interacting with background elements while open.',\n});\n\nexport const SelectLabelDefinition = defineComponent<SelectLabelProps>({\n name: 'SelectLabel',\n importPath: '@vtex/faststore/components',\n component: SelectLabel,\n editor: { label: 'Select Label', category: 'layout' },\n schema: {},\n guideline:\n 'Accessible label associated with the trigger. Always place outside Select.Trigger so screen readers announce it separately.',\n});\n\nexport const SelectTriggerDefinition = defineComponent<SelectTriggerProps>({\n name: 'SelectTrigger',\n importPath: '@vtex/faststore/components',\n component: SelectTrigger,\n editor: { label: 'Select Trigger', category: 'action' },\n schema: {\n disabled: { type: 'boolean', default: false, label: 'Disabled' },\n },\n guideline:\n 'Opens and closes the popup on click. Use data-open and data-placeholder CSS attributes for open-state and empty-state styling.',\n});\n\nexport const SelectValueDefinition = defineComponent<SelectValueProps>({\n name: 'SelectValue',\n importPath: '@vtex/faststore/components',\n component: SelectValue,\n editor: { label: 'Select Value', category: 'layout' },\n schema: {},\n guideline:\n \"Renders the selected item's text, or placeholder when nothing is selected. Style the placeholder state via [data-fs-select-value][data-placeholder].\",\n});\n\nexport const SelectIconDefinition = defineComponent<SelectIconProps>({\n name: 'SelectIcon',\n importPath: '@vtex/faststore/components',\n component: SelectIcon,\n editor: { label: 'Select Icon', category: 'layout' },\n schema: {},\n guideline:\n 'Decorative indicator (e.g. chevron) inside the trigger. Rotates or changes when the popup opens via data-open.',\n});\n\nexport const SelectPortalDefinition = defineComponent<SelectPortalProps>({\n name: 'SelectPortal',\n importPath: '@vtex/faststore/components',\n component: SelectPortal,\n editor: { label: 'Select Portal', category: 'layout' },\n schema: {},\n guideline:\n 'Teleports popup content to <body>. Always wrap Select.Positioner with this to avoid overflow/z-index issues.',\n});\n\nexport const SelectBackdropDefinition = defineComponent<SelectBackdropProps>({\n name: 'SelectBackdrop',\n importPath: '@vtex/faststore/components',\n component: SelectBackdrop,\n editor: { label: 'Select Backdrop', category: 'layout' },\n schema: {},\n guideline:\n 'Invisible overlay that closes the select when clicked outside. Required when modal=true to trap interaction.',\n});\n\nexport const SelectPositionerDefinition = defineComponent<SelectPositionerProps>({\n name: 'SelectPositioner',\n importPath: '@vtex/faststore/components',\n component: SelectPositioner,\n editor: { label: 'Select Positioner', category: 'layout' },\n schema: {\n side: { type: ['top', 'bottom', 'left', 'right'] as const, default: 'bottom', label: 'Side' },\n align: { type: ['start', 'center', 'end'] as const, default: 'center', label: 'Align' },\n sideOffset: { type: 'number', default: 0, label: 'Side Offset' },\n alignItemWithTrigger: { type: 'boolean', default: true, label: 'Align Item With Trigger' },\n },\n guideline:\n 'Positions the popup relative to the trigger. Use side and align to control placement; alignItemWithTrigger=true overlaps the trigger to align the selected item visually.',\n});\n\nexport const SelectScrollUpArrowDefinition = defineComponent<SelectScrollUpArrowProps>({\n name: 'SelectScrollUpArrow',\n importPath: '@vtex/faststore/components',\n component: SelectScrollUpArrow,\n editor: { label: 'Select Scroll Up Arrow', category: 'layout' },\n schema: {\n keepMounted: { type: 'boolean', default: false, label: 'Keep Mounted' },\n },\n guideline: 'Scrolls the list upward when hovered. Appears automatically when the list overflows at the top.',\n});\n\nexport const SelectPopupDefinition = defineComponent<SelectPopupProps>({\n name: 'SelectPopup',\n importPath: '@vtex/faststore/components',\n component: SelectPopup,\n editor: { label: 'Select Popup', category: 'layout' },\n schema: {},\n guideline: 'Visible container for the select list. Apply background, shadow, and border styles here.',\n});\n\nexport const SelectArrowDefinition = defineComponent<SelectArrowProps>({\n name: 'SelectArrow',\n importPath: '@vtex/faststore/components',\n component: SelectArrow,\n editor: { label: 'Select Arrow', category: 'layout' },\n schema: {},\n guideline:\n 'Pointing arrow attached to the popup indicating the anchor. Optional — omit when not using an arrow indicator.',\n});\n\nexport const SelectListDefinition = defineComponent<SelectListProps>({\n name: 'SelectList',\n importPath: '@vtex/faststore/components',\n component: SelectList,\n editor: { label: 'Select List', category: 'layout' },\n schema: {},\n guideline: 'Scrollable container for all Select.Item elements. Apply max-height and overflow for scrolling.',\n});\n\nexport const SelectItemDefinition = defineComponent<SelectItemProps>({\n name: 'SelectItem',\n importPath: '@vtex/faststore/components',\n component: SelectItem,\n editor: { label: 'Select Item', category: 'layout' },\n schema: {\n value: { type: 'string', label: 'Value' },\n disabled: { type: 'boolean', default: false, label: 'Disabled' },\n },\n guideline:\n 'One selectable option. Requires a unique value prop. Style selected and highlighted states via data-selected and data-highlighted attributes.',\n});\n\nexport const SelectItemTextDefinition = defineComponent<SelectItemTextProps>({\n name: 'SelectItemText',\n importPath: '@vtex/faststore/components',\n component: SelectItemText,\n editor: { label: 'Select Item Text', category: 'layout' },\n schema: {},\n guideline: 'The visible text label of an item. Base UI uses this for keyboard navigation matching.',\n});\n\nexport const SelectItemIndicatorDefinition = defineComponent<SelectItemIndicatorProps>({\n name: 'SelectItemIndicator',\n importPath: '@vtex/faststore/components',\n component: SelectItemIndicator,\n editor: { label: 'Select Item Indicator', category: 'layout' },\n schema: {\n keepMounted: { type: 'boolean', default: false, label: 'Keep Mounted' },\n },\n guideline: 'Checkmark or indicator shown only on the selected item. Set keepMounted=true to animate in/out.',\n});\n\nexport const SelectSeparatorDefinition = defineComponent<SelectSeparatorProps>({\n name: 'SelectSeparator',\n importPath: '@vtex/faststore/components',\n component: SelectSeparator,\n editor: { label: 'Select Separator', category: 'layout' },\n schema: {},\n guideline: 'Visual divider between items or groups. Use between unrelated option groups.',\n});\n\nexport const SelectGroupDefinition = defineComponent<SelectGroupProps>({\n name: 'SelectGroup',\n importPath: '@vtex/faststore/components',\n component: SelectGroup,\n editor: { label: 'Select Group', category: 'layout' },\n schema: {},\n guideline: 'Groups related items under a shared SelectGroupLabel for semantic and visual grouping.',\n});\n\nexport const SelectGroupLabelDefinition = defineComponent<SelectGroupLabelProps>({\n name: 'SelectGroupLabel',\n importPath: '@vtex/faststore/components',\n component: SelectGroupLabel,\n editor: { label: 'Select Group Label', category: 'layout' },\n schema: {},\n guideline: 'Non-interactive label for a Select.Group. Announced by screen readers as a group name.',\n});\n\nexport const SelectScrollDownArrowDefinition = defineComponent<SelectScrollDownArrowProps>({\n name: 'SelectScrollDownArrow',\n importPath: '@vtex/faststore/components',\n component: SelectScrollDownArrow,\n editor: { label: 'Select Scroll Down Arrow', category: 'layout' },\n schema: {\n keepMounted: { type: 'boolean', default: false, label: 'Keep Mounted' },\n },\n guideline: 'Scrolls the list downward when hovered. Appears when the list overflows at the bottom.',\n});\n\nexport function SelectRoot({\n disabled = false,\n modal = true,\n required = false,\n readOnly = false,\n children,\n ...props\n}: SelectRootProps) {\n return (\n <BaseSelect.Root {...props} disabled={disabled} modal={modal} required={required} readOnly={readOnly}>\n {children}\n </BaseSelect.Root>\n );\n}\n\nexport function SelectLabel({ className, children, ...props }: SelectLabelProps) {\n return (\n <BaseSelect.Label {...props} className={className} data-fs-select-label=\"\">\n {children}\n </BaseSelect.Label>\n );\n}\n\nexport function SelectTrigger({ disabled = false, className, children, ...props }: SelectTriggerProps) {\n return (\n <BaseSelect.Trigger {...props} disabled={disabled} className={className} data-fs-select-trigger=\"\">\n {children}\n </BaseSelect.Trigger>\n );\n}\n\nexport function SelectValue({ placeholder, className, children, ...props }: SelectValueProps) {\n return (\n <BaseSelect.Value {...props} placeholder={placeholder} className={className} data-fs-select-value=\"\">\n {children}\n </BaseSelect.Value>\n );\n}\n\nexport function SelectIcon({ className, children, ...props }: SelectIconProps) {\n return (\n <BaseSelect.Icon {...props} className={className} data-fs-select-icon=\"\">\n {children}\n </BaseSelect.Icon>\n );\n}\n\nexport function SelectPortal({ children }: SelectPortalProps) {\n return <BaseSelect.Portal>{children}</BaseSelect.Portal>;\n}\n\nexport function SelectBackdrop({ className, children, ...props }: SelectBackdropProps) {\n return (\n <BaseSelect.Backdrop {...props} className={className} data-fs-select-backdrop=\"\">\n {children}\n </BaseSelect.Backdrop>\n );\n}\n\nexport function SelectPositioner({\n side = 'bottom',\n align = 'center',\n sideOffset = 0,\n alignItemWithTrigger = true,\n className,\n children,\n ...props\n}: SelectPositionerProps) {\n return (\n <BaseSelect.Positioner\n {...props}\n side={side}\n align={align}\n sideOffset={sideOffset}\n alignItemWithTrigger={alignItemWithTrigger}\n className={className}\n data-fs-select-positioner=\"\"\n >\n {children}\n </BaseSelect.Positioner>\n );\n}\n\nexport function SelectScrollUpArrow({ keepMounted = false, className, children, ...props }: SelectScrollUpArrowProps) {\n return (\n <BaseSelect.ScrollUpArrow\n {...props}\n keepMounted={keepMounted}\n className={className}\n data-fs-select-scroll-up-arrow=\"\"\n >\n {children}\n </BaseSelect.ScrollUpArrow>\n );\n}\n\nexport function SelectPopup({ className, children, ...props }: SelectPopupProps) {\n return (\n <BaseSelect.Popup {...props} className={className} data-fs-select-popup=\"\">\n {children}\n </BaseSelect.Popup>\n );\n}\n\nexport function SelectArrow({ className, children, ...props }: SelectArrowProps) {\n return (\n <BaseSelect.Arrow {...props} className={className} data-fs-select-arrow=\"\">\n {children}\n </BaseSelect.Arrow>\n );\n}\n\nexport function SelectList({ className, children, ...props }: SelectListProps) {\n return (\n <BaseSelect.List {...props} className={className} data-fs-select-list=\"\">\n {children}\n </BaseSelect.List>\n );\n}\n\nexport function SelectItem({ value, disabled = false, label, className, children, ...props }: SelectItemProps) {\n return (\n <BaseSelect.Item\n {...props}\n value={value}\n disabled={disabled}\n label={label}\n className={className}\n data-fs-select-item=\"\"\n >\n {children}\n </BaseSelect.Item>\n );\n}\n\nexport function SelectItemText({ className, children, ...props }: SelectItemTextProps) {\n return (\n <BaseSelect.ItemText {...props} className={className} data-fs-select-item-text=\"\">\n {children}\n </BaseSelect.ItemText>\n );\n}\n\nexport function SelectItemIndicator({ keepMounted = false, className, children, ...props }: SelectItemIndicatorProps) {\n return (\n <BaseSelect.ItemIndicator\n {...props}\n keepMounted={keepMounted}\n className={className}\n data-fs-select-item-indicator=\"\"\n >\n {children}\n </BaseSelect.ItemIndicator>\n );\n}\n\nexport function SelectSeparator({ className, children, ...props }: SelectSeparatorProps) {\n return (\n <BaseSelect.Separator {...props} className={className} data-fs-select-separator=\"\">\n {children}\n </BaseSelect.Separator>\n );\n}\n\nexport function SelectGroup({ className, children, ...props }: SelectGroupProps) {\n return (\n <BaseSelect.Group {...props} className={className} data-fs-select-group=\"\">\n {children}\n </BaseSelect.Group>\n );\n}\n\nexport function SelectGroupLabel({ className, children, ...props }: SelectGroupLabelProps) {\n return (\n <BaseSelect.GroupLabel {...props} className={className} data-fs-select-group-label=\"\">\n {children}\n </BaseSelect.GroupLabel>\n );\n}\n\nexport function SelectScrollDownArrow({\n keepMounted = false,\n className,\n children,\n ...props\n}: SelectScrollDownArrowProps) {\n return (\n <BaseSelect.ScrollDownArrow\n {...props}\n keepMounted={keepMounted}\n className={className}\n data-fs-select-scroll-down-arrow=\"\"\n >\n {children}\n </BaseSelect.ScrollDownArrow>\n );\n}\n\nexport const Select = {\n Root: SelectRoot,\n Label: SelectLabel,\n Trigger: SelectTrigger,\n Value: SelectValue,\n Icon: SelectIcon,\n Portal: SelectPortal,\n Backdrop: SelectBackdrop,\n Positioner: SelectPositioner,\n ScrollUpArrow: SelectScrollUpArrow,\n Popup: SelectPopup,\n Arrow: SelectArrow,\n List: SelectList,\n Item: SelectItem,\n ItemText: SelectItemText,\n ItemIndicator: SelectItemIndicator,\n Separator: SelectSeparator,\n Group: SelectGroup,\n GroupLabel: SelectGroupLabel,\n ScrollDownArrow: SelectScrollDownArrow,\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"select.js","names":["BaseSelect","Select"],"sources":["../../../src/particles/select/select.tsx"],"sourcesContent":["'use client';\nimport { Select as BaseSelect } from '@base-ui/react/select';\nimport { defineComponent } from '@vtex/fs-core';\nimport type { ComponentPropsWithRef, ReactNode } from 'react';\n\nexport type SelectSide = 'top' | 'bottom' | 'left' | 'right';\nexport type SelectAlign = 'start' | 'center' | 'end';\n\nexport type SelectRootProps = {\n disabled?: boolean;\n modal?: boolean;\n required?: boolean;\n readOnly?: boolean;\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string | null) => void;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n name?: string;\n /** Forwarded to Base UI's hidden `<input>` — turns on browser autofill for the field. */\n autoComplete?: string;\n children?: ReactNode;\n};\n\nexport type SelectLabelProps = ComponentPropsWithRef<'div'>;\n\nexport type SelectTriggerProps = ComponentPropsWithRef<'button'> & {\n disabled?: boolean;\n};\n\nexport type SelectValueProps = Omit<ComponentPropsWithRef<'span'>, 'children'> & {\n placeholder?: string;\n /** Rendered content, or a render function receiving the current value (Base UI resolves the\n * matching item's label automatically when omitted, but only once that item has mounted at\n * least once — e.g. after the popup has been opened — so pass a render function when the\n * label must be correct before the shopper ever opens the dropdown). */\n children?: ReactNode | ((value: string | null) => ReactNode);\n};\n\nexport type SelectIconProps = ComponentPropsWithRef<'span'>;\n\nexport type SelectPortalProps = {\n children?: ReactNode;\n};\n\nexport type SelectBackdropProps = ComponentPropsWithRef<'div'>;\n\nexport type SelectPositionerProps = ComponentPropsWithRef<'div'> & {\n side?: SelectSide;\n align?: SelectAlign;\n sideOffset?: number;\n alignItemWithTrigger?: boolean;\n};\n\nexport type SelectScrollUpArrowProps = ComponentPropsWithRef<'div'> & {\n keepMounted?: boolean;\n};\n\nexport type SelectPopupProps = ComponentPropsWithRef<'div'>;\n\nexport type SelectArrowProps = ComponentPropsWithRef<'div'>;\n\nexport type SelectListProps = ComponentPropsWithRef<'div'>;\n\nexport type SelectItemProps = ComponentPropsWithRef<'div'> & {\n value?: string;\n disabled?: boolean;\n label?: string;\n};\n\nexport type SelectItemTextProps = ComponentPropsWithRef<'div'>;\n\nexport type SelectItemIndicatorProps = ComponentPropsWithRef<'span'> & {\n keepMounted?: boolean;\n};\n\nexport type SelectSeparatorProps = ComponentPropsWithRef<'div'>;\n\nexport type SelectGroupProps = ComponentPropsWithRef<'div'>;\n\nexport type SelectGroupLabelProps = ComponentPropsWithRef<'div'>;\n\nexport type SelectScrollDownArrowProps = ComponentPropsWithRef<'div'> & {\n keepMounted?: boolean;\n};\n\nexport const SelectRootDefinition = defineComponent<SelectRootProps>({\n name: 'SelectRoot',\n importPath: '@vtex/faststore/components',\n component: SelectRoot,\n editor: { label: 'Select Root', category: 'layout' },\n schema: {\n disabled: { type: 'boolean', default: false, label: 'Disabled' },\n modal: { type: 'boolean', default: true, label: 'Modal' },\n required: { type: 'boolean', default: false, label: 'Required' },\n readOnly: { type: 'boolean', default: false, label: 'Read Only' },\n },\n guideline:\n 'Root of a select dropdown. Manages selection state, modal overlay, and form integration. Compose as: SelectRoot > (SelectLabel + SelectTrigger > (SelectValue + SelectIcon) + SelectPortal > (SelectBackdrop + SelectPositioner > SelectPopup > (SelectScrollUpArrow + SelectList > [SelectItem > (SelectItemText + SelectItemIndicator)] + SelectScrollDownArrow))). Use SelectGroup > (SelectGroupLabel + [SelectItem]) for grouped options. Set modal=false to allow interacting with background elements while open.',\n});\n\nexport const SelectLabelDefinition = defineComponent<SelectLabelProps>({\n name: 'SelectLabel',\n importPath: '@vtex/faststore/components',\n component: SelectLabel,\n editor: { label: 'Select Label', category: 'layout' },\n schema: {},\n guideline:\n 'Accessible label associated with the trigger. Always place outside Select.Trigger so screen readers announce it separately.',\n});\n\nexport const SelectTriggerDefinition = defineComponent<SelectTriggerProps>({\n name: 'SelectTrigger',\n importPath: '@vtex/faststore/components',\n component: SelectTrigger,\n editor: { label: 'Select Trigger', category: 'action' },\n schema: {\n disabled: { type: 'boolean', default: false, label: 'Disabled' },\n },\n guideline:\n 'Opens and closes the popup on click. Use data-open and data-placeholder CSS attributes for open-state and empty-state styling.',\n});\n\nexport const SelectValueDefinition = defineComponent<SelectValueProps>({\n name: 'SelectValue',\n importPath: '@vtex/faststore/components',\n component: SelectValue,\n editor: { label: 'Select Value', category: 'layout' },\n schema: {},\n guideline:\n \"Renders the selected item's text, or placeholder when nothing is selected. Style the placeholder state via [data-fs-select-value][data-placeholder].\",\n});\n\nexport const SelectIconDefinition = defineComponent<SelectIconProps>({\n name: 'SelectIcon',\n importPath: '@vtex/faststore/components',\n component: SelectIcon,\n editor: { label: 'Select Icon', category: 'layout' },\n schema: {},\n guideline:\n 'Decorative indicator (e.g. chevron) inside the trigger. Rotates or changes when the popup opens via data-open.',\n});\n\nexport const SelectPortalDefinition = defineComponent<SelectPortalProps>({\n name: 'SelectPortal',\n importPath: '@vtex/faststore/components',\n component: SelectPortal,\n editor: { label: 'Select Portal', category: 'layout' },\n schema: {},\n guideline:\n 'Teleports popup content to <body>. Always wrap Select.Positioner with this to avoid overflow/z-index issues.',\n});\n\nexport const SelectBackdropDefinition = defineComponent<SelectBackdropProps>({\n name: 'SelectBackdrop',\n importPath: '@vtex/faststore/components',\n component: SelectBackdrop,\n editor: { label: 'Select Backdrop', category: 'layout' },\n schema: {},\n guideline:\n 'Invisible overlay that closes the select when clicked outside. Required when modal=true to trap interaction.',\n});\n\nexport const SelectPositionerDefinition = defineComponent<SelectPositionerProps>({\n name: 'SelectPositioner',\n importPath: '@vtex/faststore/components',\n component: SelectPositioner,\n editor: { label: 'Select Positioner', category: 'layout' },\n schema: {\n side: { type: ['top', 'bottom', 'left', 'right'] as const, default: 'bottom', label: 'Side' },\n align: { type: ['start', 'center', 'end'] as const, default: 'start', label: 'Align' },\n sideOffset: { type: 'number', default: 0, label: 'Side Offset' },\n alignItemWithTrigger: { type: 'boolean', default: false, label: 'Align Item With Trigger' },\n },\n guideline:\n 'Positions the popup relative to the trigger. Use side and align to control placement. The popup opens below the trigger by default; alignItemWithTrigger=true makes it cover the trigger to align the selected item with it.',\n});\n\nexport const SelectScrollUpArrowDefinition = defineComponent<SelectScrollUpArrowProps>({\n name: 'SelectScrollUpArrow',\n importPath: '@vtex/faststore/components',\n component: SelectScrollUpArrow,\n editor: { label: 'Select Scroll Up Arrow', category: 'layout' },\n schema: {\n keepMounted: { type: 'boolean', default: false, label: 'Keep Mounted' },\n },\n guideline: 'Scrolls the list upward when hovered. Appears automatically when the list overflows at the top.',\n});\n\nexport const SelectPopupDefinition = defineComponent<SelectPopupProps>({\n name: 'SelectPopup',\n importPath: '@vtex/faststore/components',\n component: SelectPopup,\n editor: { label: 'Select Popup', category: 'layout' },\n schema: {},\n guideline:\n 'Visible container for the select list. Apply background, shadow, and border styles here. The base stylesheet bounds it to the viewport (max-height from --available-height, as a flex column) so the list scrolls inside it; a utility class such as max-h-60 overrides that bound.',\n});\n\nexport const SelectArrowDefinition = defineComponent<SelectArrowProps>({\n name: 'SelectArrow',\n importPath: '@vtex/faststore/components',\n component: SelectArrow,\n editor: { label: 'Select Arrow', category: 'layout' },\n schema: {},\n guideline:\n 'Pointing arrow attached to the popup indicating the anchor. Optional — omit when not using an arrow indicator.',\n});\n\nexport const SelectListDefinition = defineComponent<SelectListProps>({\n name: 'SelectList',\n importPath: '@vtex/faststore/components',\n component: SelectList,\n editor: { label: 'Select List', category: 'layout' },\n schema: {},\n guideline:\n 'Scrollable container for all Select.Item elements. The base stylesheet makes it scroll (overflow-y: auto) inside the popup bound; an overflow-* utility class overrides that.',\n});\n\nexport const SelectItemDefinition = defineComponent<SelectItemProps>({\n name: 'SelectItem',\n importPath: '@vtex/faststore/components',\n component: SelectItem,\n editor: { label: 'Select Item', category: 'layout' },\n schema: {\n value: { type: 'string', label: 'Value' },\n disabled: { type: 'boolean', default: false, label: 'Disabled' },\n },\n guideline:\n 'One selectable option. Requires a unique value prop. Style selected and highlighted states via data-selected and data-highlighted attributes.',\n});\n\nexport const SelectItemTextDefinition = defineComponent<SelectItemTextProps>({\n name: 'SelectItemText',\n importPath: '@vtex/faststore/components',\n component: SelectItemText,\n editor: { label: 'Select Item Text', category: 'layout' },\n schema: {},\n guideline: 'The visible text label of an item. Base UI uses this for keyboard navigation matching.',\n});\n\nexport const SelectItemIndicatorDefinition = defineComponent<SelectItemIndicatorProps>({\n name: 'SelectItemIndicator',\n importPath: '@vtex/faststore/components',\n component: SelectItemIndicator,\n editor: { label: 'Select Item Indicator', category: 'layout' },\n schema: {\n keepMounted: { type: 'boolean', default: false, label: 'Keep Mounted' },\n },\n guideline: 'Checkmark or indicator shown only on the selected item. Set keepMounted=true to animate in/out.',\n});\n\nexport const SelectSeparatorDefinition = defineComponent<SelectSeparatorProps>({\n name: 'SelectSeparator',\n importPath: '@vtex/faststore/components',\n component: SelectSeparator,\n editor: { label: 'Select Separator', category: 'layout' },\n schema: {},\n guideline: 'Visual divider between items or groups. Use between unrelated option groups.',\n});\n\nexport const SelectGroupDefinition = defineComponent<SelectGroupProps>({\n name: 'SelectGroup',\n importPath: '@vtex/faststore/components',\n component: SelectGroup,\n editor: { label: 'Select Group', category: 'layout' },\n schema: {},\n guideline: 'Groups related items under a shared SelectGroupLabel for semantic and visual grouping.',\n});\n\nexport const SelectGroupLabelDefinition = defineComponent<SelectGroupLabelProps>({\n name: 'SelectGroupLabel',\n importPath: '@vtex/faststore/components',\n component: SelectGroupLabel,\n editor: { label: 'Select Group Label', category: 'layout' },\n schema: {},\n guideline: 'Non-interactive label for a Select.Group. Announced by screen readers as a group name.',\n});\n\nexport const SelectScrollDownArrowDefinition = defineComponent<SelectScrollDownArrowProps>({\n name: 'SelectScrollDownArrow',\n importPath: '@vtex/faststore/components',\n component: SelectScrollDownArrow,\n editor: { label: 'Select Scroll Down Arrow', category: 'layout' },\n schema: {\n keepMounted: { type: 'boolean', default: false, label: 'Keep Mounted' },\n },\n guideline: 'Scrolls the list downward when hovered. Appears when the list overflows at the bottom.',\n});\n\nexport function SelectRoot({\n disabled = false,\n modal = true,\n required = false,\n readOnly = false,\n children,\n ...props\n}: SelectRootProps) {\n return (\n <BaseSelect.Root {...props} disabled={disabled} modal={modal} required={required} readOnly={readOnly}>\n {children}\n </BaseSelect.Root>\n );\n}\n\nexport function SelectLabel({ className, children, ...props }: SelectLabelProps) {\n return (\n <BaseSelect.Label {...props} className={className} data-fs-select-label=\"\">\n {children}\n </BaseSelect.Label>\n );\n}\n\nexport function SelectTrigger({ disabled = false, className, children, ...props }: SelectTriggerProps) {\n return (\n <BaseSelect.Trigger {...props} disabled={disabled} className={className} data-fs-select-trigger=\"\">\n {children}\n </BaseSelect.Trigger>\n );\n}\n\nexport function SelectValue({ placeholder, className, children, ...props }: SelectValueProps) {\n return (\n <BaseSelect.Value {...props} placeholder={placeholder} className={className} data-fs-select-value=\"\">\n {children}\n </BaseSelect.Value>\n );\n}\n\nexport function SelectIcon({ className, children, ...props }: SelectIconProps) {\n return (\n <BaseSelect.Icon {...props} className={className} data-fs-select-icon=\"\">\n {children}\n </BaseSelect.Icon>\n );\n}\n\nexport function SelectPortal({ children }: SelectPortalProps) {\n return <BaseSelect.Portal>{children}</BaseSelect.Portal>;\n}\n\nexport function SelectBackdrop({ className, children, ...props }: SelectBackdropProps) {\n return (\n <BaseSelect.Backdrop {...props} className={className} data-fs-select-backdrop=\"\">\n {children}\n </BaseSelect.Backdrop>\n );\n}\n\nexport function SelectPositioner({\n side = 'bottom',\n align = 'start',\n sideOffset = 0,\n alignItemWithTrigger = false,\n className,\n children,\n ...props\n}: SelectPositionerProps) {\n return (\n <BaseSelect.Positioner\n {...props}\n side={side}\n align={align}\n sideOffset={sideOffset}\n alignItemWithTrigger={alignItemWithTrigger}\n className={className}\n data-fs-select-positioner=\"\"\n >\n {children}\n </BaseSelect.Positioner>\n );\n}\n\nexport function SelectScrollUpArrow({ keepMounted = false, className, children, ...props }: SelectScrollUpArrowProps) {\n return (\n <BaseSelect.ScrollUpArrow\n {...props}\n keepMounted={keepMounted}\n className={className}\n data-fs-select-scroll-up-arrow=\"\"\n >\n {children}\n </BaseSelect.ScrollUpArrow>\n );\n}\n\nexport function SelectPopup({ className, children, ...props }: SelectPopupProps) {\n return (\n <BaseSelect.Popup {...props} className={className} data-fs-select-popup=\"\">\n {children}\n </BaseSelect.Popup>\n );\n}\n\nexport function SelectArrow({ className, children, ...props }: SelectArrowProps) {\n return (\n <BaseSelect.Arrow {...props} className={className} data-fs-select-arrow=\"\">\n {children}\n </BaseSelect.Arrow>\n );\n}\n\nexport function SelectList({ className, children, ...props }: SelectListProps) {\n return (\n <BaseSelect.List {...props} className={className} data-fs-select-list=\"\">\n {children}\n </BaseSelect.List>\n );\n}\n\nexport function SelectItem({ value, disabled = false, label, className, children, ...props }: SelectItemProps) {\n return (\n <BaseSelect.Item\n {...props}\n value={value}\n disabled={disabled}\n label={label}\n className={className}\n data-fs-select-item=\"\"\n >\n {children}\n </BaseSelect.Item>\n );\n}\n\nexport function SelectItemText({ className, children, ...props }: SelectItemTextProps) {\n return (\n <BaseSelect.ItemText {...props} className={className} data-fs-select-item-text=\"\">\n {children}\n </BaseSelect.ItemText>\n );\n}\n\nexport function SelectItemIndicator({ keepMounted = false, className, children, ...props }: SelectItemIndicatorProps) {\n return (\n <BaseSelect.ItemIndicator\n {...props}\n keepMounted={keepMounted}\n className={className}\n data-fs-select-item-indicator=\"\"\n >\n {children}\n </BaseSelect.ItemIndicator>\n );\n}\n\nexport function SelectSeparator({ className, children, ...props }: SelectSeparatorProps) {\n return (\n <BaseSelect.Separator {...props} className={className} data-fs-select-separator=\"\">\n {children}\n </BaseSelect.Separator>\n );\n}\n\nexport function SelectGroup({ className, children, ...props }: SelectGroupProps) {\n return (\n <BaseSelect.Group {...props} className={className} data-fs-select-group=\"\">\n {children}\n </BaseSelect.Group>\n );\n}\n\nexport function SelectGroupLabel({ className, children, ...props }: SelectGroupLabelProps) {\n return (\n <BaseSelect.GroupLabel {...props} className={className} data-fs-select-group-label=\"\">\n {children}\n </BaseSelect.GroupLabel>\n );\n}\n\nexport function SelectScrollDownArrow({\n keepMounted = false,\n className,\n children,\n ...props\n}: SelectScrollDownArrowProps) {\n return (\n <BaseSelect.ScrollDownArrow\n {...props}\n keepMounted={keepMounted}\n className={className}\n data-fs-select-scroll-down-arrow=\"\"\n >\n {children}\n </BaseSelect.ScrollDownArrow>\n );\n}\n\nexport const Select = {\n Root: SelectRoot,\n Label: SelectLabel,\n Trigger: SelectTrigger,\n Value: SelectValue,\n Icon: SelectIcon,\n Portal: SelectPortal,\n Backdrop: SelectBackdrop,\n Positioner: SelectPositioner,\n ScrollUpArrow: SelectScrollUpArrow,\n Popup: SelectPopup,\n Arrow: SelectArrow,\n List: SelectList,\n Item: SelectItem,\n ItemText: SelectItemText,\n ItemIndicator: SelectItemIndicator,\n Separator: SelectSeparator,\n Group: SelectGroup,\n GroupLabel: SelectGroupLabel,\n ScrollDownArrow: SelectScrollDownArrow,\n};\n"],"mappings":"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"}
|
|
@@ -60,7 +60,7 @@ export declare const ToastActionDefinition: ComponentDefinition<import("react").
|
|
|
60
60
|
export declare const ToastCloseDefinition: ComponentDefinition<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>>;
|
|
61
61
|
export declare function ToastProvider({ limit, timeout, toastManager, children }: ToastProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
62
62
|
export declare function ToastPortal({ className, children }: ToastPortalProps): import("react/jsx-runtime").JSX.Element;
|
|
63
|
-
export declare function ToastViewport({ className, children, ...props }: ToastViewportProps): import("react/jsx-runtime").JSX.Element;
|
|
63
|
+
export declare function ToastViewport({ className, children, 'aria-label': ariaLabel, ...props }: ToastViewportProps): import("react/jsx-runtime").JSX.Element;
|
|
64
64
|
export declare function ToastRoot({ toast, swipeDirection, className, children }: ToastRootProps): import("react/jsx-runtime").JSX.Element;
|
|
65
65
|
export declare function ToastTitle({ className, children, ...props }: ToastTitleProps): import("react/jsx-runtime").JSX.Element;
|
|
66
66
|
export declare function ToastDescription({ className, children, ...props }: ToastDescriptionProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { defineComponent } from "../../core/dist/define-component.js";
|
|
3
3
|
import "../../core/dist/index.js";
|
|
4
|
-
import {
|
|
4
|
+
import { useIntl } from "../../sdk/i18n/client.js";
|
|
5
|
+
import { Children } from "react";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
7
|
import { Toast } from "@base-ui/react/toast";
|
|
6
8
|
//#region src/particles/toast/toast.tsx
|
|
7
9
|
const ToastProviderDefinition = defineComponent({
|
|
@@ -24,7 +26,7 @@ const ToastProviderDefinition = defineComponent({
|
|
|
24
26
|
label: "Default Auto-Dismiss (ms)"
|
|
25
27
|
}
|
|
26
28
|
},
|
|
27
|
-
guideline: "Mount once at the layout root to enable toasts anywhere in the tree. Compose as: ToastProvider > ToastPortal > ToastViewport
|
|
29
|
+
guideline: "Mount once at the layout root to enable toasts anywhere in the tree. Compose as: ToastProvider > ToastPortal > ToastViewport (a childless viewport renders the active toasts itself; add ToastRoot children only to override). Components trigger toasts via the useToast() hook, not through page-schema composition."
|
|
28
30
|
});
|
|
29
31
|
const ToastPortalDefinition = defineComponent({
|
|
30
32
|
name: "ToastPortal",
|
|
@@ -46,7 +48,7 @@ const ToastViewportDefinition = defineComponent({
|
|
|
46
48
|
category: "layout"
|
|
47
49
|
},
|
|
48
50
|
schema: {},
|
|
49
|
-
guideline: "The fixed-position stack container for all active toasts. Position it with a swatch on data-fs-toast-viewport (e.g. bottom-right vs. top-center). Direct child of ToastPortal."
|
|
51
|
+
guideline: "The fixed-position stack container for all active toasts. With no children it renders every active toast itself (title, description, action and a localized close button), so a page schema needs only ToastProvider > ToastPortal > ToastViewport. Pass children (a ToastRoot per useToast().toasts entry) to take control of the markup. Position it with a swatch on data-fs-toast-viewport (e.g. bottom-right vs. top-center). Direct child of ToastPortal."
|
|
50
52
|
});
|
|
51
53
|
const ToastRootDefinition = defineComponent({
|
|
52
54
|
name: "ToastRoot",
|
|
@@ -57,7 +59,7 @@ const ToastRootDefinition = defineComponent({
|
|
|
57
59
|
category: "layout"
|
|
58
60
|
},
|
|
59
61
|
schema: {},
|
|
60
|
-
guideline: "One instance per active toast,
|
|
62
|
+
guideline: "One instance per active toast. A childless ToastViewport renders these itself; compose ToastRoot only to override that, by mapping over useToast().toasts. Compose as: ToastRoot > (Icon + ToastTitle + ToastDescription + ToastAction + ToastClose), all optional except at least one of Title/Description."
|
|
61
63
|
});
|
|
62
64
|
const ToastTitleDefinition = defineComponent({
|
|
63
65
|
name: "ToastTitle",
|
|
@@ -117,15 +119,39 @@ function ToastPortal({ className, children }) {
|
|
|
117
119
|
children
|
|
118
120
|
});
|
|
119
121
|
}
|
|
120
|
-
function
|
|
122
|
+
function hasChildren(children) {
|
|
123
|
+
return Children.toArray(children).length > 0;
|
|
124
|
+
}
|
|
125
|
+
function DefaultToastList() {
|
|
126
|
+
const intl = useIntl();
|
|
127
|
+
const { toasts } = useToast();
|
|
128
|
+
return toasts.map((toast) => /* @__PURE__ */ jsxs(ToastRoot, {
|
|
129
|
+
toast,
|
|
130
|
+
children: [
|
|
131
|
+
/* @__PURE__ */ jsx(ToastTitle, {}),
|
|
132
|
+
/* @__PURE__ */ jsx(ToastDescription, {}),
|
|
133
|
+
/* @__PURE__ */ jsx(ToastAction, {}),
|
|
134
|
+
/* @__PURE__ */ jsx(ToastClose, {
|
|
135
|
+
"aria-label": intl.formatMessage({ id: "fs/toast.dismiss" }),
|
|
136
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
137
|
+
"aria-hidden": "true",
|
|
138
|
+
children: "×"
|
|
139
|
+
})
|
|
140
|
+
})
|
|
141
|
+
]
|
|
142
|
+
}, toast.id));
|
|
143
|
+
}
|
|
144
|
+
function ToastViewport({ className, children, "aria-label": ariaLabel, ...props }) {
|
|
145
|
+
const intl = useIntl();
|
|
121
146
|
return /* @__PURE__ */ jsx(Toast.Viewport, {
|
|
122
147
|
...props,
|
|
148
|
+
"aria-label": ariaLabel ?? intl.formatMessage({ id: "fs/toast.region" }),
|
|
123
149
|
className,
|
|
124
150
|
render: (renderProps, state) => /* @__PURE__ */ jsx("div", {
|
|
125
151
|
...renderProps,
|
|
126
152
|
"data-fs-toast-viewport": "",
|
|
127
153
|
"data-fs-toast-viewport-expanded": state.expanded ? "" : void 0,
|
|
128
|
-
children
|
|
154
|
+
children: hasChildren(children) ? children : /* @__PURE__ */ jsx(DefaultToastList, {})
|
|
129
155
|
})
|
|
130
156
|
});
|
|
131
157
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toast.js","names":["BaseToast","Toast"],"sources":["../../../src/particles/toast/toast.tsx"],"sourcesContent":["'use client';\nimport type { ToastManager, ToastRootToastObject } from '@base-ui/react/toast';\nimport { Toast as BaseToast } from '@base-ui/react/toast';\nimport { defineComponent } from '@vtex/fs-core';\nimport type { ComponentPropsWithRef, ReactNode } from 'react';\n\n/** The queued toast object `useToast().toasts` returns and `ToastRoot` renders. */\nexport type ToastObject = ToastRootToastObject;\nexport type { ToastManager } from '@base-ui/react/toast';\n\ntype SwipeDirection = 'up' | 'down' | 'left' | 'right';\n\nexport type ToastProviderProps = Readonly<{\n /** Max concurrent toasts before older ones are marked limited. */\n limit?: number;\n /** Default auto-dismiss delay (ms); `0` disables. */\n timeout?: number;\n /** External manager for triggering toasts outside React (e.g. a non-component module). */\n toastManager?: ToastManager;\n children?: ReactNode;\n}>;\n\nexport type ToastPortalProps = Readonly<{\n className?: string;\n children?: ReactNode;\n}>;\n\nexport type ToastViewportProps = ComponentPropsWithRef<'div'>;\n\nexport type ToastRootProps = Readonly<{\n /** The queued toast to render, from `useToast().toasts`. */\n toast: ToastObject;\n /** Directions the toast can be swiped to dismiss. @default ['down', 'right'] */\n swipeDirection?: SwipeDirection | SwipeDirection[];\n className?: string;\n children?: ReactNode;\n}>;\n\nexport type ToastTitleProps = ComponentPropsWithRef<'h2'>;\n\nexport type ToastDescriptionProps = ComponentPropsWithRef<'p'>;\n\nexport type ToastActionProps = ComponentPropsWithRef<'button'>;\n\nexport type ToastCloseProps = ComponentPropsWithRef<'button'>;\n\nexport const ToastProviderDefinition = defineComponent<ToastProviderProps>({\n name: 'ToastProvider',\n importPath: '@vtex/faststore/components',\n component: ToastProvider,\n editor: { label: 'Toast Provider', category: 'layout' },\n schema: {\n limit: { type: 'number', default: 3, label: 'Max Concurrent Toasts' },\n timeout: { type: 'number', default: 5000, label: 'Default Auto-Dismiss (ms)' },\n },\n guideline:\n 'Mount once at the layout root to enable toasts anywhere in the tree. Compose as: ToastProvider > ToastPortal > ToastViewport > (ToastRoot per active toast). Components trigger toasts via the useToast() hook, not through page-schema composition.',\n});\n\nexport const ToastPortalDefinition = defineComponent<ToastPortalProps>({\n name: 'ToastPortal',\n importPath: '@vtex/faststore/components',\n component: ToastPortal,\n editor: { label: 'Toast Portal', category: 'layout' },\n schema: {},\n guideline:\n 'Renders its children (ToastViewport) outside the DOM tree, into document.body. Direct child of ToastProvider.',\n});\n\nexport const ToastViewportDefinition = defineComponent<ToastViewportProps>({\n name: 'ToastViewport',\n importPath: '@vtex/faststore/components',\n component: ToastViewport,\n editor: { label: 'Toast Viewport', category: 'layout' },\n schema: {},\n guideline:\n 'The fixed-position stack container for all active toasts. Position it with a swatch on data-fs-toast-viewport (e.g. bottom-right vs. top-center). Direct child of ToastPortal.',\n});\n\nexport const ToastRootDefinition = defineComponent<ToastRootProps>({\n name: 'ToastRoot',\n importPath: '@vtex/faststore/components',\n component: ToastRoot,\n editor: { label: 'Toast Root', category: 'layout' },\n schema: {},\n guideline:\n 'One instance per active toast, rendered by mapping over useToast().toasts. Compose as: ToastRoot > (Icon + ToastTitle + ToastDescription + ToastAction + ToastClose), all optional except at least one of Title/Description.',\n});\n\nexport const ToastTitleDefinition = defineComponent<ToastTitleProps>({\n name: 'ToastTitle',\n importPath: '@vtex/faststore/components',\n component: ToastTitle,\n editor: { label: 'Toast Title', category: 'layout' },\n schema: {},\n guideline: 'Renders the toast.title automatically when composed with no children. Direct child of ToastRoot.',\n});\n\nexport const ToastDescriptionDefinition = defineComponent<ToastDescriptionProps>({\n name: 'ToastDescription',\n importPath: '@vtex/faststore/components',\n component: ToastDescription,\n editor: { label: 'Toast Description', category: 'layout' },\n schema: {},\n guideline:\n 'Renders the toast.description automatically when composed with no children. Direct child of ToastRoot, after ToastTitle.',\n});\n\nexport const ToastActionDefinition = defineComponent<ToastActionProps>({\n name: 'ToastAction',\n importPath: '@vtex/faststore/components',\n component: ToastAction,\n editor: { label: 'Toast Action', category: 'action' },\n schema: {},\n guideline: \"Reversible-action button (e.g. Undo) forwarding the toast's actionProps. Omit for toasts with no action.\",\n});\n\nexport const ToastCloseDefinition = defineComponent<ToastCloseProps>({\n name: 'ToastClose',\n importPath: '@vtex/faststore/components',\n component: ToastClose,\n editor: { label: 'Toast Close', category: 'action' },\n schema: {},\n guideline: 'Dismisses the nearest ancestor ToastRoot when clicked. Can appear alongside or instead of ToastAction.',\n});\n\nexport function ToastProvider({ limit = 3, timeout = 5000, toastManager, children }: ToastProviderProps) {\n return (\n <BaseToast.Provider limit={limit} timeout={timeout} toastManager={toastManager}>\n {children}\n </BaseToast.Provider>\n );\n}\n\nexport function ToastPortal({ className, children }: ToastPortalProps) {\n return <BaseToast.Portal className={className}>{children}</BaseToast.Portal>;\n}\n\nexport function ToastViewport({ className, children, ...props }: ToastViewportProps) {\n return (\n <BaseToast.Viewport\n {...props}\n className={className}\n render={(renderProps, state) => (\n <div\n {...renderProps}\n data-fs-toast-viewport=\"\"\n data-fs-toast-viewport-expanded={state.expanded ? '' : undefined}\n >\n {children}\n </div>\n )}\n />\n );\n}\n\n// Uses Base UI's `render` prop (rather than plain prop-forwarding, unlike the rest of this file) so\n// `data-fs-toast-root-type`/`-limited`/`-swiping` can mirror internal render state (`state.type`,\n// `state.limited`, `state.swiping`) that is never exposed back to us as a prop.\nexport function ToastRoot({ toast, swipeDirection, className, children }: ToastRootProps) {\n return (\n <BaseToast.Root\n toast={toast}\n swipeDirection={swipeDirection}\n className={className}\n render={(renderProps, state) => (\n <div\n {...renderProps}\n data-fs-toast-root=\"\"\n data-fs-toast-root-type={state.type}\n data-fs-toast-root-limited={state.limited ? '' : undefined}\n data-fs-toast-root-swiping={state.swiping ? '' : undefined}\n >\n {children}\n </div>\n )}\n />\n );\n}\n\nexport function ToastTitle({ className, children, ...props }: ToastTitleProps) {\n return (\n <BaseToast.Title {...props} className={className} data-fs-toast-title=\"\">\n {children}\n </BaseToast.Title>\n );\n}\n\nexport function ToastDescription({ className, children, ...props }: ToastDescriptionProps) {\n return (\n <BaseToast.Description {...props} className={className} data-fs-toast-description=\"\">\n {children}\n </BaseToast.Description>\n );\n}\n\nexport function ToastAction({ className, children, ...props }: ToastActionProps) {\n return (\n <BaseToast.Action {...props} className={className} data-fs-toast-action=\"\">\n {children}\n </BaseToast.Action>\n );\n}\n\nexport function ToastClose({ className, children, ...props }: ToastCloseProps) {\n return (\n <BaseToast.Close {...props} className={className} data-fs-toast-close=\"\">\n {children}\n </BaseToast.Close>\n );\n}\n\n/** Thin re-export of Base UI's `useToastManager()` — see Key Decision 1 in the spec. */\nexport const useToast = BaseToast.useToastManager;\n\nexport const Toast = {\n Provider: ToastProvider,\n Portal: ToastPortal,\n Viewport: ToastViewport,\n Root: ToastRoot,\n Title: ToastTitle,\n Description: ToastDescription,\n Action: ToastAction,\n Close: ToastClose,\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"toast.js","names":["BaseToast","Toast"],"sources":["../../../src/particles/toast/toast.tsx"],"sourcesContent":["'use client';\nimport type { ToastManager, ToastRootToastObject } from '@base-ui/react/toast';\nimport { Toast as BaseToast } from '@base-ui/react/toast';\nimport { defineComponent } from '@vtex/fs-core';\nimport type { ComponentPropsWithRef, ReactNode } from 'react';\nimport { Children } from 'react';\nimport { useIntl } from '../../sdk/i18n/client.js';\n\n/** The queued toast object `useToast().toasts` returns and `ToastRoot` renders. */\nexport type ToastObject = ToastRootToastObject;\nexport type { ToastManager } from '@base-ui/react/toast';\n\ntype SwipeDirection = 'up' | 'down' | 'left' | 'right';\n\nexport type ToastProviderProps = Readonly<{\n /** Max concurrent toasts before older ones are marked limited. */\n limit?: number;\n /** Default auto-dismiss delay (ms); `0` disables. */\n timeout?: number;\n /** External manager for triggering toasts outside React (e.g. a non-component module). */\n toastManager?: ToastManager;\n children?: ReactNode;\n}>;\n\nexport type ToastPortalProps = Readonly<{\n className?: string;\n children?: ReactNode;\n}>;\n\nexport type ToastViewportProps = ComponentPropsWithRef<'div'>;\n\nexport type ToastRootProps = Readonly<{\n /** The queued toast to render, from `useToast().toasts`. */\n toast: ToastObject;\n /** Directions the toast can be swiped to dismiss. @default ['down', 'right'] */\n swipeDirection?: SwipeDirection | SwipeDirection[];\n className?: string;\n children?: ReactNode;\n}>;\n\nexport type ToastTitleProps = ComponentPropsWithRef<'h2'>;\n\nexport type ToastDescriptionProps = ComponentPropsWithRef<'p'>;\n\nexport type ToastActionProps = ComponentPropsWithRef<'button'>;\n\nexport type ToastCloseProps = ComponentPropsWithRef<'button'>;\n\nexport const ToastProviderDefinition = defineComponent<ToastProviderProps>({\n name: 'ToastProvider',\n importPath: '@vtex/faststore/components',\n component: ToastProvider,\n editor: { label: 'Toast Provider', category: 'layout' },\n schema: {\n limit: { type: 'number', default: 3, label: 'Max Concurrent Toasts' },\n timeout: { type: 'number', default: 5000, label: 'Default Auto-Dismiss (ms)' },\n },\n guideline:\n 'Mount once at the layout root to enable toasts anywhere in the tree. Compose as: ToastProvider > ToastPortal > ToastViewport (a childless viewport renders the active toasts itself; add ToastRoot children only to override). Components trigger toasts via the useToast() hook, not through page-schema composition.',\n});\n\nexport const ToastPortalDefinition = defineComponent<ToastPortalProps>({\n name: 'ToastPortal',\n importPath: '@vtex/faststore/components',\n component: ToastPortal,\n editor: { label: 'Toast Portal', category: 'layout' },\n schema: {},\n guideline:\n 'Renders its children (ToastViewport) outside the DOM tree, into document.body. Direct child of ToastProvider.',\n});\n\nexport const ToastViewportDefinition = defineComponent<ToastViewportProps>({\n name: 'ToastViewport',\n importPath: '@vtex/faststore/components',\n component: ToastViewport,\n editor: { label: 'Toast Viewport', category: 'layout' },\n schema: {},\n guideline:\n 'The fixed-position stack container for all active toasts. With no children it renders every active toast itself (title, description, action and a localized close button), so a page schema needs only ToastProvider > ToastPortal > ToastViewport. Pass children (a ToastRoot per useToast().toasts entry) to take control of the markup. Position it with a swatch on data-fs-toast-viewport (e.g. bottom-right vs. top-center). Direct child of ToastPortal.',\n});\n\nexport const ToastRootDefinition = defineComponent<ToastRootProps>({\n name: 'ToastRoot',\n importPath: '@vtex/faststore/components',\n component: ToastRoot,\n editor: { label: 'Toast Root', category: 'layout' },\n schema: {},\n guideline:\n 'One instance per active toast. A childless ToastViewport renders these itself; compose ToastRoot only to override that, by mapping over useToast().toasts. Compose as: ToastRoot > (Icon + ToastTitle + ToastDescription + ToastAction + ToastClose), all optional except at least one of Title/Description.',\n});\n\nexport const ToastTitleDefinition = defineComponent<ToastTitleProps>({\n name: 'ToastTitle',\n importPath: '@vtex/faststore/components',\n component: ToastTitle,\n editor: { label: 'Toast Title', category: 'layout' },\n schema: {},\n guideline: 'Renders the toast.title automatically when composed with no children. Direct child of ToastRoot.',\n});\n\nexport const ToastDescriptionDefinition = defineComponent<ToastDescriptionProps>({\n name: 'ToastDescription',\n importPath: '@vtex/faststore/components',\n component: ToastDescription,\n editor: { label: 'Toast Description', category: 'layout' },\n schema: {},\n guideline:\n 'Renders the toast.description automatically when composed with no children. Direct child of ToastRoot, after ToastTitle.',\n});\n\nexport const ToastActionDefinition = defineComponent<ToastActionProps>({\n name: 'ToastAction',\n importPath: '@vtex/faststore/components',\n component: ToastAction,\n editor: { label: 'Toast Action', category: 'action' },\n schema: {},\n guideline: \"Reversible-action button (e.g. Undo) forwarding the toast's actionProps. Omit for toasts with no action.\",\n});\n\nexport const ToastCloseDefinition = defineComponent<ToastCloseProps>({\n name: 'ToastClose',\n importPath: '@vtex/faststore/components',\n component: ToastClose,\n editor: { label: 'Toast Close', category: 'action' },\n schema: {},\n guideline: 'Dismisses the nearest ancestor ToastRoot when clicked. Can appear alongside or instead of ToastAction.',\n});\n\nexport function ToastProvider({ limit = 3, timeout = 5000, toastManager, children }: ToastProviderProps) {\n return (\n <BaseToast.Provider limit={limit} timeout={timeout} toastManager={toastManager}>\n {children}\n </BaseToast.Provider>\n );\n}\n\nexport function ToastPortal({ className, children }: ToastPortalProps) {\n return <BaseToast.Portal className={className}>{children}</BaseToast.Portal>;\n}\n\nfunction hasChildren(children: ReactNode): boolean {\n return Children.toArray(children).length > 0;\n}\n\nfunction DefaultToastList() {\n const intl = useIntl();\n const { toasts } = useToast();\n\n return toasts.map((toast) => (\n <ToastRoot key={toast.id} toast={toast}>\n <ToastTitle />\n <ToastDescription />\n <ToastAction />\n <ToastClose aria-label={intl.formatMessage({ id: 'fs/toast.dismiss' })}>\n <span aria-hidden=\"true\">×</span>\n </ToastClose>\n </ToastRoot>\n ));\n}\n\nexport function ToastViewport({ className, children, 'aria-label': ariaLabel, ...props }: ToastViewportProps) {\n const intl = useIntl();\n\n return (\n <BaseToast.Viewport\n {...props}\n aria-label={ariaLabel ?? intl.formatMessage({ id: 'fs/toast.region' })}\n className={className}\n render={(renderProps, state) => (\n <div\n {...renderProps}\n data-fs-toast-viewport=\"\"\n data-fs-toast-viewport-expanded={state.expanded ? '' : undefined}\n >\n {hasChildren(children) ? children : <DefaultToastList />}\n </div>\n )}\n />\n );\n}\n\n// Uses Base UI's `render` prop (rather than plain prop-forwarding, unlike the rest of this file) so\n// `data-fs-toast-root-type`/`-limited`/`-swiping` can mirror internal render state (`state.type`,\n// `state.limited`, `state.swiping`) that is never exposed back to us as a prop.\nexport function ToastRoot({ toast, swipeDirection, className, children }: ToastRootProps) {\n return (\n <BaseToast.Root\n toast={toast}\n swipeDirection={swipeDirection}\n className={className}\n render={(renderProps, state) => (\n <div\n {...renderProps}\n data-fs-toast-root=\"\"\n data-fs-toast-root-type={state.type}\n data-fs-toast-root-limited={state.limited ? '' : undefined}\n data-fs-toast-root-swiping={state.swiping ? '' : undefined}\n >\n {children}\n </div>\n )}\n />\n );\n}\n\nexport function ToastTitle({ className, children, ...props }: ToastTitleProps) {\n return (\n <BaseToast.Title {...props} className={className} data-fs-toast-title=\"\">\n {children}\n </BaseToast.Title>\n );\n}\n\nexport function ToastDescription({ className, children, ...props }: ToastDescriptionProps) {\n return (\n <BaseToast.Description {...props} className={className} data-fs-toast-description=\"\">\n {children}\n </BaseToast.Description>\n );\n}\n\nexport function ToastAction({ className, children, ...props }: ToastActionProps) {\n return (\n <BaseToast.Action {...props} className={className} data-fs-toast-action=\"\">\n {children}\n </BaseToast.Action>\n );\n}\n\nexport function ToastClose({ className, children, ...props }: ToastCloseProps) {\n return (\n <BaseToast.Close {...props} className={className} data-fs-toast-close=\"\">\n {children}\n </BaseToast.Close>\n );\n}\n\n/** Thin re-export of Base UI's `useToastManager()` — see Key Decision 1 in the spec. */\nexport const useToast = BaseToast.useToastManager;\n\nexport const Toast = {\n Provider: ToastProvider,\n Portal: ToastPortal,\n Viewport: ToastViewport,\n Root: ToastRoot,\n Title: ToastTitle,\n Description: ToastDescription,\n Action: ToastAction,\n Close: ToastClose,\n};\n"],"mappings":"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"}
|