@vtex/faststore 0.0.4 → 0.0.6

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.
Files changed (306) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/dist/actions.json +181 -0
  3. package/dist/catalog.json +1595 -481
  4. package/dist/client.d.ts +2 -1
  5. package/dist/client.js +2 -1
  6. package/dist/components.d.ts +31 -7
  7. package/dist/components.js +35 -13
  8. package/dist/content-types.json +73 -0
  9. package/dist/docs/access-code-sign-in.md +1 -1
  10. package/dist/docs/account-access-gate.md +153 -0
  11. package/dist/docs/account-entry-point.md +1 -2
  12. package/dist/docs/account-menu.md +164 -0
  13. package/dist/docs/address-summary.md +24 -3
  14. package/dist/docs/alert-dialog.md +204 -0
  15. package/dist/docs/billing-address.md +284 -0
  16. package/dist/docs/buy-button.md +1 -1
  17. package/dist/docs/card-entry.md +250 -0
  18. package/dist/docs/cardholder-document.md +142 -0
  19. package/dist/docs/cart.md +1 -1
  20. package/dist/docs/client-preferences-fieldset.md +148 -0
  21. package/dist/docs/client-preferences.md +2 -1
  22. package/dist/docs/client-profile-fieldset.md +184 -0
  23. package/dist/docs/client-profile.md +1 -1
  24. package/dist/docs/document-field.md +58 -4
  25. package/dist/docs/field.md +317 -0
  26. package/dist/docs/form.md +307 -0
  27. package/dist/docs/identity-edit.md +6 -6
  28. package/dist/docs/identity-summary.md +5 -5
  29. package/dist/docs/installments.md +248 -0
  30. package/dist/docs/my-account-profile.md +1 -0
  31. package/dist/docs/order-placed-payment-summary.md +138 -0
  32. package/dist/docs/payment-method-badges.md +232 -0
  33. package/dist/docs/payment-methods.md +1 -0
  34. package/dist/docs/payment.md +218 -0
  35. package/dist/docs/phone-field.md +58 -4
  36. package/dist/docs/place-order.md +157 -0
  37. package/dist/docs/save-card.md +186 -0
  38. package/dist/docs/saved-cards.md +218 -0
  39. package/dist/docs/select.md +465 -0
  40. package/dist/docs/session.md +1 -1
  41. package/dist/docs/shipping-address.md +110 -258
  42. package/dist/docs/sign-in-redirect.md +1 -1
  43. package/dist/index.d.ts +4 -1
  44. package/dist/internal/client.d.ts +3 -1
  45. package/dist/internal/client.js +3 -1
  46. package/dist/matter/access-code-sign-in/access-code-sign-in.js +9 -8
  47. package/dist/matter/access-code-sign-in/access-code-sign-in.js.map +1 -1
  48. package/dist/matter/account-access-gate/account-access-gate.d.ts +86 -0
  49. package/dist/matter/account-access-gate/account-access-gate.js +283 -0
  50. package/dist/matter/account-access-gate/account-access-gate.js.map +1 -0
  51. package/dist/matter/account-access-gate/sign-out-intent.d.ts +17 -0
  52. package/dist/matter/account-access-gate/sign-out-intent.js +62 -0
  53. package/dist/matter/account-access-gate/sign-out-intent.js.map +1 -0
  54. package/dist/matter/account-entry-point/account-entry-point.js +2 -2
  55. package/dist/matter/account-entry-point/account-entry-point.js.map +1 -1
  56. package/dist/matter/account-menu/account-menu.d.ts +88 -0
  57. package/dist/matter/account-menu/account-menu.js +246 -0
  58. package/dist/matter/account-menu/account-menu.js.map +1 -0
  59. package/dist/matter/billing-address/billing-address.d.ts +165 -0
  60. package/dist/matter/billing-address/billing-address.js +408 -0
  61. package/dist/matter/billing-address/billing-address.js.map +1 -0
  62. package/dist/matter/card-entry/card-capture.d.ts +25 -0
  63. package/dist/matter/card-entry/card-capture.js +25 -0
  64. package/dist/matter/card-entry/card-capture.js.map +1 -0
  65. package/dist/matter/card-entry/card-entry.d.ts +120 -0
  66. package/dist/matter/card-entry/card-entry.js +832 -0
  67. package/dist/matter/card-entry/card-entry.js.map +1 -0
  68. package/dist/matter/cardholder-document/cardholder-document.d.ts +45 -0
  69. package/dist/matter/cardholder-document/cardholder-document.js +70 -0
  70. package/dist/matter/cardholder-document/cardholder-document.js.map +1 -0
  71. package/dist/matter/cart/cart.d.ts +1 -1
  72. package/dist/matter/cart/cart.js +2 -2
  73. package/dist/matter/cart/cart.js.map +1 -1
  74. package/dist/matter/client-preferences/client-preferences-fieldset.d.ts +77 -0
  75. package/dist/matter/client-preferences/client-preferences-fieldset.js +299 -0
  76. package/dist/matter/client-preferences/client-preferences-fieldset.js.map +1 -0
  77. package/dist/matter/client-preferences/client-preferences.d.ts +3 -5
  78. package/dist/matter/client-preferences/client-preferences.js +6 -6
  79. package/dist/matter/client-preferences/client-preferences.js.map +1 -1
  80. package/dist/matter/client-profile/client-profile.d.ts +4 -6
  81. package/dist/matter/client-profile/client-profile.js +9 -6
  82. package/dist/matter/client-profile/client-profile.js.map +1 -1
  83. package/dist/matter/client-profile-form/client-profile-fieldset.d.ts +119 -0
  84. package/dist/matter/client-profile-form/client-profile-fieldset.js +488 -0
  85. package/dist/matter/client-profile-form/client-profile-fieldset.js.map +1 -0
  86. package/dist/matter/delivery-options/delivery-options.js.map +1 -1
  87. package/dist/matter/identity-edit/identity-edit.js +2 -2
  88. package/dist/matter/identity-edit/identity-edit.js.map +1 -1
  89. package/dist/matter/identity-summary/identity-summary.js +2 -2
  90. package/dist/matter/identity-summary/identity-summary.js.map +1 -1
  91. package/dist/matter/installments/installments-select.d.ts +42 -0
  92. package/dist/matter/installments/installments-select.js +167 -0
  93. package/dist/matter/installments/installments-select.js.map +1 -0
  94. package/dist/matter/installments/installments.d.ts +58 -0
  95. package/dist/matter/installments/installments.js +176 -0
  96. package/dist/matter/installments/installments.js.map +1 -0
  97. package/dist/matter/installments/use-installments-selection.d.ts +29 -0
  98. package/dist/matter/installments/use-installments-selection.js +95 -0
  99. package/dist/matter/installments/use-installments-selection.js.map +1 -0
  100. package/dist/matter/my-account-profile/my-account-profile.js +5 -5
  101. package/dist/matter/my-account-profile/my-account-profile.js.map +1 -1
  102. package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.d.ts +63 -0
  103. package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js +305 -0
  104. package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js.map +1 -0
  105. package/dist/matter/payment/payment-card-capture.d.ts +19 -0
  106. package/dist/matter/payment/payment-card-capture.js +129 -0
  107. package/dist/matter/payment/payment-card-capture.js.map +1 -0
  108. package/dist/matter/payment/payment-controller.d.ts +24 -0
  109. package/dist/matter/payment/payment-controller.js +107 -0
  110. package/dist/matter/payment/payment-controller.js.map +1 -0
  111. package/dist/matter/payment/payment-method-badges.d.ts +57 -0
  112. package/dist/matter/payment/payment-method-badges.js +192 -0
  113. package/dist/matter/payment/payment-method-badges.js.map +1 -0
  114. package/dist/matter/payment/payment.d.ts +89 -0
  115. package/dist/matter/payment/payment.js +263 -0
  116. package/dist/matter/payment/payment.js.map +1 -0
  117. package/dist/matter/payment/use-payment-method-selection.d.ts +302 -0
  118. package/dist/matter/payment/use-payment-method-selection.js +458 -0
  119. package/dist/matter/payment/use-payment-method-selection.js.map +1 -0
  120. package/dist/matter/payment/use-payment-submit-gate.d.ts +111 -0
  121. package/dist/matter/payment/use-payment-submit-gate.js +144 -0
  122. package/dist/matter/payment/use-payment-submit-gate.js.map +1 -0
  123. package/dist/matter/place-order/place-order.d.ts +74 -0
  124. package/dist/matter/place-order/place-order.js +379 -0
  125. package/dist/matter/place-order/place-order.js.map +1 -0
  126. package/dist/matter/product-list/product-list.d.ts +1 -0
  127. package/dist/matter/product-list/product-list.js.map +1 -1
  128. package/dist/matter/product-shelf/product-shelf.d.ts +1 -0
  129. package/dist/matter/product-shelf/product-shelf.js +2 -0
  130. package/dist/matter/product-shelf/product-shelf.js.map +1 -1
  131. package/dist/matter/region/region.js +1 -1
  132. package/dist/matter/region/region.js.map +1 -1
  133. package/dist/matter/save-card/save-card.d.ts +49 -0
  134. package/dist/matter/save-card/save-card.js +188 -0
  135. package/dist/matter/save-card/save-card.js.map +1 -0
  136. package/dist/matter/saved-cards/saved-cards.d.ts +79 -0
  137. package/dist/matter/saved-cards/saved-cards.js +387 -0
  138. package/dist/matter/saved-cards/saved-cards.js.map +1 -0
  139. package/dist/matter/shipping-address/country-descriptors.js +20 -10
  140. package/dist/matter/shipping-address/country-descriptors.js.map +1 -1
  141. package/dist/matter/shipping-address/shipping-address.d.ts +113 -174
  142. package/dist/matter/shipping-address/shipping-address.js +481 -792
  143. package/dist/matter/shipping-address/shipping-address.js.map +1 -1
  144. package/dist/matter/shipping-simulator/shipping-simulator.js.map +1 -1
  145. package/dist/matter/variant-selector/variant-selector.js +1 -1
  146. package/dist/particles/address-summary/address-summary.d.ts +24 -0
  147. package/dist/particles/address-summary/address-summary.js +83 -2
  148. package/dist/particles/address-summary/address-summary.js.map +1 -1
  149. package/dist/particles/alert-dialog/alert-dialog.d.ts +68 -0
  150. package/dist/particles/alert-dialog/alert-dialog.js +187 -0
  151. package/dist/particles/alert-dialog/alert-dialog.js.map +1 -0
  152. package/dist/particles/checkbox/checkbox.d.ts +7 -3
  153. package/dist/particles/checkbox/checkbox.js +4 -1
  154. package/dist/particles/checkbox/checkbox.js.map +1 -1
  155. package/dist/particles/document-field/document-field.d.ts +48 -5
  156. package/dist/particles/document-field/document-field.js +189 -32
  157. package/dist/particles/document-field/document-field.js.map +1 -1
  158. package/dist/particles/field/bound-field-registry.js +52 -0
  159. package/dist/particles/field/bound-field-registry.js.map +1 -0
  160. package/dist/particles/field/field.d.ts +116 -0
  161. package/dist/particles/field/field.js +497 -6
  162. package/dist/particles/field/field.js.map +1 -1
  163. package/dist/particles/fieldset/fieldset.js +2 -2
  164. package/dist/particles/fieldset/fieldset.js.map +1 -1
  165. package/dist/particles/footer-social/footer-social.js +1 -1
  166. package/dist/particles/form/form.d.ts +104 -0
  167. package/dist/particles/form/form.js +485 -0
  168. package/dist/particles/form/form.js.map +1 -0
  169. package/dist/particles/incentives/incentives.js +1 -1
  170. package/dist/particles/phone-field/phone-field.d.ts +38 -10
  171. package/dist/particles/phone-field/phone-field.js +183 -39
  172. package/dist/particles/phone-field/phone-field.js.map +1 -1
  173. package/dist/particles/postal-code-field/postal-code-field.js +2 -2
  174. package/dist/particles/postal-code-field/postal-code-field.js.map +1 -1
  175. package/dist/particles/select/field-select.d.ts +43 -0
  176. package/dist/particles/select/field-select.js +150 -0
  177. package/dist/particles/select/field-select.js.map +1 -0
  178. package/dist/particles/select/select.d.ts +2 -0
  179. package/dist/particles/select/select.js.map +1 -1
  180. package/dist/particles/shared/compose-refs.js +21 -0
  181. package/dist/particles/shared/compose-refs.js.map +1 -0
  182. package/dist/schema.graphql +701 -2
  183. package/dist/sdk/actions/analytics-action-provider.d.ts +15 -0
  184. package/dist/sdk/actions/analytics-action-provider.js +19 -0
  185. package/dist/sdk/actions/analytics-action-provider.js.map +1 -0
  186. package/dist/sdk/actions/cart-action-provider.d.ts +1 -1
  187. package/dist/sdk/actions/cart-action-provider.js +1 -1
  188. package/dist/sdk/actions/cart-action-provider.js.map +1 -1
  189. package/dist/sdk/actions/index.d.ts +3 -1
  190. package/dist/sdk/actions/index.js +3 -1
  191. package/dist/sdk/actions/payment-action-provider.d.ts +22 -0
  192. package/dist/sdk/actions/payment-action-provider.js +26 -0
  193. package/dist/sdk/actions/payment-action-provider.js.map +1 -0
  194. package/dist/sdk/actions/session-action-provider.d.ts +1 -1
  195. package/dist/sdk/actions/session-action-provider.js +1 -1
  196. package/dist/sdk/actions/session-action-provider.js.map +1 -1
  197. package/dist/sdk/actions/shipping-action-provider.d.ts +1 -1
  198. package/dist/sdk/actions/shipping-action-provider.js +1 -1
  199. package/dist/sdk/actions/shipping-action-provider.js.map +1 -1
  200. package/dist/sdk/actions/types.d.ts +6 -2
  201. package/dist/sdk/analytics/analytics-destination.d.ts +43 -0
  202. package/dist/sdk/analytics/analytics-destination.js +90 -0
  203. package/dist/sdk/analytics/analytics-destination.js.map +1 -0
  204. package/dist/sdk/analytics/use-analytics-actions.d.ts +57 -0
  205. package/dist/sdk/analytics/use-analytics-actions.js +108 -0
  206. package/dist/sdk/analytics/use-analytics-actions.js.map +1 -0
  207. package/dist/sdk/cache/storefront-cache.js +1 -1
  208. package/dist/sdk/cache/storefront-cache.js.map +1 -1
  209. package/dist/sdk/cart/operations.d.ts +4 -4
  210. package/dist/sdk/cart/operations.js +1 -1
  211. package/dist/sdk/cart/operations.js.map +1 -1
  212. package/dist/sdk/cart/optimistic.js +1 -1
  213. package/dist/sdk/cart/optimistic.js.map +1 -1
  214. package/dist/sdk/cart/use-cart-actions.d.ts +1 -1
  215. package/dist/sdk/cart/use-cart-actions.js +4 -4
  216. package/dist/sdk/cart/use-cart-actions.js.map +1 -1
  217. package/dist/sdk/cart/use-cart-validate-on-open.js +1 -1
  218. package/dist/sdk/cart/use-cart-validate-on-open.js.map +1 -1
  219. package/dist/sdk/cart/write-gate.js +1 -1
  220. package/dist/sdk/cart/write-gate.js.map +1 -1
  221. package/dist/sdk/data/entity-resolution-context.js +31 -0
  222. package/dist/sdk/data/entity-resolution-context.js.map +1 -0
  223. package/dist/sdk/data/entity-subscriber.js +18 -8
  224. package/dist/sdk/data/entity-subscriber.js.map +1 -1
  225. package/dist/sdk/data/index.js +1 -0
  226. package/dist/sdk/data/page-reactive-data-root.d.ts +38 -2
  227. package/dist/sdk/data/page-reactive-data-root.js +4 -2
  228. package/dist/sdk/data/page-reactive-data-root.js.map +1 -1
  229. package/dist/sdk/data/reactive-data-provider.d.ts +1 -1
  230. package/dist/sdk/data/reactive-data-provider.js +8 -4
  231. package/dist/sdk/data/reactive-data-provider.js.map +1 -1
  232. package/dist/sdk/data/reactive-list-item-data-provider.d.ts +1 -1
  233. package/dist/sdk/data/reactive-list-item-data-provider.js +13 -5
  234. package/dist/sdk/data/reactive-list-item-data-provider.js.map +1 -1
  235. package/dist/sdk/data/use-reactive-data-settled.js +39 -0
  236. package/dist/sdk/data/use-reactive-data-settled.js.map +1 -0
  237. package/dist/sdk/data/use-reactive-entity.js +6 -2
  238. package/dist/sdk/data/use-reactive-entity.js.map +1 -1
  239. package/dist/sdk/generated/fragment-types.js +2 -0
  240. package/dist/sdk/generated/fragment-types.js.map +1 -1
  241. package/dist/sdk/generated/gql.js +2 -1
  242. package/dist/sdk/generated/gql.js.map +1 -1
  243. package/dist/sdk/generated/graphql.js +85 -1
  244. package/dist/sdk/generated/graphql.js.map +1 -1
  245. package/dist/sdk/i18n/messages/en-US.js +3 -0
  246. package/dist/sdk/i18n/messages/en-US.json +3 -0
  247. package/dist/sdk/i18n/messages/en-US.json.d.ts +3 -0
  248. package/dist/sdk/i18n/messages/es-ES.js +3 -0
  249. package/dist/sdk/i18n/messages/es-ES.json +3 -0
  250. package/dist/sdk/i18n/messages/pt-BR.js +3 -0
  251. package/dist/sdk/i18n/messages/pt-BR.json +3 -0
  252. package/dist/sdk/identity/operations.js.map +1 -1
  253. package/dist/sdk/identity/use-identity-actions.d.ts +1 -1
  254. package/dist/sdk/identity/use-identity-actions.js +3 -2
  255. package/dist/sdk/identity/use-identity-actions.js.map +1 -1
  256. package/dist/sdk/payment/gateway-origin.js +35 -0
  257. package/dist/sdk/payment/gateway-origin.js.map +1 -0
  258. package/dist/sdk/payment/gateway.d.ts +85 -0
  259. package/dist/sdk/payment/gateway.js +183 -0
  260. package/dist/sdk/payment/gateway.js.map +1 -0
  261. package/dist/sdk/payment/operations.d.ts +52 -0
  262. package/dist/sdk/payment/operations.js +223 -0
  263. package/dist/sdk/payment/operations.js.map +1 -0
  264. package/dist/sdk/payment/security-code-mask.js +71 -0
  265. package/dist/sdk/payment/security-code-mask.js.map +1 -0
  266. package/dist/sdk/payment/submission-registry.d.ts +33 -0
  267. package/dist/sdk/payment/submission-registry.js +58 -0
  268. package/dist/sdk/payment/submission-registry.js.map +1 -0
  269. package/dist/sdk/payment/use-payment-actions.d.ts +78 -0
  270. package/dist/sdk/payment/use-payment-actions.js +276 -0
  271. package/dist/sdk/payment/use-payment-actions.js.map +1 -0
  272. package/dist/sdk/payment/use-place-order.d.ts +65 -0
  273. package/dist/sdk/payment/use-place-order.js +640 -0
  274. package/dist/sdk/payment/use-place-order.js.map +1 -0
  275. package/dist/sdk/session/auth-operations.d.ts +1 -1
  276. package/dist/sdk/session/auth-operations.js.map +1 -1
  277. package/dist/sdk/session/use-session-actions.d.ts +1 -1
  278. package/dist/sdk/session/use-session-actions.js.map +1 -1
  279. package/dist/sdk/session/use-session-revalidation.js +65 -0
  280. package/dist/sdk/session/use-session-revalidation.js.map +1 -0
  281. package/dist/sdk/shipping/option-select-operations.d.ts +1 -1
  282. package/dist/sdk/shipping/option-select-operations.js.map +1 -1
  283. package/dist/sdk/shipping/request-timeout.js +1 -1
  284. package/dist/sdk/shipping/request-timeout.js.map +1 -1
  285. package/dist/sdk/shipping/shipping-operations.d.ts +1 -1
  286. package/dist/sdk/shipping/shipping-operations.js.map +1 -1
  287. package/dist/sdk/shipping/use-shipping-actions.d.ts +2 -2
  288. package/dist/sdk/shipping/use-shipping-actions.js +1 -1
  289. package/dist/sdk/shipping/use-shipping-actions.js.map +1 -1
  290. package/dist/sdk/state/cart.d.ts +3 -4
  291. package/dist/sdk/state/cart.js +6 -7
  292. package/dist/sdk/state/cart.js.map +1 -1
  293. package/dist/utils/loggable-error-name.js +49 -0
  294. package/dist/utils/loggable-error-name.js.map +1 -0
  295. package/dist/utils/resolve-authored-copy.js +18 -0
  296. package/dist/utils/resolve-authored-copy.js.map +1 -0
  297. package/dist/utils/safe-href.js +3 -3
  298. package/dist/utils/safe-href.js.map +1 -1
  299. package/dist/utils/substitute-template.js +33 -0
  300. package/dist/utils/substitute-template.js.map +1 -0
  301. package/package.json +2 -1
  302. package/src/styles/tailwind.css +34 -0
  303. package/dist/docs/client-profile-form.md +0 -192
  304. package/dist/matter/client-profile-form/client-profile-form.d.ts +0 -126
  305. package/dist/matter/client-profile-form/client-profile-form.js +0 -662
  306. package/dist/matter/client-profile-form/client-profile-form.js.map +0 -1
@@ -0,0 +1,165 @@
1
+ import { ComponentDefinition } from "../../core/dist/define-component.js";
2
+ import "../../core/dist/index.js";
3
+ import { ComponentActions } from "../../sdk/actions/types.js";
4
+ import { ComponentPropsWithRef } from "react";
5
+ //#region src/matter/billing-address/billing-address.d.ts
6
+ /**
7
+ * The `BillingAddress` matter (specs/billing-address.md, T11 of the Credit Card epic;
8
+ * docs/features/credit-card/rfc.md § D6). A "same as delivery" toggle (default on) plus, when off, a
9
+ * country-specific address form that persists via `$actions.payment.setBillingAddress`
10
+ * (already shipped by T4, zero consumers before this task).
11
+ *
12
+ * The shared `Address` composition RFC D6 names (shipping and billing as two control matters over
13
+ * one set of reusable particles) is DEFERRED — an implementation-time call the engineer resolved
14
+ * narrow (specs/billing-address.md Decision 1). This component builds its own controls and imports
15
+ * `countryDescriptors` from `../shipping-address/country-descriptors.js`; `matter/shipping-address/`
16
+ * is read, never modified — zero bytes of that directory change here.
17
+ *
18
+ * There is NO read-back path for a persisted billing address (specs/billing-address.md Decision 3):
19
+ * `type Payment` carries no `billingAddress` field, and `setBillingAddress` itself resolves only
20
+ * `userErrors`, discarding the mutation's own echo. This component declares no fragment and renders
21
+ * nothing below the toggle while "same as delivery" is checked, not even the delivery address
22
+ * (specs/stop-re-rendering-the-full-delivery.md, T175). The custom-address form always starts blank,
23
+ * and its own local state is the sole source of truth for what was typed.
24
+ *
25
+ * Only a boolean rides the shared `draft` (`billingAddressDifferent`, widened onto `PaymentDraft` by
26
+ * this task under sole ownership of `use-payment-method-selection.ts` — specs/billing-address.md
27
+ * Decision 5); the address itself is persisted server-side by this component's own action call, never
28
+ * passed through the draft. `setBillingAddress` is dispatched at exactly two points (Decision 9): the
29
+ * toggle's transition back to "same as delivery", and the custom form's explicit submit control —
30
+ * never on mount, never per keystroke.
31
+ *
32
+ * **`draft.billingAddressDifferent` only ever becomes `true` once `setBillingAddress` has actually
33
+ * persisted a different address (PR #544 N1).** Unchecking "same as delivery" opens the form
34
+ * (`formOpen`, local-only state below) but does not touch the draft — `gateway.ts`'s own doc comment
35
+ * ("`setBillingAddress` already persisted it … so the gateway reads it from there") is the contract
36
+ * this must not break: publishing `true` before anything is persisted would point the gateway at an
37
+ * `invoiceData` address nothing ever wrote. The engineer's own resolution for this (session of
38
+ * 2026-07-31): the new-address fields become required whenever "different" is selected, so this
39
+ * component's own submit blocks on an incomplete address (`isBillingAddressFormValid`) — but that
40
+ * alone cannot stop a shopper from declining "same as delivery" and clicking Place Order without ever
41
+ * opening the form's own submit control, which is why the draft write itself is gated on success, not
42
+ * merely the submit button.
43
+ *
44
+ * **The native `required` attribute below is cosmetic here, not an enforcement mechanism (PR #544
45
+ * N7).** This file renders no `aria-required` at all — only `required` (native HTML). There is no
46
+ * `<form>` in this render tree and the submit control is `type="button"`, so the browser's own
47
+ * constraint validation never runs — nothing in this file or its tests may claim this attribute itself
48
+ * prevents a shopper from placing an order with an unsaved address; the actual submit gate is
49
+ * `isBillingAddressFormValid`, read at the submit control's own `disabled` below. Since T38
50
+ * (specs/harden-and-verify-accessibility-across-the.md FR-6) each rendered field does carry a
51
+ * `Field.Error`, but it is driven by a local blur-tracked `touched` set and this same non-blank rule,
52
+ * never by `required`'s own native `ValidityState` — so this paragraph's point is unchanged: `required`
53
+ * itself still enforces nothing here. What this component owes, and
54
+ * does: make the gap **visible** — an inline `role="status"` notice while the form is open and nothing
55
+ * has been persisted yet — and publish that same fact (`setDraftBillingAddressUnsaved`) onto the
56
+ * shared draft, from the identical expression the notice renders from (T24,
57
+ * specs/cardholder-document-submit-gate.md FR-6). **The actual hard block lives elsewhere**: T24's
58
+ * `usePaymentSubmitGate()` reads that published fact and refuses Place Order client-side — this
59
+ * component's own job stops at publishing the fact and showing the notice, never at gating the CTA
60
+ * itself. See `specs/billing-address.md`'s Documentation Gaps #1 for the deferral this closes.
61
+ */
62
+ /**
63
+ * Local-only values for the "different" address form, keyed by the country descriptor's own
64
+ * canonical field names — a plain string index signature, not a closed set of properties, so a future
65
+ * country descriptor introducing a new field name needs no type change here (mirrors
66
+ * `FieldDescriptor.name: string`'s own deliberately untyped choice; specs/billing-address.md
67
+ * Decision 7). `postalCode` and `country` are named explicitly because this component's own logic
68
+ * reads both directly. Never carries a `recipientName` key: `PaymentBillingAddressUpdateInput` has no
69
+ * such field (Decision 4) — the render loop filters it out of whatever the descriptor lists.
70
+ */
71
+ export type BillingAddressFormDraft = Readonly<{
72
+ postalCode: string;
73
+ country: string;
74
+ [fieldName: string]: string;
75
+ }>;
76
+ export type BillingAddressProps = Omit<ComponentPropsWithRef<'div'>, 'children'> & {
77
+ /** The "same as delivery" toggle's own accessible label. */
78
+ sameAsDeliveryLabel?: string;
79
+ /** ISO 3166-1 alpha-3 default country for the custom-address form's country selector. */
80
+ defaultCountry?: string;
81
+ /** Label for the country selector inside the custom-address form. */
82
+ countryLabel?: string;
83
+ /** Label for the control that persists a custom billing address. */
84
+ submitLabel?: string;
85
+ /** Label on the submit control while the mutation is in flight. */
86
+ submitPendingLabel?: string;
87
+ /** Shown when the selected method's validator marks a billing address required. */
88
+ requiredNoticeLabel?: string;
89
+ /** Label for the recipient-name descriptor field. Not rendered by the custom-address form today
90
+ * (`OMITTED_FORM_FIELD_NAMES` — the write contract has no matching input slot, Decision 4); kept
91
+ * for parity with the other seven field labels this same map covers. */
92
+ recipientNameLabel?: string;
93
+ /** Label for the street descriptor field. */
94
+ streetLabel?: string;
95
+ /** Label for the street-number descriptor field. */
96
+ numberLabel?: string;
97
+ /** Label for the complement descriptor field. Its "(optional)" suffix is the only signal that the
98
+ * field is not required — `OPTIONAL_FORM_FIELD_NAMES` drives the actual `required` attribute
99
+ * independently, so authoring this without the suffix loses the optionality cue, not the behavior
100
+ * (R7). */
101
+ complementLabel?: string;
102
+ /** Label for the neighborhood descriptor field. Unused when the active country's descriptor has no
103
+ * `neighborhood` field (e.g. USA). */
104
+ neighborhoodLabel?: string;
105
+ /** Label for the city descriptor field. */
106
+ cityLabel?: string;
107
+ /** Label for the state descriptor field. */
108
+ stateLabel?: string;
109
+ /** Label for the postal-code descriptor field. */
110
+ postalCodeLabel?: string;
111
+ /** Shown while the form is open and no address has been persisted yet (PR #544 N7) — the shopper
112
+ * declined "same as delivery" but has not (or not yet again) had a submit succeed, so Place Order
113
+ * will bill the delivery address unless they save one first. Rendered `role="status"`, not
114
+ * `role="alert"`: it is a persistent, advisory condition of the form being open, not a one-off
115
+ * announcement reacting to a rejected action (see this file's own existing `-error` alert for that
116
+ * shape) — see `specs/billing-address.md`'s Accessibility Contract for the site count this choice is
117
+ * measured against. */
118
+ unsavedAddressNoticeLabel?: string;
119
+ /** Always-on billing-match disclaimer (requirement 12.20): tells the shopper their billing address
120
+ * must match the one their card issuer or bank statement holds, so an AVS mismatch does not get the
121
+ * order declined with no explanation on screen. Gated on this prop and `billingMatchNoticeVisible`
122
+ * only — reads no `usePayment()` value, no local state, no `$data` (FR-4), unlike the two notices
123
+ * above. */
124
+ billingMatchNoticeLabel?: string;
125
+ /** Switches the billing-match disclaimer above on or off. Defaults to `true` (Decision 5 — the
126
+ * requirement's own intent); subordinate to `billingMatchNoticeLabel.trim()`, which alone can still
127
+ * suppress an empty notice (FR-3) regardless of this prop's value. */
128
+ billingMatchNoticeVisible?: boolean;
129
+ /**
130
+ * Shown as a `Field.Error` under a required, blank, touched field (T38, FR-6/FR-7) — the same
131
+ * non-blank rule `isBillingAddressFormValid` already applies, except `complement`
132
+ * (`OPTIONAL_FORM_FIELD_NAMES`), which is never marked invalid. One prop, not one per field: every
133
+ * rendered field shares the same rule, so seven props would be seven ways to say the same sentence.
134
+ * Resolved through `resolveAuthoredCopy`.
135
+ */
136
+ fieldRequiredMessage?: string;
137
+ /** Disables the toggle, every form field, the country selector, and the submit control. */
138
+ disabled?: boolean;
139
+ /** Compiler-injected action surface; carries `payment.setBillingAddress`. */
140
+ $actions?: ComponentActions;
141
+ };
142
+ /**
143
+ * Whether the toggle reads as "same as delivery" — `true` whenever the published flag is `null`
144
+ * (never touched, the default) or `false` (explicitly reverted); only an explicit `true` means the
145
+ * shopper is on the custom-address path. Takes no closure over component state, so it is safe to call
146
+ * fresh on every render.
147
+ */
148
+ export declare function resolveSameAsDelivery(billingAddressDifferent: boolean | null | undefined): boolean;
149
+ /**
150
+ * Whether the custom-address form may be submitted. Stricter than the server's own
151
+ * `MISSING_BILLING_ADDRESS_FIELDS` floor ("sameAsDelivery is false but postalCode **or country** was
152
+ * omitted" [source: `core.graphql:2857-2858`]) — every field the active country's descriptor renders,
153
+ * except `complement` (`OPTIONAL_FORM_FIELD_NAMES`), must be non-blank (PR #544 N1 item 1: the
154
+ * engineer's own rule that the new-address fields are required once "different" is selected). Resolves
155
+ * the descriptor from `formDraft.country` itself rather than taking a second parameter, so this stays a
156
+ * single self-contained fact about one `BillingAddressFormDraft` value. `country` itself is not part of
157
+ * `descriptor.fields` (Decision 7) and is never checked here — it always carries a non-blank value from
158
+ * `defaultCountry` or the selector's own current value (review F12), so it can never be the field this
159
+ * gate would fail on.
160
+ */
161
+ export declare function isBillingAddressFormValid(formDraft: BillingAddressFormDraft): boolean;
162
+ export declare const BillingAddressDefinition: ComponentDefinition<BillingAddressProps>;
163
+ export declare function BillingAddress({ sameAsDeliveryLabel, defaultCountry, countryLabel, submitLabel, submitPendingLabel, requiredNoticeLabel, unsavedAddressNoticeLabel, billingMatchNoticeLabel, billingMatchNoticeVisible, recipientNameLabel, streetLabel, numberLabel, complementLabel, neighborhoodLabel, cityLabel, stateLabel, postalCodeLabel, fieldRequiredMessage, disabled, className, $actions: $actionsProp, ...props }: BillingAddressProps): import("react/jsx-runtime").JSX.Element | null;
164
+ //#endregion
165
+ //# sourceMappingURL=billing-address.d.ts.map
@@ -0,0 +1,408 @@
1
+ "use client";
2
+ import { defineComponent } from "../../core/dist/define-component.js";
3
+ import "../../core/dist/index.js";
4
+ import { Checkbox } from "../../particles/checkbox/checkbox.js";
5
+ import { Field } from "../../particles/field/field.js";
6
+ import { useActionsOverride } from "../../sdk/actions/actions-override-context.js";
7
+ import { resolveAuthoredCopy } from "../../utils/resolve-authored-copy.js";
8
+ import { Icon } from "../../particles/icon/icon.js";
9
+ import { Select } from "../../particles/select/select.js";
10
+ import { usePayment } from "../payment/payment.js";
11
+ import { getAvailableCountries, getCountryDescriptor } from "../shipping-address/country-descriptors.js";
12
+ import { useEffect, useId, useState } from "react";
13
+ import { jsx, jsxs } from "react/jsx-runtime";
14
+ //#region src/matter/billing-address/billing-address.tsx
15
+ /** Canonical field names the custom-address form never renders, even when a country descriptor
16
+ * lists them — because the write contract has no matching input slot (Decision 4). */
17
+ const OMITTED_FORM_FIELD_NAMES = /* @__PURE__ */ new Set(["recipientName"]);
18
+ /** Descriptor field names the custom-address form renders but never marks required, even while
19
+ * "different" is selected (PR #544 N1 item 1 — the engineer's own rule, verbatim: "if the person says
20
+ * the address is different, the new address fields must be required"). `complement` is the one
21
+ * exception: `complementLabel`'s own default already labels it optional ("Complement (optional)"),
22
+ * and neither a real-world address nor the server's own write contract treats it as load-bearing.
23
+ * Shared between the `required` attribute below and `isBillingAddressFormValid`, so the two never
24
+ * drift apart. An authored `complementLabel` that drops the "(optional)" suffix loses that visual cue
25
+ * without changing this set — the two are independent (R7, billing-address.md). */
26
+ const OPTIONAL_FORM_FIELD_NAMES = /* @__PURE__ */ new Set(["complement"]);
27
+ /**
28
+ * English override for the descriptor's own country display names (`'Brasil'`, `'Estados Unidos'`) —
29
+ * `country-descriptors.ts` is shared with `shipping-address` and out of this task's write scope
30
+ * (`matter/shipping-address/` is read-only here), and its labels are Portuguese regardless of country.
31
+ * T31 (specs/make-the-payment-components-authored-copy.md, Decision 5) turned the eight *field* labels
32
+ * this same reasoning used to justify (`FIELD_LABELS_EN`) into schema props instead, but deliberately
33
+ * left this one a plain map: a prop per ISO code does not scale the way eight named field-label props
34
+ * do, and the epic block's own wording covers field labels only. Keyed by the descriptor's own ISO
35
+ * code.
36
+ */
37
+ const COUNTRY_LABELS_EN = {
38
+ BRA: "Brazil",
39
+ USA: "United States"
40
+ };
41
+ /** Resolves a country's English display name, falling back to the descriptor's own label (then the
42
+ * raw ISO code) for a country this map does not yet cover. */
43
+ function getCountryLabel(iso) {
44
+ return COUNTRY_LABELS_EN[iso] ?? getCountryDescriptor(iso)?.label ?? iso;
45
+ }
46
+ /**
47
+ * Whether the toggle reads as "same as delivery" — `true` whenever the published flag is `null`
48
+ * (never touched, the default) or `false` (explicitly reverted); only an explicit `true` means the
49
+ * shopper is on the custom-address path. Takes no closure over component state, so it is safe to call
50
+ * fresh on every render.
51
+ */
52
+ function resolveSameAsDelivery(billingAddressDifferent) {
53
+ return billingAddressDifferent !== true;
54
+ }
55
+ /**
56
+ * Whether the custom-address form may be submitted. Stricter than the server's own
57
+ * `MISSING_BILLING_ADDRESS_FIELDS` floor ("sameAsDelivery is false but postalCode **or country** was
58
+ * omitted" [source: `core.graphql:2857-2858`]) — every field the active country's descriptor renders,
59
+ * except `complement` (`OPTIONAL_FORM_FIELD_NAMES`), must be non-blank (PR #544 N1 item 1: the
60
+ * engineer's own rule that the new-address fields are required once "different" is selected). Resolves
61
+ * the descriptor from `formDraft.country` itself rather than taking a second parameter, so this stays a
62
+ * single self-contained fact about one `BillingAddressFormDraft` value. `country` itself is not part of
63
+ * `descriptor.fields` (Decision 7) and is never checked here — it always carries a non-blank value from
64
+ * `defaultCountry` or the selector's own current value (review F12), so it can never be the field this
65
+ * gate would fail on.
66
+ */
67
+ function isBillingAddressFormValid(formDraft) {
68
+ const descriptor = getCountryDescriptor(formDraft.country);
69
+ if (!descriptor) return false;
70
+ return descriptor.fields.filter((field) => !OMITTED_FORM_FIELD_NAMES.has(field.name) && !OPTIONAL_FORM_FIELD_NAMES.has(field.name)).every((field) => (formDraft[field.name] ?? "").trim().length > 0);
71
+ }
72
+ const BillingAddressDefinition = defineComponent({
73
+ name: "BillingAddress",
74
+ importPath: "@vtex/faststore/components",
75
+ component: BillingAddress,
76
+ requiresContext: "payment",
77
+ actions: { payment: ["setBillingAddress"] },
78
+ editor: {
79
+ label: "Billing Address",
80
+ category: "commerce"
81
+ },
82
+ schema: {
83
+ sameAsDeliveryLabel: {
84
+ type: "string",
85
+ default: "Billing address same as delivery address",
86
+ label: "Same-as-delivery toggle label"
87
+ },
88
+ defaultCountry: {
89
+ type: "string",
90
+ default: "BRA",
91
+ label: "Default country (ISO-3)"
92
+ },
93
+ countryLabel: {
94
+ type: "string",
95
+ default: "Country",
96
+ label: "Country field label"
97
+ },
98
+ submitLabel: {
99
+ type: "string",
100
+ default: "Save billing address",
101
+ label: "Submit button label"
102
+ },
103
+ submitPendingLabel: {
104
+ type: "string",
105
+ default: "Saving...",
106
+ label: "Submit button pending label"
107
+ },
108
+ requiredNoticeLabel: {
109
+ type: "string",
110
+ default: "This payment method requires a billing address.",
111
+ label: "Required-billing-address notice label"
112
+ },
113
+ unsavedAddressNoticeLabel: {
114
+ type: "string",
115
+ default: "No billing address has been saved yet — the delivery address will be used unless you save one below.",
116
+ label: "Unsaved-address notice label"
117
+ },
118
+ billingMatchNoticeLabel: {
119
+ type: "string",
120
+ default: "Your billing address must match the one on your card or bank statement, or your bank may decline the order.",
121
+ label: "Billing-match disclaimer"
122
+ },
123
+ billingMatchNoticeVisible: {
124
+ type: "boolean",
125
+ default: true,
126
+ label: "Show the billing-match disclaimer"
127
+ },
128
+ recipientNameLabel: {
129
+ type: "string",
130
+ default: "Recipient's name",
131
+ label: "Recipient name field label"
132
+ },
133
+ streetLabel: {
134
+ type: "string",
135
+ default: "Street",
136
+ label: "Street field label"
137
+ },
138
+ numberLabel: {
139
+ type: "string",
140
+ default: "Number",
141
+ label: "Number field label"
142
+ },
143
+ complementLabel: {
144
+ type: "string",
145
+ default: "Complement (optional)",
146
+ label: "Complement field label"
147
+ },
148
+ neighborhoodLabel: {
149
+ type: "string",
150
+ default: "Neighborhood",
151
+ label: "Neighborhood field label"
152
+ },
153
+ cityLabel: {
154
+ type: "string",
155
+ default: "City",
156
+ label: "City field label"
157
+ },
158
+ stateLabel: {
159
+ type: "string",
160
+ default: "State",
161
+ label: "State field label"
162
+ },
163
+ postalCodeLabel: {
164
+ type: "string",
165
+ default: "Postal code",
166
+ label: "Postal code field label"
167
+ },
168
+ fieldRequiredMessage: {
169
+ type: "string",
170
+ default: "This field is required.",
171
+ label: "Field required message"
172
+ },
173
+ disabled: {
174
+ type: "boolean",
175
+ default: false,
176
+ label: "Disabled"
177
+ }
178
+ },
179
+ guideline: "Same-as-delivery toggle (default on) for the billing address; when off, mounts a country-specific address form (reusing shipping-address's country descriptors) and persists it via $actions.payment.setBillingAddress on an explicit submit control. Re-checking the toggle dispatches sameAsDelivery: true only once an address was actually persisted (otherwise it's a local no-op — there's nothing on the server to revert). Publishes only a boolean (never the address) onto the shared payment draft for usePlaceOrder to read. While the form is open and nothing has been saved yet, renders an inline status notice — the required attribute on the form's own fields is not a submit gate; Place Order can still complete billed to the delivery address if the shopper never saves. Must be inside a PaymentSectionRoot or PaymentSectionController; place as a sibling of CardEntry/SavedCards/Installments/SaveCard/PlaceOrder, never nested inside any of them. See billing-address.md."
180
+ });
181
+ function BillingAddress({ sameAsDeliveryLabel = "Billing address same as delivery address", defaultCountry = "BRA", countryLabel = "Country", submitLabel = "Save billing address", submitPendingLabel = "Saving...", requiredNoticeLabel = "This payment method requires a billing address.", unsavedAddressNoticeLabel = "No billing address has been saved yet — the delivery address will be used unless you save one below.", billingMatchNoticeLabel = "Your billing address must match the one on your card or bank statement, or your bank may decline the order.", billingMatchNoticeVisible = true, recipientNameLabel = "Recipient's name", streetLabel = "Street", numberLabel = "Number", complementLabel = "Complement (optional)", neighborhoodLabel = "Neighborhood", cityLabel = "City", stateLabel = "State", postalCodeLabel = "Postal code", fieldRequiredMessage, disabled = false, className, $actions: $actionsProp, ...props }) {
182
+ const $actions = useActionsOverride($actionsProp);
183
+ const fieldLabels = {
184
+ recipientName: recipientNameLabel,
185
+ street: streetLabel,
186
+ number: numberLabel,
187
+ complement: complementLabel,
188
+ neighborhood: neighborhoodLabel,
189
+ city: cityLabel,
190
+ state: stateLabel,
191
+ postalCode: postalCodeLabel
192
+ };
193
+ const { draft, selectedMethod, setDraftBillingAddressDifferent, setDraftBillingAddressUnsaved, placing, cardPaymentCollapsed } = usePayment();
194
+ const instanceKey = useId();
195
+ const panelId = useId();
196
+ const [formDraft, setFormDraft] = useState(() => ({
197
+ postalCode: "",
198
+ country: getCountryDescriptor(defaultCountry) ? defaultCountry : getAvailableCountries()[0] ?? defaultCountry,
199
+ street: "",
200
+ number: "",
201
+ complement: "",
202
+ neighborhood: "",
203
+ city: "",
204
+ state: ""
205
+ }));
206
+ const [pending, setPending] = useState(false);
207
+ const [error, setError] = useState(null);
208
+ const [touched, setTouched] = useState(() => /* @__PURE__ */ new Set());
209
+ const [formOpen, setFormOpen] = useState(() => !resolveSameAsDelivery(draft.billingAddressDifferent));
210
+ useEffect(() => {
211
+ setFormOpen(!resolveSameAsDelivery(draft.billingAddressDifferent));
212
+ }, [draft.billingAddressDifferent]);
213
+ const sameAsDelivery = !formOpen;
214
+ const unsavedAddressNoticeVisible = !cardPaymentCollapsed && formOpen && draft.billingAddressDifferent !== true;
215
+ useEffect(() => {
216
+ setDraftBillingAddressUnsaved(instanceKey, unsavedAddressNoticeVisible);
217
+ return () => setDraftBillingAddressUnsaved(instanceKey, false);
218
+ }, [
219
+ instanceKey,
220
+ unsavedAddressNoticeVisible,
221
+ setDraftBillingAddressUnsaved
222
+ ]);
223
+ const billingAddressRequired = selectedMethod?.validator.billingAddressRequired ?? false;
224
+ const fieldsDisabled = disabled || pending;
225
+ const requiredMessage = resolveAuthoredCopy(fieldRequiredMessage, "This field is required.");
226
+ const renderableFields = (getCountryDescriptor(formDraft.country)?.fields ?? []).filter((field) => !OMITTED_FORM_FIELD_NAMES.has(field.name));
227
+ async function handleSameAsDeliveryChange(nextSameAsDelivery) {
228
+ setError(null);
229
+ if (!nextSameAsDelivery) {
230
+ setFormOpen(true);
231
+ return;
232
+ }
233
+ if (draft.billingAddressDifferent !== true) {
234
+ setFormOpen(false);
235
+ return;
236
+ }
237
+ const setBillingAddress = $actions?.payment?.setBillingAddress;
238
+ if (!setBillingAddress) return;
239
+ setPending(true);
240
+ try {
241
+ const [firstError] = await setBillingAddress({ sameAsDelivery: true });
242
+ if (firstError) setError(firstError.message);
243
+ else {
244
+ setDraftBillingAddressDifferent(false);
245
+ setFormOpen(false);
246
+ }
247
+ } finally {
248
+ setPending(false);
249
+ }
250
+ }
251
+ function handleFieldChange(name, value) {
252
+ setFormDraft((prev) => ({
253
+ ...prev,
254
+ [name]: value
255
+ }));
256
+ }
257
+ /** Marks a field touched on its first blur (T38, FR-6). Idempotent on every later blur — a `Set`
258
+ * already containing `name` is returned unchanged, so this never triggers a redundant re-render. */
259
+ function handleFieldBlur(name) {
260
+ setTouched((prev) => prev.has(name) ? prev : new Set(prev).add(name));
261
+ }
262
+ /**
263
+ * A rendered field is invalid once the shopper has touched it, it is blank, and it is not
264
+ * `complement` (T38, FR-6, INV-3/INV-4). Mirrors `isBillingAddressFormValid`'s own per-field rule —
265
+ * the two are never allowed to disagree about which fields are required, since both read
266
+ * `OPTIONAL_FORM_FIELD_NAMES`.
267
+ */
268
+ function isFieldInvalid(name) {
269
+ return touched.has(name) && !OPTIONAL_FORM_FIELD_NAMES.has(name) && (formDraft[name] ?? "").trim().length === 0;
270
+ }
271
+ function handleCountryChange(value) {
272
+ setFormDraft((prev) => ({
273
+ ...prev,
274
+ country: value ?? prev.country
275
+ }));
276
+ }
277
+ async function handleSubmit() {
278
+ const setBillingAddress = $actions?.payment?.setBillingAddress;
279
+ setError(null);
280
+ if (!setBillingAddress) return;
281
+ const isFieldActive = (name) => renderableFields.some((field) => field.name === name);
282
+ setPending(true);
283
+ try {
284
+ const [firstError] = await setBillingAddress({
285
+ sameAsDelivery: false,
286
+ postalCode: formDraft.postalCode,
287
+ country: formDraft.country,
288
+ ...isFieldActive("street") ? { street: formDraft.street } : {},
289
+ ...isFieldActive("number") ? { number: formDraft.number } : {},
290
+ ...isFieldActive("complement") ? { complement: formDraft.complement } : {},
291
+ ...isFieldActive("neighborhood") ? { neighborhood: formDraft.neighborhood } : {},
292
+ ...isFieldActive("city") ? { city: formDraft.city } : {},
293
+ ...isFieldActive("state") ? { state: formDraft.state } : {}
294
+ });
295
+ if (firstError) setError(firstError.message);
296
+ else setDraftBillingAddressDifferent(true);
297
+ } finally {
298
+ setPending(false);
299
+ }
300
+ }
301
+ if (cardPaymentCollapsed) return null;
302
+ return /* @__PURE__ */ jsxs("div", {
303
+ ...props,
304
+ className,
305
+ inert: placing,
306
+ "aria-disabled": placing || void 0,
307
+ "data-fs-billing-address": "",
308
+ ...placing ? { "data-fs-billing-address-placing": "" } : {},
309
+ ...pending ? { "data-fs-billing-address-pending": "" } : {},
310
+ ...sameAsDelivery ? { "data-fs-billing-address-same-as-delivery": "" } : {},
311
+ children: [
312
+ billingMatchNoticeVisible && billingMatchNoticeLabel.trim() ? /* @__PURE__ */ jsx("p", {
313
+ "data-fs-billing-address-match-notice": "",
314
+ children: billingMatchNoticeLabel
315
+ }) : null,
316
+ /* @__PURE__ */ jsxs("div", {
317
+ "data-fs-billing-address-toggle-field": "",
318
+ children: [/* @__PURE__ */ jsx(Field.Root, {
319
+ disabled: fieldsDisabled,
320
+ "data-fs-field-root": "",
321
+ children: /* @__PURE__ */ jsxs(Field.Label, { children: [/* @__PURE__ */ jsx(Checkbox.Root, {
322
+ checked: sameAsDelivery,
323
+ onCheckedChange: handleSameAsDeliveryChange,
324
+ disabled: fieldsDisabled,
325
+ "aria-controls": panelId,
326
+ children: /* @__PURE__ */ jsx(Checkbox.Indicator, { children: /* @__PURE__ */ jsx(Icon, { name: "checked" }) })
327
+ }), sameAsDeliveryLabel] })
328
+ }), billingAddressRequired ? /* @__PURE__ */ jsx("p", {
329
+ "data-fs-billing-address-required-note": "",
330
+ children: requiredNoticeLabel
331
+ }) : null]
332
+ }),
333
+ /* @__PURE__ */ jsx("div", {
334
+ id: panelId,
335
+ "data-fs-billing-address-panel": "",
336
+ hidden: sameAsDelivery,
337
+ children: sameAsDelivery ? null : /* @__PURE__ */ jsxs("div", {
338
+ "data-fs-billing-address-form": "",
339
+ children: [
340
+ unsavedAddressNoticeVisible ? /* @__PURE__ */ jsx("p", {
341
+ role: "status",
342
+ "data-fs-billing-address-unsaved-notice": "",
343
+ children: unsavedAddressNoticeLabel
344
+ }) : null,
345
+ /* @__PURE__ */ jsxs(Field.Root, {
346
+ disabled: fieldsDisabled,
347
+ "data-fs-field-root": "",
348
+ "data-fs-billing-address-field": "country",
349
+ children: [/* @__PURE__ */ jsx(Field.Label, { children: countryLabel }), /* @__PURE__ */ jsxs(Select.Root, {
350
+ value: formDraft.country,
351
+ onValueChange: handleCountryChange,
352
+ disabled: fieldsDisabled,
353
+ required: true,
354
+ children: [/* @__PURE__ */ jsxs(Select.Trigger, { children: [/* @__PURE__ */ jsx(Select.Value, { children: (value) => value ? getCountryLabel(value) : value }), /* @__PURE__ */ jsx(Select.Icon, { children: "▾" })] }), /* @__PURE__ */ jsx(Select.Portal, { children: /* @__PURE__ */ jsx(Select.Positioner, { children: /* @__PURE__ */ jsx(Select.Popup, { children: /* @__PURE__ */ jsx(Select.List, { children: getAvailableCountries().map((iso) => {
355
+ const label = getCountryLabel(iso);
356
+ return /* @__PURE__ */ jsx(Select.Item, {
357
+ value: iso,
358
+ label,
359
+ children: label
360
+ }, iso);
361
+ }) }) }) }) })]
362
+ })]
363
+ }),
364
+ renderableFields.map((field) => {
365
+ const invalid = isFieldInvalid(field.name);
366
+ return /* @__PURE__ */ jsxs(Field.Root, {
367
+ disabled: fieldsDisabled,
368
+ invalid,
369
+ "data-fs-field-root": "",
370
+ "data-fs-billing-address-field": field.name,
371
+ children: [
372
+ /* @__PURE__ */ jsx(Field.Label, { children: fieldLabels[field.name] || field.label }),
373
+ /* @__PURE__ */ jsx(Field.Control, {
374
+ value: formDraft[field.name] ?? "",
375
+ onChange: (event) => handleFieldChange(field.name, event.currentTarget.value),
376
+ onBlur: () => handleFieldBlur(field.name),
377
+ disabled: fieldsDisabled,
378
+ required: !OPTIONAL_FORM_FIELD_NAMES.has(field.name)
379
+ }),
380
+ invalid ? /* @__PURE__ */ jsx(Field.Error, {
381
+ match: true,
382
+ children: requiredMessage
383
+ }) : null
384
+ ]
385
+ }, field.name);
386
+ }),
387
+ /* @__PURE__ */ jsx("button", {
388
+ type: "button",
389
+ onClick: handleSubmit,
390
+ disabled: fieldsDisabled || !isBillingAddressFormValid(formDraft),
391
+ "data-fs-billing-address-submit": "",
392
+ children: pending ? submitPendingLabel : submitLabel
393
+ })
394
+ ]
395
+ })
396
+ }),
397
+ error ? /* @__PURE__ */ jsx("div", {
398
+ role: "alert",
399
+ "data-fs-billing-address-error": "",
400
+ children: error
401
+ }) : null
402
+ ]
403
+ });
404
+ }
405
+ //#endregion
406
+ export { BillingAddress, BillingAddressDefinition, isBillingAddressFormValid, resolveSameAsDelivery };
407
+
408
+ //# sourceMappingURL=billing-address.js.map