@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.
Files changed (488) hide show
  1. package/CHANGELOG.md +99 -0
  2. package/dist/actions.json +152 -1
  3. package/dist/catalog.json +2541 -1278
  4. package/dist/cli/UnreachableCaseError-Crd168Vu.js +10 -0
  5. package/dist/cli/UnreachableCaseError-Crd168Vu.js.map +1 -0
  6. package/dist/cli/cacheControl-CEojH_TM.js +158 -0
  7. package/dist/cli/cacheControl-CEojH_TM.js.map +1 -0
  8. package/dist/cli/cachePolicy-m2vASMRW.js +26 -0
  9. package/dist/cli/cachePolicy-m2vASMRW.js.map +1 -0
  10. package/dist/cli/computeCoreSchemaHash-DPJZj-qJ.js +10 -0
  11. package/dist/cli/computeCoreSchemaHash-DPJZj-qJ.js.map +1 -0
  12. package/dist/cli/default-BCQHcwbL.js +253 -0
  13. package/dist/cli/default-BCQHcwbL.js.map +1 -0
  14. package/dist/cli/disableSuggestions-yO9UqiWn.js +21 -0
  15. package/dist/cli/disableSuggestions-yO9UqiWn.js.map +1 -0
  16. package/dist/cli/dist-C1JhdHfo.js +2001 -0
  17. package/dist/cli/dist-C1JhdHfo.js.map +1 -0
  18. package/dist/cli/graphql-DG9thCDG.js +14589 -0
  19. package/dist/cli/graphql-DG9thCDG.js.map +1 -0
  20. package/dist/cli/index.d.ts +799 -0
  21. package/dist/cli/index.js +36459 -0
  22. package/dist/cli/index.js.map +1 -0
  23. package/dist/cli/index.min-BsIHDfFK.js +613 -0
  24. package/dist/cli/index.min-BsIHDfFK.js.map +1 -0
  25. package/dist/cli/inlineTrace-uLgOJ3TH.js +52 -0
  26. package/dist/cli/inlineTrace-uLgOJ3TH.js.map +1 -0
  27. package/dist/cli/internalPlugin-DnuwN4_4.js +11 -0
  28. package/dist/cli/internalPlugin-DnuwN4_4.js.map +1 -0
  29. package/dist/cli/packageVersion-DQAnIEil.js +6 -0
  30. package/dist/cli/packageVersion-DQAnIEil.js.map +1 -0
  31. package/dist/cli/rolldown-runtime-BMI-E3GI.js +44 -0
  32. package/dist/cli/schemaIsSubgraph-DoGh3OYj.js +17 -0
  33. package/dist/cli/schemaIsSubgraph-DoGh3OYj.js.map +1 -0
  34. package/dist/cli/schemaReporting-K-me-3-v.js +199 -0
  35. package/dist/cli/schemaReporting-K-me-3-v.js.map +1 -0
  36. package/dist/cli/server-runtime.js +49879 -0
  37. package/dist/cli/server-runtime.js.map +1 -0
  38. package/dist/cli/traceTreeBuilder-BIcV2U7b.js +9118 -0
  39. package/dist/cli/traceTreeBuilder-BIcV2U7b.js.map +1 -0
  40. package/dist/cli/usageReporting-Bpl8vSZX.js +10201 -0
  41. package/dist/cli/usageReporting-Bpl8vSZX.js.map +1 -0
  42. package/dist/cli/v4-CBhFvC49.js +42 -0
  43. package/dist/cli/v4-CBhFvC49.js.map +1 -0
  44. package/dist/client.d.ts +5 -1
  45. package/dist/client.js +5 -1
  46. package/dist/components.d.ts +38 -9
  47. package/dist/components.js +42 -13
  48. package/dist/content-types.json +616 -0
  49. package/dist/core/dist/define-component.d.ts +43 -1
  50. package/dist/core/dist/index.d.ts +2 -2
  51. package/dist/docs/account-access-gate.md +4 -4
  52. package/dist/docs/account-address-book.md +519 -0
  53. package/dist/docs/account-entry-point.md +1 -1
  54. package/dist/docs/account-menu-identity.md +160 -0
  55. package/dist/docs/account-menu.md +107 -24
  56. package/dist/docs/alert-dialog.md +2 -2
  57. package/dist/docs/avatar.md +103 -0
  58. package/dist/docs/billing-address.md +17 -9
  59. package/dist/docs/card-entry.md +37 -6
  60. package/dist/docs/cardholder-document.md +16 -14
  61. package/dist/docs/cart-item.md +1 -1
  62. package/dist/docs/cart.md +8 -8
  63. package/dist/docs/client-profile-fieldset.md +7 -5
  64. package/dist/docs/copy-text.md +84 -0
  65. package/dist/docs/document-field.md +8 -8
  66. package/dist/docs/footer-link-group.md +2 -2
  67. package/dist/docs/header-root.md +1 -1
  68. package/dist/docs/incentives.md +2 -2
  69. package/dist/docs/logo.md +5 -5
  70. package/dist/docs/my-account-profile.md +5 -5
  71. package/dist/docs/navigation-link-list.md +2 -2
  72. package/dist/docs/navigation-link.md +3 -3
  73. package/dist/docs/order-cancel.md +52 -0
  74. package/dist/docs/order-delivery-address.md +63 -0
  75. package/dist/docs/order-delivery-group.md +83 -0
  76. package/dist/docs/order-details-back.md +41 -0
  77. package/dist/docs/order-details-header.md +48 -0
  78. package/dist/docs/order-list-row.md +46 -0
  79. package/dist/docs/order-list-search.md +101 -0
  80. package/dist/docs/order-list-views.md +97 -0
  81. package/dist/docs/order-list.md +94 -0
  82. package/dist/docs/order-payment.md +94 -0
  83. package/dist/docs/order-placed-date.md +49 -0
  84. package/dist/docs/order-placed-payment-summary.md +13 -15
  85. package/dist/docs/order-placed.md +225 -0
  86. package/dist/docs/order-progress.md +88 -0
  87. package/dist/docs/order-status-badge.md +91 -0
  88. package/dist/docs/order-summary.md +53 -0
  89. package/dist/docs/payment-method-badges.md +14 -3
  90. package/dist/docs/place-order.md +13 -9
  91. package/dist/docs/product-shelf.md +20 -13
  92. package/dist/docs/saved-cards.md +2 -2
  93. package/dist/docs/select.md +19 -6
  94. package/dist/docs/session.md +1 -1
  95. package/dist/docs/shipping-address.md +1 -1
  96. package/dist/docs/sign-in-redirect.md +6 -6
  97. package/dist/docs/toast.md +7 -3
  98. package/dist/index.d.ts +7 -3
  99. package/dist/index.js +2 -1
  100. package/dist/internal/client.d.ts +6 -1
  101. package/dist/internal/client.js +8 -3
  102. package/dist/internal/content.d.ts +2 -2
  103. package/dist/internal/server.d.ts +8 -1
  104. package/dist/internal/server.js +8 -1
  105. package/dist/matter/account-access-gate/account-access-gate.d.ts +2 -1
  106. package/dist/matter/account-access-gate/account-access-gate.js +19 -16
  107. package/dist/matter/account-access-gate/account-access-gate.js.map +1 -1
  108. package/dist/matter/account-address-book/account-address-book-delete.d.ts +60 -0
  109. package/dist/matter/account-address-book/account-address-book-delete.js +184 -0
  110. package/dist/matter/account-address-book/account-address-book-delete.js.map +1 -0
  111. package/dist/matter/account-address-book/account-address-book-deliverability.d.ts +19 -0
  112. package/dist/matter/account-address-book/account-address-book-deliverability.js +50 -0
  113. package/dist/matter/account-address-book/account-address-book-deliverability.js.map +1 -0
  114. package/dist/matter/account-address-book/account-address-book-form-parts.d.ts +42 -0
  115. package/dist/matter/account-address-book/account-address-book-form-parts.js +146 -0
  116. package/dist/matter/account-address-book/account-address-book-form-parts.js.map +1 -0
  117. package/dist/matter/account-address-book/account-address-book-profile-notice.d.ts +25 -0
  118. package/dist/matter/account-address-book/account-address-book-profile-notice.js +72 -0
  119. package/dist/matter/account-address-book/account-address-book-profile-notice.js.map +1 -0
  120. package/dist/matter/account-address-book/account-address-book.d.ts +120 -0
  121. package/dist/matter/account-address-book/account-address-book.js +469 -0
  122. package/dist/matter/account-address-book/account-address-book.js.map +1 -0
  123. package/dist/matter/account-address-book/account-address-country-switch.js +59 -0
  124. package/dist/matter/account-address-book/account-address-country-switch.js.map +1 -0
  125. package/dist/matter/account-address-book/account-address-country.d.ts +36 -0
  126. package/dist/matter/account-address-book/account-address-country.js +151 -0
  127. package/dist/matter/account-address-book/account-address-country.js.map +1 -0
  128. package/dist/matter/account-address-book/account-address-first-line.js +11 -0
  129. package/dist/matter/account-address-book/account-address-first-line.js.map +1 -0
  130. package/dist/matter/account-address-book/account-address-form-context.d.ts +55 -0
  131. package/dist/matter/account-address-book/account-address-form-context.js +14 -0
  132. package/dist/matter/account-address-book/account-address-form-context.js.map +1 -0
  133. package/dist/matter/account-address-book/account-address-form.d.ts +85 -0
  134. package/dist/matter/account-address-book/account-address-form.js +946 -0
  135. package/dist/matter/account-address-book/account-address-form.js.map +1 -0
  136. package/dist/matter/account-address-book/account-address-postal-autofill.js +189 -0
  137. package/dist/matter/account-address-book/account-address-postal-autofill.js.map +1 -0
  138. package/dist/matter/account-address-book/account-address-record.d.ts +26 -0
  139. package/dist/matter/account-address-book/account-address-record.js +138 -0
  140. package/dist/matter/account-address-book/account-address-record.js.map +1 -0
  141. package/dist/matter/account-entry-point/account-entry-point.js +11 -11
  142. package/dist/matter/account-entry-point/account-entry-point.js.map +1 -1
  143. package/dist/matter/account-menu/account-menu.d.ts +77 -3
  144. package/dist/matter/account-menu/account-menu.js +252 -19
  145. package/dist/matter/account-menu/account-menu.js.map +1 -1
  146. package/dist/matter/account-menu/sign-out-failure.js +50 -0
  147. package/dist/matter/account-menu/sign-out-failure.js.map +1 -0
  148. package/dist/matter/account-menu-identity/account-menu-identity.d.ts +21 -0
  149. package/dist/matter/account-menu-identity/account-menu-identity.js +88 -0
  150. package/dist/matter/account-menu-identity/account-menu-identity.js.map +1 -0
  151. package/dist/matter/billing-address/billing-address.d.ts +30 -17
  152. package/dist/matter/billing-address/billing-address.js +128 -33
  153. package/dist/matter/billing-address/billing-address.js.map +1 -1
  154. package/dist/matter/breadcrumb/breadcrumb.js +2 -2
  155. package/dist/matter/breadcrumb/breadcrumb.js.map +1 -1
  156. package/dist/matter/card-entry/card-capture.js +4 -3
  157. package/dist/matter/card-entry/card-capture.js.map +1 -1
  158. package/dist/matter/card-entry/card-entry.d.ts +5 -3
  159. package/dist/matter/card-entry/card-entry.js +78 -27
  160. package/dist/matter/card-entry/card-entry.js.map +1 -1
  161. package/dist/matter/cardholder-document/cardholder-document.d.ts +10 -9
  162. package/dist/matter/cardholder-document/cardholder-document.js +36 -16
  163. package/dist/matter/cardholder-document/cardholder-document.js.map +1 -1
  164. package/dist/matter/cart/cart.d.ts +7 -2
  165. package/dist/matter/cart/cart.js +29 -26
  166. package/dist/matter/cart/cart.js.map +1 -1
  167. package/dist/matter/cart-item/cart-item.js +2 -2
  168. package/dist/matter/cart-item/cart-item.js.map +1 -1
  169. package/dist/matter/client-preferences/client-preferences-fieldset.js +2 -2
  170. package/dist/matter/client-profile-form/client-profile-fieldset.js +9 -6
  171. package/dist/matter/client-profile-form/client-profile-fieldset.js.map +1 -1
  172. package/dist/matter/identity-edit/identity-edit.js +3 -3
  173. package/dist/matter/identity-edit/identity-edit.js.map +1 -1
  174. package/dist/matter/identity-summary/identity-summary.js +4 -3
  175. package/dist/matter/identity-summary/identity-summary.js.map +1 -1
  176. package/dist/matter/my-account-profile/my-account-profile.d.ts +6 -3
  177. package/dist/matter/my-account-profile/my-account-profile.js +6 -5
  178. package/dist/matter/my-account-profile/my-account-profile.js.map +1 -1
  179. package/dist/matter/order-cancel/order-cancel.d.ts +110 -0
  180. package/dist/matter/order-cancel/order-cancel.js +344 -0
  181. package/dist/matter/order-cancel/order-cancel.js.map +1 -0
  182. package/dist/matter/order-delivery-address/order-delivery-address.d.ts +73 -0
  183. package/dist/matter/order-delivery-address/order-delivery-address.js +172 -0
  184. package/dist/matter/order-delivery-address/order-delivery-address.js.map +1 -0
  185. package/dist/matter/order-delivery-group/order-delivery-group.d.ts +128 -0
  186. package/dist/matter/order-delivery-group/order-delivery-group.js +408 -0
  187. package/dist/matter/order-delivery-group/order-delivery-group.js.map +1 -0
  188. package/dist/matter/order-details-header/order-details-header.d.ts +104 -0
  189. package/dist/matter/order-details-header/order-details-header.js +190 -0
  190. package/dist/matter/order-details-header/order-details-header.js.map +1 -0
  191. package/dist/matter/order-list/customer-orders-filter.d.ts +12 -0
  192. package/dist/matter/order-list/customer-orders-filter.js +30 -0
  193. package/dist/matter/order-list/customer-orders-filter.js.map +1 -0
  194. package/dist/matter/order-list/order-list.d.ts +121 -0
  195. package/dist/matter/order-list/order-list.js +395 -0
  196. package/dist/matter/order-list/order-list.js.map +1 -0
  197. package/dist/matter/order-list-row/order-list-row.d.ts +44 -0
  198. package/dist/matter/order-list-row/order-list-row.js +127 -0
  199. package/dist/matter/order-list-row/order-list-row.js.map +1 -0
  200. package/dist/matter/order-list-search/order-list-search.d.ts +72 -0
  201. package/dist/matter/order-list-search/order-list-search.js +296 -0
  202. package/dist/matter/order-list-search/order-list-search.js.map +1 -0
  203. package/dist/matter/order-list-views/order-list-views.d.ts +65 -0
  204. package/dist/matter/order-list-views/order-list-views.js +154 -0
  205. package/dist/matter/order-list-views/order-list-views.js.map +1 -0
  206. package/dist/matter/order-payment/order-payment.d.ts +83 -0
  207. package/dist/matter/order-payment/order-payment.js +258 -0
  208. package/dist/matter/order-payment/order-payment.js.map +1 -0
  209. package/dist/matter/order-placed/order-placed-deliveries.d.ts +145 -0
  210. package/dist/matter/order-placed/order-placed-deliveries.js +380 -0
  211. package/dist/matter/order-placed/order-placed-deliveries.js.map +1 -0
  212. package/dist/matter/order-placed/order-placed.d.ts +122 -0
  213. package/dist/matter/order-placed/order-placed.js +452 -0
  214. package/dist/matter/order-placed/order-placed.js.map +1 -0
  215. package/dist/matter/order-placed-date/order-placed-date.d.ts +45 -0
  216. package/dist/matter/order-placed-date/order-placed-date.js +92 -0
  217. package/dist/matter/order-placed-date/order-placed-date.js.map +1 -0
  218. package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.d.ts +5 -8
  219. package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js +29 -81
  220. package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js.map +1 -1
  221. package/dist/matter/order-progress/order-progress.d.ts +85 -0
  222. package/dist/matter/order-progress/order-progress.js +203 -0
  223. package/dist/matter/order-progress/order-progress.js.map +1 -0
  224. package/dist/matter/order-summary/order-summary.d.ts +81 -0
  225. package/dist/matter/order-summary/order-summary.js +192 -0
  226. package/dist/matter/order-summary/order-summary.js.map +1 -0
  227. package/dist/matter/payment/cardholder-document-rule.d.ts +35 -0
  228. package/dist/matter/payment/cardholder-document-rule.js +35 -0
  229. package/dist/matter/payment/cardholder-document-rule.js.map +1 -0
  230. package/dist/matter/payment/payment-card-capture.js +38 -23
  231. package/dist/matter/payment/payment-card-capture.js.map +1 -1
  232. package/dist/matter/payment/payment-controller.js +12 -0
  233. package/dist/matter/payment/payment-controller.js.map +1 -1
  234. package/dist/matter/payment/payment-method-badges.js +4 -2
  235. package/dist/matter/payment/payment-method-badges.js.map +1 -1
  236. package/dist/matter/payment/payment.js +12 -0
  237. package/dist/matter/payment/payment.js.map +1 -1
  238. package/dist/matter/payment/use-payment-method-selection.d.ts +39 -0
  239. package/dist/matter/payment/use-payment-method-selection.js +30 -2
  240. package/dist/matter/payment/use-payment-method-selection.js.map +1 -1
  241. package/dist/matter/payment/use-payment-submit-gate.d.ts +16 -2
  242. package/dist/matter/payment/use-payment-submit-gate.js +42 -14
  243. package/dist/matter/payment/use-payment-submit-gate.js.map +1 -1
  244. package/dist/matter/place-order/place-order.d.ts +12 -7
  245. package/dist/matter/place-order/place-order.js +126 -103
  246. package/dist/matter/place-order/place-order.js.map +1 -1
  247. package/dist/matter/pricing/pricing.js +5 -5
  248. package/dist/matter/pricing/pricing.js.map +1 -1
  249. package/dist/matter/product-shelf/product-shelf.d.ts +61 -31
  250. package/dist/matter/product-shelf/product-shelf.js +157 -57
  251. package/dist/matter/product-shelf/product-shelf.js.map +1 -1
  252. package/dist/matter/region/region.js +1 -1
  253. package/dist/matter/saved-cards/saved-cards.js +27 -15
  254. package/dist/matter/saved-cards/saved-cards.js.map +1 -1
  255. package/dist/matter/session/session.js +2 -2
  256. package/dist/matter/session/session.js.map +1 -1
  257. package/dist/matter/shipping-address/country-descriptors.d.ts +1 -0
  258. package/dist/matter/shipping-address/country-descriptors.js +23 -1
  259. package/dist/matter/shipping-address/country-descriptors.js.map +1 -1
  260. package/dist/matter/shipping-address/shipping-address.js +63 -15
  261. package/dist/matter/shipping-address/shipping-address.js.map +1 -1
  262. package/dist/matter/shipping-simulator/shipping-simulator.d.ts +1 -1
  263. package/dist/matter/shipping-simulator/shipping-simulator.js.map +1 -1
  264. package/dist/matter/sign-in-redirect/sign-in-redirect.js +48 -10
  265. package/dist/matter/sign-in-redirect/sign-in-redirect.js.map +1 -1
  266. package/dist/matter/variant-selector/variant-selector.js +2 -2
  267. package/dist/matter/variant-selector/variant-selector.js.map +1 -1
  268. package/dist/particles/address-summary/address-summary.js +2 -2
  269. package/dist/particles/address-summary/address-summary.js.map +1 -1
  270. package/dist/particles/alert-dialog/alert-dialog.d.ts +5 -1
  271. package/dist/particles/alert-dialog/alert-dialog.js +5 -2
  272. package/dist/particles/alert-dialog/alert-dialog.js.map +1 -1
  273. package/dist/particles/avatar/avatar.d.ts +17 -0
  274. package/dist/particles/avatar/avatar.js +65 -0
  275. package/dist/particles/avatar/avatar.js.map +1 -0
  276. package/dist/particles/copy-text/copy-text.d.ts +28 -0
  277. package/dist/particles/copy-text/copy-text.js +140 -0
  278. package/dist/particles/copy-text/copy-text.js.map +1 -0
  279. package/dist/particles/document-field/document-field.d.ts +34 -5
  280. package/dist/particles/document-field/document-field.js +115 -19
  281. package/dist/particles/document-field/document-field.js.map +1 -1
  282. package/dist/particles/field/field.js +1 -1
  283. package/dist/particles/field/field.js.map +1 -1
  284. package/dist/particles/footer-link-group/footer-link-group.d.ts +6 -2
  285. package/dist/particles/footer-link-group/footer-link-group.js +18 -7
  286. package/dist/particles/footer-link-group/footer-link-group.js.map +1 -1
  287. package/dist/particles/incentives/incentives.d.ts +6 -2
  288. package/dist/particles/incentives/incentives.js +7 -2
  289. package/dist/particles/incentives/incentives.js.map +1 -1
  290. package/dist/particles/logo/logo.d.ts +3 -2
  291. package/dist/particles/logo/logo.js +20 -8
  292. package/dist/particles/logo/logo.js.map +1 -1
  293. package/dist/particles/navigation-link/navigation-link.d.ts +2 -3
  294. package/dist/particles/navigation-link/navigation-link.js +4 -4
  295. package/dist/particles/navigation-link/navigation-link.js.map +1 -1
  296. package/dist/particles/navigation-link-list/navigation-link-list.d.ts +6 -2
  297. package/dist/particles/navigation-link-list/navigation-link-list.js +18 -7
  298. package/dist/particles/navigation-link-list/navigation-link-list.js.map +1 -1
  299. package/dist/particles/order-details-back/order-details-back.d.ts +28 -0
  300. package/dist/particles/order-details-back/order-details-back.js +52 -0
  301. package/dist/particles/order-details-back/order-details-back.js.map +1 -0
  302. package/dist/particles/order-status-badge/order-status-badge.d.ts +19 -0
  303. package/dist/particles/order-status-badge/order-status-badge.js +50 -0
  304. package/dist/particles/order-status-badge/order-status-badge.js.map +1 -0
  305. package/dist/particles/phone-field/phone-field.js +2 -2
  306. package/dist/particles/phone-field/phone-field.js.map +1 -1
  307. package/dist/particles/select/select.js +6 -6
  308. package/dist/particles/select/select.js.map +1 -1
  309. package/dist/particles/toast/toast.d.ts +1 -1
  310. package/dist/particles/toast/toast.js +32 -6
  311. package/dist/particles/toast/toast.js.map +1 -1
  312. package/dist/schema.graphql +1079 -54
  313. package/dist/sdk/actions/address-action-provider.d.ts +16 -0
  314. package/dist/sdk/actions/address-action-provider.js +20 -0
  315. package/dist/sdk/actions/address-action-provider.js.map +1 -0
  316. package/dist/sdk/actions/analytics-action-provider.js +1 -1
  317. package/dist/sdk/actions/index.d.ts +3 -1
  318. package/dist/sdk/actions/index.js +3 -1
  319. package/dist/sdk/actions/order-action-provider.d.ts +12 -0
  320. package/dist/sdk/actions/order-action-provider.js +16 -0
  321. package/dist/sdk/actions/order-action-provider.js.map +1 -0
  322. package/dist/sdk/actions/types.d.ts +6 -2
  323. package/dist/sdk/address/address-fields.js +38 -0
  324. package/dist/sdk/address/address-fields.js.map +1 -0
  325. package/dist/sdk/address/checkout-readiness.js +17 -0
  326. package/dist/sdk/address/checkout-readiness.js.map +1 -0
  327. package/dist/sdk/address/constants.js +60 -0
  328. package/dist/sdk/address/constants.js.map +1 -0
  329. package/dist/sdk/address/country-display.js +19 -0
  330. package/dist/sdk/address/country-display.js.map +1 -0
  331. package/dist/sdk/address/country-rules.js +30 -0
  332. package/dist/sdk/address/country-rules.js.map +1 -0
  333. package/dist/sdk/address/format-address.js +18 -0
  334. package/dist/sdk/address/format-address.js.map +1 -0
  335. package/dist/sdk/address/iso-countries.js +262 -0
  336. package/dist/sdk/address/iso-countries.js.map +1 -0
  337. package/dist/sdk/address/layouts.js +56 -0
  338. package/dist/sdk/address/layouts.js.map +1 -0
  339. package/dist/sdk/address/messages.js +97 -0
  340. package/dist/sdk/address/messages.js.map +1 -0
  341. package/dist/sdk/address/operations.d.ts +54 -0
  342. package/dist/sdk/address/operations.js +83 -0
  343. package/dist/sdk/address/operations.js.map +1 -0
  344. package/dist/sdk/address/postal-code-lookup-operations.js +23 -0
  345. package/dist/sdk/address/postal-code-lookup-operations.js.map +1 -0
  346. package/dist/sdk/address/postal-code.js +11 -0
  347. package/dist/sdk/address/postal-code.js.map +1 -0
  348. package/dist/sdk/address/schema.js +14 -0
  349. package/dist/sdk/address/schema.js.map +1 -0
  350. package/dist/sdk/address/server-fields.js +25 -0
  351. package/dist/sdk/address/server-fields.js.map +1 -0
  352. package/dist/sdk/address/switch-country.js +57 -0
  353. package/dist/sdk/address/switch-country.js.map +1 -0
  354. package/dist/sdk/address/types.d.ts +26 -0
  355. package/dist/sdk/address/use-address-actions.d.ts +29 -0
  356. package/dist/sdk/address/use-address-actions.js +247 -0
  357. package/dist/sdk/address/use-address-actions.js.map +1 -0
  358. package/dist/sdk/address/use-address-by-postal-code.js +57 -0
  359. package/dist/sdk/address/use-address-by-postal-code.js.map +1 -0
  360. package/dist/sdk/address/validate-address.js +62 -0
  361. package/dist/sdk/address/validate-address.js.map +1 -0
  362. package/dist/sdk/analytics/use-analytics-actions.js +2 -1
  363. package/dist/sdk/analytics/use-analytics-actions.js.map +1 -1
  364. package/dist/sdk/cache/storefront-cache.js +29 -4
  365. package/dist/sdk/cache/storefront-cache.js.map +1 -1
  366. package/dist/sdk/cart/use-cart-actions.js +9 -8
  367. package/dist/sdk/cart/use-cart-actions.js.map +1 -1
  368. package/dist/sdk/cart/use-cart-validate-on-open.js +2 -1
  369. package/dist/sdk/cart/use-cart-validate-on-open.js.map +1 -1
  370. package/dist/sdk/client/fetch-page-data.d.ts +11 -0
  371. package/dist/sdk/client/fetch-page-data.js +12 -1
  372. package/dist/sdk/client/fetch-page-data.js.map +1 -1
  373. package/dist/sdk/content/create-content-runtime.d.ts +22 -1
  374. package/dist/sdk/content/create-content-runtime.js +90 -9
  375. package/dist/sdk/content/create-content-runtime.js.map +1 -1
  376. package/dist/sdk/data/empty-content-value.js +16 -0
  377. package/dist/sdk/data/empty-content-value.js.map +1 -0
  378. package/dist/sdk/data/failed-fields.js +23 -0
  379. package/dist/sdk/data/failed-fields.js.map +1 -0
  380. package/dist/sdk/data/hot-data-provider.js +2 -1
  381. package/dist/sdk/data/hot-data-provider.js.map +1 -1
  382. package/dist/sdk/data/index.js +1 -1
  383. package/dist/sdk/data/page-reactive-data-root.d.ts +45 -7
  384. package/dist/sdk/data/page-reactive-data-root.js +88 -12
  385. package/dist/sdk/data/page-reactive-data-root.js.map +1 -1
  386. package/dist/sdk/data/variables-from-content.d.ts +43 -0
  387. package/dist/sdk/data/variables-from-content.js +57 -0
  388. package/dist/sdk/data/variables-from-content.js.map +1 -0
  389. package/dist/sdk/generated/fragment-types.js +2 -0
  390. package/dist/sdk/generated/fragment-types.js.map +1 -1
  391. package/dist/sdk/generated/gql.js +4 -1
  392. package/dist/sdk/generated/gql.js.map +1 -1
  393. package/dist/sdk/generated/graphql.d.ts +8 -0
  394. package/dist/sdk/generated/graphql.js +296 -1
  395. package/dist/sdk/generated/graphql.js.map +1 -1
  396. package/dist/sdk/i18n/messages/en-US.js +138 -1
  397. package/dist/sdk/i18n/messages/en-US.json +138 -1
  398. package/dist/sdk/i18n/messages/en-US.json.d.ts +137 -0
  399. package/dist/sdk/i18n/messages/es-ES.js +138 -1
  400. package/dist/sdk/i18n/messages/es-ES.json +138 -1
  401. package/dist/sdk/i18n/messages/pt-BR.js +138 -1
  402. package/dist/sdk/i18n/messages/pt-BR.json +138 -1
  403. package/dist/sdk/identity/use-identity-actions.js +5 -4
  404. package/dist/sdk/identity/use-identity-actions.js.map +1 -1
  405. package/dist/sdk/navigation/current-page.js +30 -0
  406. package/dist/sdk/navigation/current-page.js.map +1 -0
  407. package/dist/sdk/navigation/not-found-log.d.ts +28 -0
  408. package/dist/sdk/navigation/not-found-log.js +133 -0
  409. package/dist/sdk/navigation/not-found-log.js.map +1 -0
  410. package/dist/sdk/navigation/path.js +25 -0
  411. package/dist/sdk/navigation/path.js.map +1 -0
  412. package/dist/sdk/navigation/redirect.d.ts +11 -0
  413. package/dist/sdk/navigation/redirect.js +22 -0
  414. package/dist/sdk/navigation/redirect.js.map +1 -0
  415. package/dist/sdk/navigation/report.js +70 -0
  416. package/dist/sdk/navigation/report.js.map +1 -0
  417. package/dist/sdk/navigation/resolve-storefront-href.d.ts +12 -0
  418. package/dist/sdk/navigation/resolve-storefront-href.js +214 -0
  419. package/dist/sdk/navigation/resolve-storefront-href.js.map +1 -0
  420. package/dist/sdk/navigation/route-identity-provider.d.ts +11 -0
  421. package/dist/sdk/navigation/route-identity-provider.js +20 -0
  422. package/dist/sdk/navigation/route-identity-provider.js.map +1 -0
  423. package/dist/sdk/navigation/route-map-provider.d.ts +19 -0
  424. package/dist/sdk/navigation/route-map-provider.js +29 -0
  425. package/dist/sdk/navigation/route-map-provider.js.map +1 -0
  426. package/dist/sdk/navigation/storefront-link.d.ts +16 -0
  427. package/dist/sdk/navigation/storefront-link.js +66 -0
  428. package/dist/sdk/navigation/storefront-link.js.map +1 -0
  429. package/dist/sdk/navigation/types.d.ts +45 -0
  430. package/dist/sdk/navigation/use-storefront-navigation.d.ts +26 -0
  431. package/dist/sdk/navigation/use-storefront-navigation.js +73 -0
  432. package/dist/sdk/navigation/use-storefront-navigation.js.map +1 -0
  433. package/dist/sdk/navigation/use-storefront-route.d.ts +26 -0
  434. package/dist/sdk/navigation/use-storefront-route.js +87 -0
  435. package/dist/sdk/navigation/use-storefront-route.js.map +1 -0
  436. package/dist/sdk/navigation/use-storefront-search-params.d.ts +11 -0
  437. package/dist/sdk/navigation/use-storefront-search-params.js +16 -0
  438. package/dist/sdk/navigation/use-storefront-search-params.js.map +1 -0
  439. package/dist/sdk/orders/completion-badge.d.ts +8 -0
  440. package/dist/sdk/orders/completion-badge.js +47 -0
  441. package/dist/sdk/orders/completion-badge.js.map +1 -0
  442. package/dist/sdk/orders/order-operations.d.ts +19 -0
  443. package/dist/sdk/orders/order-operations.js +21 -0
  444. package/dist/sdk/orders/order-operations.js.map +1 -0
  445. package/dist/sdk/orders/use-order-actions.d.ts +23 -0
  446. package/dist/sdk/orders/use-order-actions.js +62 -0
  447. package/dist/sdk/orders/use-order-actions.js.map +1 -0
  448. package/dist/sdk/payment/gateway-origin.js +26 -13
  449. package/dist/sdk/payment/gateway-origin.js.map +1 -1
  450. package/dist/sdk/payment/gateway.d.ts +14 -2
  451. package/dist/sdk/payment/gateway.js +32 -14
  452. package/dist/sdk/payment/gateway.js.map +1 -1
  453. package/dist/sdk/payment/operations.js +11 -0
  454. package/dist/sdk/payment/operations.js.map +1 -1
  455. package/dist/sdk/payment/submission-registry.d.ts +2 -1
  456. package/dist/sdk/payment/submission-registry.js +12 -8
  457. package/dist/sdk/payment/submission-registry.js.map +1 -1
  458. package/dist/sdk/payment/use-payment-actions.d.ts +5 -3
  459. package/dist/sdk/payment/use-payment-actions.js +6 -3
  460. package/dist/sdk/payment/use-payment-actions.js.map +1 -1
  461. package/dist/sdk/payment/use-place-order.d.ts +6 -3
  462. package/dist/sdk/payment/use-place-order.js +334 -144
  463. package/dist/sdk/payment/use-place-order.js.map +1 -1
  464. package/dist/sdk/region/use-region-actions.js +2 -1
  465. package/dist/sdk/region/use-region-actions.js.map +1 -1
  466. package/dist/sdk/seo/page-alternates.d.ts +55 -0
  467. package/dist/sdk/seo/page-alternates.js +132 -0
  468. package/dist/sdk/seo/page-alternates.js.map +1 -0
  469. package/dist/sdk/session/read-server-session.d.ts +21 -0
  470. package/dist/sdk/session/read-server-session.js +61 -0
  471. package/dist/sdk/session/read-server-session.js.map +1 -0
  472. package/dist/sdk/session/use-session-actions.js +5 -4
  473. package/dist/sdk/session/use-session-actions.js.map +1 -1
  474. package/dist/sdk/session/use-session-revalidation.js +2 -1
  475. package/dist/sdk/session/use-session-revalidation.js.map +1 -1
  476. package/dist/sdk/shipping/use-shipping-actions.js +3 -2
  477. package/dist/sdk/shipping/use-shipping-actions.js.map +1 -1
  478. package/dist/utils/own-value.js +19 -0
  479. package/dist/utils/own-value.js.map +1 -0
  480. package/dist/utils/safe-href.d.ts +11 -0
  481. package/dist/utils/safe-href.js +31 -22
  482. package/dist/utils/safe-href.js.map +1 -1
  483. package/package.json +17 -2
  484. package/skills/storefront-asset/SKILL.md +111 -0
  485. package/skills/storefront-asset/references/api-side.md +153 -0
  486. package/skills/storefront-asset/references/findings.md +40 -0
  487. package/skills/storefront-asset/references/ui-side.md +94 -0
  488. package/src/styles/tailwind.css +27 -0
@@ -1 +1 @@
1
- {"version":3,"file":"place-order.js","names":[],"sources":["../../../src/matter/place-order/place-order.tsx"],"sourcesContent":["'use client';\n\nimport { defineComponent } from '@vtex/fs-core';\nimport { useRouter } from 'next/navigation';\nimport { type ComponentPropsWithRef, useEffect, useId, useLayoutEffect, useState } from 'react';\nimport { Button } from '../../particles/button/button.js';\nimport { useActionsOverride } from '../../sdk/actions/actions-override-context.js';\nimport type { ComponentActions } from '../../sdk/actions/types.js';\nimport { useDataOverride } from '../../sdk/data/data-override-context.js';\nimport type { PaymentUserError } from '../../sdk/payment/operations.js';\nimport { type PlaceOrderData, type UsePlaceOrder, usePlaceOrder } from '../../sdk/payment/use-place-order.js';\nimport { usePayment } from '../payment/payment.js';\nimport { usePaymentSubmitGate } from '../payment/use-payment-submit-gate.js';\n\n/**\n * The `PlaceOrder` CTA matter (specs/place-order.md, T14 of the Credit Card epic;\n * docs/features/credit-card/rfc.md § D9). Drives T13's `usePlaceOrder` orchestration hook and renders\n * the three v1 states the RFC names: the idle CTA, a blocking loading state while the three-call\n * sequence runs, and an inline outcome (error or success) once it settles.\n *\n * **Composes as a sibling of the card entry (T7) and the saved cards list (T12) under the payment\n * root, never nested inside either.** That placement is what lets this one CTA serve both the\n * new-card and saved-card paths — nesting it inside a card form, as the legacy `CardForm` does,\n * would force a second CTA for the saved-card path. This is a documented authoring convention, not a\n * compiler guarantee: `requiresContext: 'payment'` (ADR-0009) only fails the build when *no* ancestor\n * at any depth declares `providesContext: 'payment'` — there is no `forbidsAncestor` token, so a\n * schema that nests this component inside `CardEntry`/`SavedCards` instead of beside them still\n * compiles and still resolves the context from the payment root further up. This component throws\n * at runtime only when rendered entirely outside a `PaymentSectionRoot`/`Controller` subtree — both\n * `usePayment()` (read directly below, for `draft.billingAddressDifferent`) and `usePlaceOrder` (via\n * the submission channel those roots provide) enforce that guard, with `usePayment()` throwing first\n * since its value feeds `usePlaceOrder`'s own argument — a real, load-bearing guard, but a weaker one\n * than \"must be a sibling.\" See specs/place-order.md's open items for this gap.\n *\n * **This component never touches card data.** It declares its own thin fragment for the read-model\n * slice `usePlaceOrder` needs (`selectedMethodId`, `selectedInstallment`, `methods` — ADR-0011,\n * mirroring `PaymentSummaryData`/`PaymentSectionData`) and forwards it plus `$actions` straight into\n * the hook. The one fact it reads off `usePayment()`'s context directly is `draft.billingAddressDifferent`\n * (T11's widening of `PaymentDraft`), forwarded into `usePlaceOrder`'s own optional argument of the\n * same name so the gateway descriptor carries the shopper's choice (fix pass, PR #544 review F1) —\n * still not a card field, since `PaymentDraft` never carries one. `usePaymentSubmitGate()` (T24)\n * resolves the client-side document/billing refusal off that same context and is forwarded as\n * `usePlaceOrder`'s `submitGate` argument — an opaque `PaymentUserError | null`, never the facts\n * behind it. The hook already owns `placing`, `userErrors`, and `orderId` — including releasing\n * `placing` on every failure path — so this component only reflects that state, never re-implements it.\n *\n * `attempted` is the one bit of state this component adds, and it is not a duplicate of anything the\n * hook owns: `usePlaceOrder`'s `userErrors: []` is both the pre-attempt state and the settled-success\n * state (T13 does not disambiguate the two, by design — see `UsePlaceOrder`'s doc), so distinguishing\n * \"never attempted\" from \"attempted and succeeded\" is exactly this component's job. `succeeded` is\n * derived, not stored: `attempted && !placing && userErrors.length === 0`.\n *\n * **T29 widens both `succeeded` and the button label with the surviving `attempt` record read off\n * `usePayment()`** (specs/make-an-order-attempt-survive-a.md), never mirrored into local state:\n * `attempted`/`userErrors`/`orderId` all restart at their pre-attempt defaults on every mount, but the\n * attempt record does not, so a remount renders its truth rather than this instance's own fresh state.\n * `succeeded` is `true` whenever the record's own phase is `'settled'`, independent of `attempted`; the\n * button shows `resumeLabel` instead of `label` whenever the phase is `'sent'` or `'unresolved'` — the\n * card already left the browser (or its fate is unknown) and the next click finalizes it through\n * `usePlaceOrder`'s `resume()` rather than opening a new transaction.\n *\n * The button disables on `placing` (the required blocking state) and, deliberately, on `succeeded`\n * too — an already-placed order has nothing left to submit, and a second click risks exactly the\n * duplicate-transaction outcome T13's own concurrency guard (Decision 6) calls \"the worst outcome\n * this task's surface has\". `usePlaceOrder`'s in-flight ref is the inner guard; this is the outer one.\n * Fix pass, finding S-F1: it also disables on the *shared* `usePayment().placing`, since a second\n * composed `PlaceOrder` has no other way to learn a sibling instance already opened a transaction —\n * each `usePlaceOrder()` call owns its own, independent `inFlight` ref.\n */\n\n// ---------------------------------------------------------------------------\n// GraphQL Fragment — raw template literal, matching the merged `payment`/`payment-summary` siblings:\n// the codegen `documents` glob does not scan `src/matter/place-order*`, so the typed `graphql()`\n// factory is unavailable here; `data-component-contract.test.ts` validates this fragment against the\n// real schema and the built catalog.\n//\n// Selects exactly the three fields `PlaceOrderData` (sdk/payment/use-place-order.ts) needs — nothing\n// from `PaymentSectionData` is re-selected, and nothing card-shaped is ever in scope.\n// ---------------------------------------------------------------------------\n\nconst fragment = /* GraphQL */ `\n fragment PlaceOrderData on Query {\n payment {\n __typename\n id\n selectedMethodId\n selectedInstallment {\n __typename\n count\n value {\n amount\n currencyCode\n }\n interestRate\n }\n methods {\n __typename\n id\n groupName\n }\n }\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Props\n// ---------------------------------------------------------------------------\n\nexport type PlaceOrderProps = ComponentPropsWithRef<'div'> & {\n /** CTA label while idle. */\n label?: string;\n /** CTA label while the three-call sequence is in flight. */\n placingLabel?: string;\n /**\n * CTA label while a surviving attempt (T29) offers a resume — the card already left the browser\n * (`sent`) or its fate is unknown (`unresolved`), and the next click finalizes it rather than running\n * the full sequence again. Shown instead of `label`, never alongside `placingLabel` (mutually\n * exclusive — `placing` takes priority whenever both could apply).\n */\n resumeLabel?: string;\n /** Inline message shown once the sequence has settled with no `userErrors`. */\n successMessage?: string;\n /** Shown when `placeOrder()` is invoked with no registered submission for the current path. */\n missingSubmissionMessage?: string;\n /** Shown when no payment method is selected yet. */\n missingMethodMessage?: string;\n /** Shown when `startTransaction` resolves incomplete transaction data. */\n invalidTransactionMessage?: string;\n /** Shown for an infrastructure-level failure reaching the payment gateway action. */\n networkErrorMessage?: string;\n /** Shown when the selected method requires a cardholder document and none is set. */\n missingDocumentMessage?: string;\n /** Shown when the typed cardholder document fails validation. */\n invalidDocumentMessage?: string;\n /**\n * Shown instead of the two document messages above when the selected method calls for a cardholder\n * document the page is not showing — a method the card form cannot pay with, or one outside the\n * section's `group` — so the shopper has to choose another payment method (T192).\n */\n unavailableMethodMessage?: string;\n /** Shown when the shopper declined \"same as delivery\" but never saved a billing address. */\n unsavedBillingAddressMessage?: string;\n /** Shown when the new-card draft itself fails validation before ever reaching the gateway. */\n invalidCardDataMessage?: string;\n /** Shown when a saved-card submission is refused for a missing or invalid CVV. */\n invalidSecurityCodeMessage?: string;\n /** Shown when the payment gateway itself refuses the submitted card. */\n gatewayErrorMessage?: string;\n /**\n * Shown when a click lands on an order-placement attempt whose own sequence is still running — a\n * transaction this instance did not open, and which nothing here may finalize or re-run (T170).\n */\n inFlightMessage?: string;\n /**\n * Shown when the payment was handed to the gateway but the order could not be confirmed, so it may still be\n * processing (T176). Rendered as a status, never as the error alert.\n */\n unconfirmedMessage?: string;\n /**\n * Route template navigated to after a successful placement. The literal `{orderGroup}` is\n * replaced by the placed order's group, percent-encoded. Absent ⇒ no navigation. Must resolve to\n * the current page's origin — an absolute, protocol-relative, or non-http(s) template is refused\n * rather than navigated to (fail closed, dev-only warn; fix pass, finding S1).\n * e.g. \"/reserva/checkout/order-placed/{orderGroup}\"\n */\n successHref?: string;\n /** `Payment` slice forwarded by the reactive runtime (arity-1, ADR-0015) — `null` until it resolves. */\n $data?: PlaceOrderData;\n /** Compiler-injected action surface; carries `payment.startTransaction`, `payment.gatewayCallback`, `analytics.track`. */\n $actions?: ComponentActions;\n};\n\n// ---------------------------------------------------------------------------\n// Definition\n// ---------------------------------------------------------------------------\n\nexport const PlaceOrderDefinition = defineComponent<PlaceOrderProps>({\n name: 'PlaceOrder',\n importPath: '@vtex/faststore/components',\n component: PlaceOrder,\n fragment,\n fetchStrategy: 'reactive',\n actions: { payment: ['startTransaction', 'gatewayCallback'], analytics: ['track'] },\n requiresContext: 'payment',\n editor: { label: 'Place Order', category: 'commerce' },\n schema: {\n // Literals, not shared constants: the native catalog builder extracts `schema` statically and\n // silently drops an identifier-valued default (place-order.test.tsx asserts the built catalog\n // keeps every one of them, mirroring payment.tsx's group-default guard).\n label: { type: 'string', default: 'Place order', label: 'Button label' },\n placingLabel: { type: 'string', default: 'Placing order...', label: 'Button label while placing' },\n resumeLabel: {\n type: 'string',\n default: 'Complete your order',\n label: 'Button label while a surviving attempt offers a resume',\n },\n successMessage: { type: 'string', default: 'Order placed successfully.', label: 'Success message' },\n // T31 (specs/make-the-payment-components-authored-copy.md, FR-4, Decision 1) — one prop per\n // client-synthesized PaymentUserError code this CTA's alert can render, each defaulting to that\n // error's current, unchanged `message` (Decision 11 — the module-level constants that produce\n // these codes elsewhere in the payment surface keep their own message verbatim).\n missingSubmissionMessage: {\n type: 'string',\n default: 'Enter your payment details before placing the order.',\n label: 'Missing payment submission message',\n },\n missingMethodMessage: {\n type: 'string',\n default: 'Choose a payment method before placing the order.',\n label: 'Missing payment method message',\n },\n invalidTransactionMessage: {\n type: 'string',\n default: 'Unable to start the payment. Please try again.',\n label: 'Invalid transaction message',\n },\n networkErrorMessage: {\n type: 'string',\n default: 'Unable to complete the request. Please try again.',\n label: 'Network error message',\n },\n missingDocumentMessage: {\n type: 'string',\n default: 'Enter your document before placing the order.',\n label: 'Missing document message',\n },\n invalidDocumentMessage: {\n type: 'string',\n default: 'Enter a valid document before placing the order.',\n label: 'Invalid document message',\n },\n unavailableMethodMessage: {\n type: 'string',\n default: 'Choose another payment method before placing the order.',\n label: 'Unavailable payment method message',\n },\n unsavedBillingAddressMessage: {\n type: 'string',\n default: 'Save your billing address before placing the order.',\n label: 'Unsaved billing address message',\n },\n invalidCardDataMessage: {\n type: 'string',\n default: 'Enter valid card details before placing the order.',\n label: 'Invalid card data message',\n },\n invalidSecurityCodeMessage: {\n type: 'string',\n default: 'Enter a valid security code before placing the order.',\n label: 'Invalid security code message',\n },\n gatewayErrorMessage: {\n type: 'string',\n default: 'Unable to complete the payment. Please try again.',\n label: 'Gateway error message',\n },\n inFlightMessage: {\n type: 'string',\n default: 'This order is already being placed. Please wait.',\n label: 'Order already in flight message',\n },\n unconfirmedMessage: {\n type: 'string',\n default: 'We could not confirm your order yet. Your payment may still be processing, so please do not pay again.',\n label: 'Unconfirmed order message',\n },\n // No default (FR-2, T43, deliberate — see Decision 3 in specs/navigate-the-shopper-to-the-order.md):\n // absence of this prop must mean absence of the navigation effect, so a default here would silently\n // start redirecting every existing composition. Says \"token\", not the spec's own word for this —\n // see the note above warnMissingOrderGroupToken below.\n successHref: { type: 'string', label: 'Confirmation route template ({orderGroup} token)' },\n },\n guideline:\n \"The place-order CTA: invokes usePlaceOrder's three-call sequence (start transaction, the registered submission's own direct-to-gateway leg, then the gateway callback) and blocks interaction while it runs. Compose it as a sibling — never a child — of every other payment-entry leaf under the same PaymentSectionRoot or PaymentSectionController, so the one CTA serves every entry path. Renders one inline outcome after settling: the first userError's message, or successMessage on a clean settle. This component reaches no payment-sensitive input. Must be inside a payment root. See place-order.md.\",\n});\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\n/**\n * OQ-6 (2026-08-12 spec gate, `specs/navigate-the-shopper-to-the-order.md`): a `successHref` missing\n * the `{orderGroup}` placeholder is a store-authoring mistake — every order would land on the same\n * literal URL, which then renders unresolved. Fail closed instead of navigating there, and warn in\n * development only, mirroring `variant-selector.tsx`'s `warnUnresolvedAxis`.\n *\n * Named and worded around \"token\" rather than the spec's own word for this: that word contains\n * `holder` as a substring (the same reason `cardholder` matches), which trips `CARD_FIELD_PATTERN`\n * (`card-field-pattern.ts`) — the pattern `place-order.test.tsx`'s \"card-data boundary\" suite asserts\n * never matches this file's source text.\n */\nfunction warnMissingOrderGroupToken(successHref: string): void {\n if (process.env.NODE_ENV === 'production') return;\n console.warn(\n `[PlaceOrder] successHref \"${successHref}\" has no {orderGroup} token; refusing to navigate there ` +\n 'rather than sending every order to the same URL.',\n );\n}\n\n/**\n * Fix pass, finding S1 (High, CWE-601 open redirect): nothing upstream validates `successHref`'s\n * shape — the schema field is a bare `{type: 'string'}` with no pattern/format/enum, sukima never\n * inspects prop values, and this runtime's only prior check was the `{orderGroup}` substring test\n * above, which an absolute or protocol-relative template still satisfies\n * (`\"https://evil.example/{orderGroup}\"`, `\"//evil.example/{orderGroup}\"`). Left unchecked, a store\n * schema can turn this CTA into an open redirect that fires immediately after a real purchase,\n * carrying the shopper's own order group to an attacker-controlled origin.\n *\n * Resolves the template against the current origin with the same parser Next.js's own router applies\n * internally to decide \"external\" (`dispatchNavigateAction` -> `new URL(href, location.href)` ->\n * `isExternalURL`), rather than a `startsWith('/')` string check: a prefix check alone is bypassed by\n * a leading backslash or an embedded control character — `new URL('/\\\\evil.example', origin)` and\n * `new URL('/\\t/evil.example', origin)` both resolve to the `evil.example` origin under the WHATWG URL\n * parser (the same parser the browser itself applies before navigating) while starting with a single\n * `/` and not `//`. Asking the parser the same question it is asked again downstream is what makes\n * this bypass-proof; it also rejects `javascript:` and other non-http(s) schemes for free, since their\n * `.origin` is the literal string `\"null\"`, which never equals a real page origin (finding S2).\n */\nfunction isSameOriginTemplate(successHref: string): boolean {\n try {\n return new URL(successHref, window.location.origin).origin === window.location.origin;\n } catch {\n return false;\n }\n}\n\n/** Fail-closed counterpart of `warnMissingOrderGroupToken`, for a `successHref` that resolves off the\n * current origin (finding S1) — same dev-only, non-production channel. */\nfunction warnUnsafeSuccessHref(successHref: string): void {\n if (process.env.NODE_ENV === 'production') return;\n console.warn(\n `[PlaceOrder] successHref \"${successHref}\" resolves to a different origin than the current page; ` +\n 'refusing to navigate there rather than sending the shopper off-site right after a purchase.',\n );\n}\n\ntype PlaceOrderNavigateOnSuccessProps = Pick<UsePlaceOrder, 'orderId' | 'userErrors'> & {\n successHref: string;\n};\n\n/**\n * Fix pass, finding R1 (High): `useRouter()` requires an App Router context, and `PlaceOrder` used to\n * call it unconditionally — so the component could not render at all outside one, even for every\n * composition that never sets `successHref` (`place-order.stories.tsx`'s four stories, which mount\n * under no such context, were the concrete in-repo victim). Splitting the hook into its own child,\n * rendered only while `successHref` is set (see the call site below), means `useRouter()` — and the\n * App Router requirement that comes with it — is invoked only once a store has actually opted into the\n * navigation. This restores INV-4 / NFR-1 / US-3 AC1: with `successHref` absent, `PlaceOrder` neither\n * renders this child nor calls `useRouter()` at all.\n *\n * The effect is otherwise T43's original: navigates once `orderId` transitions to a non-empty value —\n * not on `succeeded` (Decision 4) — so a null or empty order group (fix pass, finding R4) and every\n * failure path never navigate. `userErrors` is also consulted directly (fix pass, finding R3 / INV-1):\n * today's real `usePlaceOrder` never settles a non-empty `orderId` alongside a non-empty `userErrors`,\n * but this component does not own that hook and should not rely on an invariant of it that T29 is\n * about to rework (spec Decision 1) — checking both fields here keeps INV-1 true by this component's\n * own construction, not by inheritance from a hook it does not control.\n *\n * Fix pass (Low finding, T29): the call site below passes `displayOrderId` (`orderId ?? the surviving\n * attempt's own orderId`), not the mount-local `orderId` this type is named for — a remounted CTA\n * whose own `usePlaceOrder()` never itself ran (it read an already-`settled` attempt straight from\n * `usePayment()`) has an empty local `orderId` forever, so passing the local value here left a store\n * whose only confirmation surface is `successHref` stuck on the payment page after exactly the remount\n * this task exists to make safe: `succeeded` rendered (from the shared attempt) but `router.replace`\n * never fired (from the mount-local, always-null `orderId`).\n */\nfunction PlaceOrderNavigateOnSuccess({ successHref, orderId, userErrors }: PlaceOrderNavigateOnSuccessProps) {\n const router = useRouter();\n\n useEffect(() => {\n if (!orderId || userErrors.length > 0) return;\n if (!isSameOriginTemplate(successHref)) {\n warnUnsafeSuccessHref(successHref);\n return;\n }\n if (!successHref.includes('{orderGroup}')) {\n warnMissingOrderGroupToken(successHref);\n return;\n }\n // `replaceAll`, not `replace` (fix pass, finding R5): a template with the placeholder repeated —\n // e.g. a route segment plus a tracking query param — passes the `includes` guard above on its\n // first occurrence alone, and `String.prototype.replace` with a string pattern substitutes only\n // that first occurrence, leaving every later `{orderGroup}` in the URL literal and unencoded.\n router.replace(successHref.replaceAll('{orderGroup}', encodeURIComponent(orderId)));\n }, [orderId, successHref, userErrors, router]);\n\n return null;\n}\n\n/** The message props FR-4 adds, unnested — one field per client-synthesized `PaymentUserError` code\n * this CTA can render. Ten from T31; `inFlightMessage` joins them for T170's own code,\n * `unconfirmedMessage` for T176's, which renders in the status node instead of the alert, and\n * `unavailableMethodMessage` for T192's. */\nexport type AuthoredPlaceOrderMessages = Readonly<{\n missingSubmissionMessage: string;\n missingMethodMessage: string;\n invalidTransactionMessage: string;\n networkErrorMessage: string;\n missingDocumentMessage: string;\n invalidDocumentMessage: string;\n unsavedBillingAddressMessage: string;\n invalidCardDataMessage: string;\n invalidSecurityCodeMessage: string;\n gatewayErrorMessage: string;\n inFlightMessage: string;\n unconfirmedMessage: string;\n unavailableMethodMessage: string;\n}>;\n\n/**\n * Builds the code -> copy map `resolveErrorMessage` reads (Decision 1, FR-4). The codes are literal\n * strings, never imported constants: importing them from card-entry.tsx / saved-cards.tsx /\n * use-place-order.ts / use-payment-submit-gate.ts / gateway.ts here would make this file a matter ->\n * matter dependency (R5) — `resolvePaymentSubmitGate` and `use-place-order.ts` stay untouched and this\n * component still imports nothing from either module beyond the hooks it already called. Exported for\n * direct unit testing, mirroring card-entry.tsx's convention for its own pure helpers:\n * place-order.test.tsx imports the five files' own real exported code constants and asserts this\n * function's returned key set equals their union.\n */\nexport function buildAuthoredErrorMessages(messages: AuthoredPlaceOrderMessages): Readonly<Record<string, string>> {\n return {\n MISSING_PAYMENT_SUBMISSION: messages.missingSubmissionMessage,\n MISSING_PAYMENT_METHOD_SELECTION: messages.missingMethodMessage,\n INVALID_TRANSACTION_DATA: messages.invalidTransactionMessage,\n NETWORK_ERROR: messages.networkErrorMessage,\n MISSING_CARDHOLDER_DOCUMENT: messages.missingDocumentMessage,\n INVALID_CARDHOLDER_DOCUMENT: messages.invalidDocumentMessage,\n UNSAVED_BILLING_ADDRESS: messages.unsavedBillingAddressMessage,\n INVALID_CARD_DATA: messages.invalidCardDataMessage,\n INVALID_SECURITY_CODE: messages.invalidSecurityCodeMessage,\n GATEWAY_ERROR: messages.gatewayErrorMessage,\n PLACE_ORDER_IN_FLIGHT: messages.inFlightMessage,\n PLACE_ORDER_UNCONFIRMED: messages.unconfirmedMessage,\n UNAVAILABLE_PAYMENT_METHOD: messages.unavailableMethodMessage,\n };\n}\n\n/**\n * Resolves the alert's rendered message for one client-synthesized `PaymentUserError`: the authored\n * copy for its `code` when this component owns one, otherwise the error's own `message` unchanged\n * (US-2 AC2 — a server-returned code this component does not author must render verbatim).\n *\n * `||`, not `??` (fix pass, finding 7): a store author can write `\"\"` for a code's authored message —\n * a valid, if unusual, `type: 'string'` prop value — and `??` only falls through on `null`/`undefined`,\n * so an authored empty string would render as an empty `role=\"alert\"` on a genuine gateway refusal,\n * leaving the shopper with no feedback at all where the unauthored default always rendered\n * `error.message`. Falling through on any falsy authored value is the exception on this surface, not\n * the rule: eight sibling `??` resolutions elsewhere (`access-code-sign-in.tsx`, `region.tsx`) stay on\n * `??`; `billing-address.tsx`'s `fieldLabels` fallback (fix pass round 2, finding N1) is fixed the\n * same way, for the same reason.\n */\nexport function resolveErrorMessage(error: PaymentUserError, authored: Readonly<Record<string, string>>): string {\n return authored[error.code] || error.message;\n}\n\nexport function PlaceOrder({\n label = 'Place order',\n placingLabel = 'Placing order...',\n resumeLabel = 'Complete your order',\n successMessage = 'Order placed successfully.',\n missingSubmissionMessage = 'Enter your payment details before placing the order.',\n missingMethodMessage = 'Choose a payment method before placing the order.',\n invalidTransactionMessage = 'Unable to start the payment. Please try again.',\n networkErrorMessage = 'Unable to complete the request. Please try again.',\n missingDocumentMessage = 'Enter your document before placing the order.',\n invalidDocumentMessage = 'Enter a valid document before placing the order.',\n unavailableMethodMessage = 'Choose another payment method before placing the order.',\n unsavedBillingAddressMessage = 'Save your billing address before placing the order.',\n invalidCardDataMessage = 'Enter valid card details before placing the order.',\n invalidSecurityCodeMessage = 'Enter a valid security code before placing the order.',\n gatewayErrorMessage = 'Unable to complete the payment. Please try again.',\n inFlightMessage = 'This order is already being placed. Please wait.',\n unconfirmedMessage = 'We could not confirm your order yet. Your payment may still be processing, so please do not pay again.',\n successHref,\n $data: $dataProp,\n $actions: $actionsProp,\n className,\n ...props\n}: PlaceOrderProps) {\n const $data = useDataOverride($dataProp);\n const $actions = useActionsOverride($actionsProp);\n // T28: this instance's own stable identity, so its publish effect below retracts only its own key\n // (Decision 4) — never a second composed PlaceOrder's still-in-flight one.\n const instanceKey = useId();\n // Also enforces the PaymentSectionRoot/PaymentSectionController ancestor: usePayment() throws\n // outside that subtree (see the module doc comment) — the first of the two guards to run, since its\n // result feeds usePlaceOrder's own argument below.\n //\n // Fix pass, finding S-F1 (High, duplicate-transaction route (a)): `sectionPlacing` is the shared\n // fact this instance also *writes* below — read back so this CTA's own `disabled` can OR it in.\n // Without this, a second composed PlaceOrder stayed enabled for the whole time a first instance's\n // sequence was open: each instance's `usePlaceOrder()` call owns its own independent `placing`/\n // `inFlight` guard, so nothing local to a second CTA ever knew a sibling had already opened a\n // transaction. This never makes this CTA's own subtree inert (FR-6/Decision 5 are untouched) — it\n // only widens the *button's* own disabled condition.\n //\n // T29: `attempt`/`setAttempt` are this same contract's own record of an order-placement attempt —\n // read here (never mirrored locally) so a remount renders the surviving truth instead of this\n // instance's own fresh, reset local state (see `succeeded`/`resumable` below).\n const { draft, placing: sectionPlacing, setPlacing, attempt, setAttempt } = usePayment();\n // T24's submit gate: an already-resolved client-side refusal (a missing/malformed cardholder\n // document, or an unsaved billing address), forwarded verbatim into usePlaceOrder's own opaque\n // argument — still not a card field, since the hook only ever receives the resolved verdict.\n const submitGate = usePaymentSubmitGate();\n const { placeOrder, placing, userErrors, orderId } = usePlaceOrder({\n $data,\n $actions,\n attempt,\n setAttempt,\n billingAddressDifferent: draft.billingAddressDifferent,\n submitGate,\n });\n const authoredErrorMessages = buildAuthoredErrorMessages({\n missingSubmissionMessage,\n missingMethodMessage,\n invalidTransactionMessage,\n networkErrorMessage,\n missingDocumentMessage,\n invalidDocumentMessage,\n unsavedBillingAddressMessage,\n invalidCardDataMessage,\n invalidSecurityCodeMessage,\n gatewayErrorMessage,\n inFlightMessage,\n unconfirmedMessage,\n unavailableMethodMessage,\n });\n const [attempted, setAttempted] = useState(false);\n\n // T28 (FR-1/FR-7): mirrors this CTA's own in-flight state onto the payment context so the sibling\n // entry leaves can freeze while an order-placement sequence is open. Retracts only this instance's\n // key on unmount, so a second composed PlaceOrder's own live sequence is never unblocked by this one\n // settling or unmounting (Decision 4, R5).\n //\n // Fix pass, finding F7 (assumption A-3): a *layout* effect, not a passive one — it must commit in\n // the same frame as `placing`'s own render, so no intermediate paint ever shows this CTA's button\n // still enabled beside leaves that are about to go inert (or the reverse, on release). A passive\n // `useEffect` here leaves a ~1-frame window where a fast key-repeat could land.\n //\n // T29 (FR-5, INV-5): the cleanup's own release is now conditional on `placing` — closed over from\n // the same render as this effect instance, so it reflects this CTA's own sequence at the moment it\n // unmounts. `placing` is true for the whole span from before `startTransaction()`/`gatewayCallback()`\n // to `run()`/`resume()` settling (unchanged by this task), so an unmount while it is still true is\n // exactly an unmount mid-sequence (the overlay closing with no `keepMounted`) — the `run()`/`resume()`\n // closure this CTA started keeps writing the surviving attempt's phase after this CTA is gone\n // (NFR-3), and nothing else will ever flip this key back, so the release must not happen. A routine\n // re-render where `placing` itself just flipped self-corrects immediately after, via this same\n // effect's next body call, which re-publishes the current value directly.\n //\n // Fix pass (Critical finding): this instance's own key in `usePayment()`'s ref-counted set is\n // therefore genuinely never retracted once abandoned here — by design, since nothing can safely\n // predict at unmount time whether the closure is about to resolve to a terminal phase or is still\n // truly in flight. What bounds the damage is `usePaymentMethodSelection`'s own `placing` derivation,\n // which folds the shared attempt's phase into every reader of this fact: once the abandoned closure\n // finally writes `refused` or `settled`, `placing` reads `false` again for this root regardless of\n // how many stale keys the ref-counted set still carries. `blockedByOtherInstance`/`resumable` below\n // read that same, already-corrected `sectionPlacing` value, so they need no separate escape hatch of\n // their own for this case.\n useLayoutEffect(() => {\n setPlacing(instanceKey, placing);\n return () => {\n if (placing) return;\n setPlacing(instanceKey, false);\n };\n }, [instanceKey, placing, setPlacing]);\n\n const [firstError] = userErrors;\n // T29: a settled attempt renders as succeeded even across a remount, where this component's own\n // `attempted`/`userErrors` restart at their pre-attempt defaults (FR-1) but the shared `attempt`\n // does not. On the same mount, `attempted && !placing && userErrors.length === 0` already covers it\n // (both a clean `run()` and a clean `resume()` settle through the same wrapper), so this only adds\n // the case local state cannot see.\n const settledAttemptOrderId = attempt && attempt.phase === 'settled' ? attempt.orderId : null;\n const succeeded = (attempted && !placing && userErrors.length === 0) || attempt?.phase === 'settled';\n // T29 (FR-2, FR-3): the next click finalizes rather than re-runs the sequence. Never true once\n // `succeeded` is (phases are mutually exclusive), and `placing` already takes priority in the label\n // below, so this needs no exclusion of its own here. The `'sent'` check is defensive-only today: no\n // write site in `run()` rests there (it writes `finalizing` directly, same tick, specs/make-an-order-\n // attempt-survive-a.md §2) — kept in case a future write path ever rests there again, rather than\n // silently treating that phase as non-resumable.\n const resumable = attempt?.phase === 'sent' || attempt?.phase === 'unresolved';\n // Local `orderId` (this mount's own settle) is preferred; a remounted CTA reading a settled attempt\n // has none of its own yet, so it falls back to the record's.\n const displayOrderId = orderId ?? settledAttemptOrderId;\n // T176 (FR-10, INV-11): the card was handed to the gateway and the order could not be confirmed, so\n // the payment may still be processing. That is a pending state, not a refusal: it renders in its own\n // status node, never in the alert stores style as an error, and never beside a success line — another\n // composed CTA can settle the shared record while this one still holds the outcome.\n const unconfirmed = firstError?.code === 'PLACE_ORDER_UNCONFIRMED';\n\n // T29: `sectionPlacing` overrides `resumable` below, not the other way round — a CTA that unmounted\n // mid-sequence (FR-5) leaves its own key published forever, because the `run()`/`resume()` closure it\n // abandoned settles through *local* state (`setPlacing(false)` inside `usePlaceOrder`'s own `settle`)\n // that has nowhere left to render once that CTA is gone, so the shared key it once set is never\n // retracted by anything else either. A resumable attempt must still be reachable through that stale\n // lock: `resume()` cannot re-pay by construction (Decision 3), so overriding a stuck `sectionPlacing`\n // here is safe exactly when it matters — a lock a *different*, still-genuinely-placing instance holds\n // is never resumable at the same time (the shared attempt is one fact — Decision 1 — so a real\n // concurrent opener keeps this attempt at `opening`/`finalizing`, not `sent`/`unresolved`).\n const blockedByOtherInstance = sectionPlacing && !resumable;\n\n function handleClick() {\n // FR-2 (T56): `setAttempted(true)` moved off the click and onto settlement, so `succeeded`\n // means \"an attempt settled with no refusals\" rather than \"a click happened and nothing is\n // in flight\". `placeOrder()` resolves; it never rejects (T13's own contract), and this\n // component reflects its state from the hook's own return value on every render rather than\n // from the awaited result — a rejection handler here would be dead code, and (review finding\n // F3) setting `attempted` from one would not \"keep the CTA disabled\": it would make\n // `succeeded` `true` with the attempt's real outcome unknown, the exact false-success frame\n // FR-2 exists to prevent.\n //\n // Review finding F1: settling `attempted` is not enough on its own past the first attempt.\n // Once an attempt settles, `attempted` stays `true` until something lowers it — and nothing\n // did, so a second click's own synchronous commit (`placeOrder` resets `userErrors` to `[]`\n // unconditionally, and a refusal leaves `placing` `false`) satisfied `succeeded` immediately,\n // one microtask before the new refusal arrived. Resetting `attempted` here, in the same\n // synchronous batch as that reset, makes every attempt — not just the first — start its own\n // click commit from \"not attempted\"; the `.then` below raises it again only once *this*\n // attempt's own outcome is in.\n setAttempted(false);\n void placeOrder().then(() => setAttempted(true));\n }\n\n return (\n <div\n {...props}\n className={className}\n data-fs-place-order=\"\"\n {...(placing ? { 'data-fs-place-order-pending': '' } : {})}\n >\n <Button\n onClick={handleClick}\n disabled={placing || succeeded || blockedByOtherInstance}\n aria-busy={placing || undefined}\n data-fs-place-order-button=\"\"\n {...(placing ? { 'data-fs-place-order-button-pending': '' } : {})}\n >\n {placing ? placingLabel : resumable ? resumeLabel : label}\n </Button>\n {firstError && !unconfirmed ? (\n <div role=\"alert\" data-fs-place-order-error=\"\">\n {resolveErrorMessage(firstError, authoredErrorMessages)}\n </div>\n ) : null}\n {firstError && unconfirmed && !succeeded ? (\n <div role=\"status\" data-fs-place-order-unconfirmed=\"\">\n {resolveErrorMessage(firstError, authoredErrorMessages)}\n </div>\n ) : null}\n {succeeded ? (\n <div role=\"status\" data-fs-place-order-success=\"\">\n <span data-fs-place-order-success-message=\"\">{successMessage}</span>\n {displayOrderId ? <span data-fs-place-order-success-order-id=\"\">{displayOrderId}</span> : null}\n </div>\n ) : null}\n {successHref != null ? (\n <PlaceOrderNavigateOnSuccess successHref={successHref} orderId={displayOrderId} userErrors={userErrors} />\n ) : null}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"place-order.js","names":[],"sources":["../../../src/matter/place-order/place-order.tsx"],"sourcesContent":["'use client';\n\nimport { defineComponent } from '@vtex/fs-core';\nimport { type ComponentPropsWithRef, useEffect, useId, useLayoutEffect, useState } from 'react';\nimport { Button } from '../../particles/button/button.js';\nimport { useActionsOverride } from '../../sdk/actions/actions-override-context.js';\nimport type { ComponentActions } from '../../sdk/actions/types.js';\nimport { useDataOverride } from '../../sdk/data/data-override-context.js';\nimport type { PageRef } from '../../sdk/navigation/types.js';\nimport { useStorefrontNavigation } from '../../sdk/navigation/use-storefront-navigation.js';\nimport type { PaymentUserError } from '../../sdk/payment/operations.js';\nimport { type PlaceOrderData, type UsePlaceOrder, usePlaceOrder } from '../../sdk/payment/use-place-order.js';\nimport { resolveSiteRelativeHref, type SafeHrefRejection } from '../../utils/safe-href.js';\nimport { usePayment } from '../payment/payment.js';\nimport { refusalTargetOf, usePaymentSubmitGate } from '../payment/use-payment-submit-gate.js';\n\n/**\n * The `PlaceOrder` CTA matter (specs/place-order.md, T14 of the Credit Card epic;\n * docs/features/credit-card/rfc.md § D9). Drives T13's `usePlaceOrder` orchestration hook and renders\n * the three v1 states the RFC names: the idle CTA, a blocking loading state while the three-call\n * sequence runs, and an inline outcome (error or success) once it settles.\n *\n * **Composes as a sibling of the card entry (T7) and the saved cards list (T12) under the payment\n * root, never nested inside either.** That placement is what lets this one CTA serve both the\n * new-card and saved-card paths — nesting it inside a card form, as the legacy `CardForm` does,\n * would force a second CTA for the saved-card path. This is a documented authoring convention, not a\n * compiler guarantee: `requiresContext: 'payment'` (ADR-0009) only fails the build when *no* ancestor\n * at any depth declares `providesContext: 'payment'` — there is no `forbidsAncestor` token, so a\n * schema that nests this component inside `CardEntry`/`SavedCards` instead of beside them still\n * compiles and still resolves the context from the payment root further up. This component throws\n * at runtime only when rendered entirely outside a `PaymentSectionRoot`/`Controller` subtree — both\n * `usePayment()` (read directly below, for `draft.billingAddressDifferent`) and `usePlaceOrder` (via\n * the submission channel those roots provide) enforce that guard, with `usePayment()` throwing first\n * since its value feeds `usePlaceOrder`'s own argument — a real, load-bearing guard, but a weaker one\n * than \"must be a sibling.\" See specs/place-order.md's open items for this gap.\n *\n * **This component never touches card data.** It declares its own thin fragment for the read-model\n * slice `usePlaceOrder` needs (`selectedMethodId`, `selectedInstallment`, `methods` — ADR-0011,\n * mirroring `PaymentSummaryData`/`PaymentSectionData`) and forwards it plus `$actions` straight into\n * the hook. The one fact it reads off `usePayment()`'s context directly is `draft.billingAddressDifferent`\n * (T11's widening of `PaymentDraft`), forwarded into `usePlaceOrder`'s own optional argument of the\n * same name so the gateway descriptor carries the shopper's choice (fix pass, PR #544 review F1) —\n * still not a card field, since `PaymentDraft` never carries one. `usePaymentSubmitGate()` (T24)\n * resolves the client-side document/billing refusal off that same context and is forwarded as\n * `usePlaceOrder`'s `submitGate` argument — an opaque `PaymentUserError | null`, never the facts\n * behind it. The hook already owns `placing`, `userErrors`, and `orderId` — including releasing\n * `placing` on every failure path — so this component only reflects that state, never re-implements it.\n *\n * `attempted` is the one bit of state this component adds, and it is not a duplicate of anything the\n * hook owns: `usePlaceOrder`'s `userErrors: []` is both the pre-attempt state and the settled-success\n * state (T13 does not disambiguate the two, by design — see `UsePlaceOrder`'s doc), so distinguishing\n * \"never attempted\" from \"attempted and succeeded\" is exactly this component's job. `succeeded` is\n * derived, not stored: `attempted && !placing && userErrors.length === 0`.\n *\n * **T29 widens both `succeeded` and the button label with the surviving `attempt` record read off\n * `usePayment()`** (specs/make-an-order-attempt-survive-a.md), never mirrored into local state:\n * `attempted`/`userErrors`/`orderId` all restart at their pre-attempt defaults on every mount, but the\n * attempt record does not, so a remount renders its truth rather than this instance's own fresh state.\n * `succeeded` is `true` whenever the record's own phase is `'settled'`, independent of `attempted`; the\n * button shows `resumeLabel` instead of `label` whenever the phase is `'sent'` or `'unresolved'` — the\n * card already left the browser (or its fate is unknown) and the next click finalizes it through\n * `usePlaceOrder`'s `resume()` rather than opening a new transaction.\n *\n * The button disables on `placing` (the required blocking state) and, deliberately, on `succeeded`\n * too — an already-placed order has nothing left to submit, and a second click risks exactly the\n * duplicate-transaction outcome T13's own concurrency guard (Decision 6) calls \"the worst outcome\n * this task's surface has\". `usePlaceOrder`'s in-flight ref is the inner guard; this is the outer one.\n * Fix pass, finding S-F1: it also disables on the *shared* `usePayment().placing`, since a second\n * composed `PlaceOrder` has no other way to learn a sibling instance already opened a transaction —\n * each `usePlaceOrder()` call owns its own, independent `inFlight` ref.\n */\n\n// ---------------------------------------------------------------------------\n// GraphQL Fragment — raw template literal, matching the merged `payment`/`payment-summary` siblings:\n// the codegen `documents` glob does not scan `src/matter/place-order*`, so the typed `graphql()`\n// factory is unavailable here; `data-component-contract.test.ts` validates this fragment against the\n// real schema and the built catalog.\n//\n// Selects exactly the three fields `PlaceOrderData` (sdk/payment/use-place-order.ts) needs — nothing\n// from `PaymentSectionData` is re-selected, and nothing card-shaped is ever in scope.\n// ---------------------------------------------------------------------------\n\nconst fragment = /* GraphQL */ `\n fragment PlaceOrderData on Query {\n payment {\n __typename\n id\n selectedMethodId\n selectedInstallment {\n __typename\n count\n value {\n amount\n currencyCode\n }\n interestRate\n }\n methods {\n __typename\n id\n groupName\n }\n }\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Props\n// ---------------------------------------------------------------------------\n\nexport type PlaceOrderProps = ComponentPropsWithRef<'div'> & {\n /** CTA label while idle. */\n label?: string;\n /** CTA label while the three-call sequence is in flight. */\n placingLabel?: string;\n /** Status message shown beside the button for as long as the order is being placed. Absent or blank renders nothing. */\n placingMessage?: string;\n /**\n * CTA label while a surviving attempt (T29) offers a resume — the card already left the browser\n * (`sent`) or its fate is unknown (`unresolved`), and the next click finalizes it rather than running\n * the full sequence again. Shown instead of `label`, never alongside `placingLabel` (mutually\n * exclusive — `placing` takes priority whenever both could apply).\n */\n resumeLabel?: string;\n /** Inline message shown once the sequence has settled with no `userErrors`. */\n successMessage?: string;\n /** Shown when `placeOrder()` is invoked with no registered submission for the current path. */\n missingSubmissionMessage?: string;\n /** Shown when no payment method is selected yet. */\n missingMethodMessage?: string;\n /** Shown when `startTransaction` resolves incomplete transaction data. */\n invalidTransactionMessage?: string;\n /** Shown for an infrastructure-level failure reaching the payment gateway action. */\n networkErrorMessage?: string;\n /** Shown when the selected method requires a cardholder document and none is set. */\n missingDocumentMessage?: string;\n /** Shown when the typed cardholder document fails validation. */\n invalidDocumentMessage?: string;\n /**\n * Shown instead of the two document messages above when the selected method calls for a cardholder\n * document the page is not showing — a method the card form cannot pay with, or one outside the\n * section's `group` — so the shopper has to choose another payment method (T192).\n */\n unavailableMethodMessage?: string;\n /** Shown when the shopper declined \"same as delivery\" but never saved a billing address. */\n unsavedBillingAddressMessage?: string;\n /** Shown when the new-card draft itself fails validation before ever reaching the gateway. */\n invalidCardDataMessage?: string;\n /** Shown when the typed card number is well-formed but no payment network the store accepts claims it (T47). */\n unsupportedNetworkMessage?: string;\n /** Shown when a saved-card submission is refused for a missing or invalid CVV. */\n invalidSecurityCodeMessage?: string;\n /** Shown when the payment gateway itself refuses the submitted card. */\n gatewayErrorMessage?: string;\n /**\n * Shown when a click lands on an order-placement attempt whose own sequence is still running — a\n * transaction this instance did not open, and which nothing here may finalize or re-run (T170).\n */\n inFlightMessage?: string;\n /**\n * Shown when the payment was handed to the gateway but the order could not be confirmed, so it may still be\n * processing (T176). Rendered as a status, never as the error alert.\n */\n unconfirmedMessage?: string;\n /**\n * Where the shopper lands after a successful placement. A page reference gets the placed order's\n * group as its `orderGroup` param. A string is a logical path of this store, navigated as written;\n * an absolute, protocol-relative, or non-http(s) value, or a `{orderGroup}` template, is refused\n * rather than navigated to (fail closed, dev-only warn).\n * e.g. `{ standard: 'order-placed' }`\n */\n successHref?: PageRef | string;\n /** `Payment` slice forwarded by the reactive runtime (arity-1, ADR-0015) — `null` until it resolves. */\n $data?: PlaceOrderData;\n /** Compiler-injected action surface; carries `payment.startTransaction`, `payment.gatewayCallback`, `analytics.track`. */\n $actions?: ComponentActions;\n};\n\n// ---------------------------------------------------------------------------\n// Definition\n// ---------------------------------------------------------------------------\n\nexport const PlaceOrderDefinition = defineComponent<PlaceOrderProps>({\n name: 'PlaceOrder',\n importPath: '@vtex/faststore/components',\n component: PlaceOrder,\n fragment,\n fetchStrategy: 'reactive',\n actions: { payment: ['startTransaction', 'gatewayCallback'], analytics: ['track'] },\n requiresContext: 'payment',\n editor: { label: 'Place Order', category: 'commerce' },\n schema: {\n // Literals, not shared constants: the native catalog builder extracts `schema` statically and\n // silently drops an identifier-valued default (place-order.test.tsx asserts the built catalog\n // keeps every one of them, mirroring payment.tsx's group-default guard).\n label: { type: 'string', default: 'Place order', label: 'Button label' },\n placingLabel: { type: 'string', default: 'Placing order...', label: 'Button label while placing' },\n // No default on purpose: absent means no surface, so a store that does not author it renders today's markup.\n placingMessage: { type: 'string', label: 'Message shown while placing the order' },\n resumeLabel: {\n type: 'string',\n default: 'Complete your order',\n label: 'Button label while a surviving attempt offers a resume',\n },\n successMessage: { type: 'string', default: 'Order placed successfully.', label: 'Success message' },\n // T31 (specs/make-the-payment-components-authored-copy.md, FR-4, Decision 1) — one prop per\n // client-synthesized PaymentUserError code this CTA's alert can render, each defaulting to that\n // error's current, unchanged `message` (Decision 11 — the module-level constants that produce\n // these codes elsewhere in the payment surface keep their own message verbatim).\n missingSubmissionMessage: {\n type: 'string',\n default: 'Enter your payment details before placing the order.',\n label: 'Missing payment submission message',\n },\n missingMethodMessage: {\n type: 'string',\n default: 'Choose a payment method before placing the order.',\n label: 'Missing payment method message',\n },\n invalidTransactionMessage: {\n type: 'string',\n default: 'Unable to start the payment. Please try again.',\n label: 'Invalid transaction message',\n },\n networkErrorMessage: {\n type: 'string',\n default: 'Unable to complete the request. Please try again.',\n label: 'Network error message',\n },\n missingDocumentMessage: {\n type: 'string',\n default: 'Enter your document before placing the order.',\n label: 'Missing document message',\n },\n invalidDocumentMessage: {\n type: 'string',\n default: 'Enter a valid document before placing the order.',\n label: 'Invalid document message',\n },\n unavailableMethodMessage: {\n type: 'string',\n default: 'Choose another payment method before placing the order.',\n label: 'Unavailable payment method message',\n },\n unsavedBillingAddressMessage: {\n type: 'string',\n default: 'Save your billing address before placing the order.',\n label: 'Unsaved billing address message',\n },\n invalidCardDataMessage: {\n type: 'string',\n default: 'Enter valid card details before placing the order.',\n label: 'Invalid card data message',\n },\n unsupportedNetworkMessage: {\n type: 'string',\n default: 'This card is not from a network the store accepts. Use another card or choose another payment method.',\n label: 'Unsupported card network message',\n },\n invalidSecurityCodeMessage: {\n type: 'string',\n default: 'Enter a valid security code before placing the order.',\n label: 'Invalid security code message',\n },\n gatewayErrorMessage: {\n type: 'string',\n default: 'Unable to complete the payment. Please try again.',\n label: 'Gateway error message',\n },\n inFlightMessage: {\n type: 'string',\n default: 'This order is already being placed. Please wait.',\n label: 'Order already in flight message',\n },\n unconfirmedMessage: {\n type: 'string',\n default: 'We could not confirm your order yet. Your payment may still be processing, so please do not pay again.',\n label: 'Unconfirmed order message',\n },\n successHref: {\n type: 'link',\n default: { standard: 'order-placed' },\n fills: ['orderGroup'],\n label: 'Confirmation Page',\n },\n },\n guideline:\n \"The place-order CTA: invokes usePlaceOrder's three-call sequence (start transaction, the registered submission's own direct-to-gateway leg, then the gateway callback) and blocks interaction while it runs. Compose it as a sibling — never a child — of every other payment-entry leaf under the same PaymentSectionRoot or PaymentSectionController, so the one CTA serves every entry path. Renders one inline outcome after settling: the first userError's message, or successMessage on a clean settle. While the order is being placed it renders nothing but the button, unless placingMessage is set: then a status message shows beside the button, and the rest of the payment form is blocked for as long as it shows. This component reaches no payment-sensitive input. Must be inside a payment root. See place-order.md.\",\n});\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\n/** The default confirmation page. */\nconst ORDER_PLACED_PAGE: PageRef = { standard: 'order-placed' };\n\n/**\n * Fail-closed warning for a string `successHref` that is not a path of this store. Nothing upstream\n * validates a string prop's shape, and an absolute or protocol-relative value would turn this CTA into\n * an open redirect that fires right after a real purchase, carrying the shopper's own order group to\n * another origin. Dev-only, like every other authoring warning in this component.\n */\nfunction warnUnsafeSuccessHref(successHref: string, reason: SafeHrefRejection): void {\n if (process.env.NODE_ENV === 'production') return;\n console.warn(\n `[PlaceOrder] successHref \"${successHref}\" is not a path of this store (${reason}); refusing to ` +\n 'navigate there rather than sending the shopper off-site right after a purchase.',\n );\n}\n\n/**\n * Fail-closed warning for a string `successHref` that still carries a `{token}`, the template form this\n * prop took before page references. Nothing fills the token any more, so navigating would land the\n * shopper on a literal `%7BorderGroup%7D` 404 right after paying. Dev-only.\n */\nfunction warnTemplateSuccessHref(successHref: string): void {\n if (process.env.NODE_ENV === 'production') return;\n console.warn(\n `[PlaceOrder] successHref \"${successHref}\" is a route template; refusing to navigate there. ` +\n \"Reference the confirmation page instead: { standard: 'order-placed' }.\",\n );\n}\n\ntype PlaceOrderNavigateOnSuccessProps = Pick<UsePlaceOrder, 'orderId' | 'userErrors'> & {\n successHref: PageRef | string;\n};\n\n/**\n * Navigates once `orderId` transitions to a non-empty value — not on `succeeded` (Decision 4) — so a\n * null or empty order group and every failure path never navigate. `userErrors` is also consulted\n * directly (INV-1): this component does not own `usePlaceOrder`, so it does not rely on that hook never\n * settling an order id beside an error.\n *\n * The call site passes `displayOrderId` (`orderId ?? the surviving attempt's own orderId`), not the\n * mount-local `orderId` this type is named for: a remounted CTA whose own `usePlaceOrder()` never ran\n * has an empty local `orderId` forever, and would otherwise leave the shopper on the payment page.\n *\n * The effect keys on the serialized `successHref`, not on its identity: a reference authored in a\n * schema arrives as a new object on every server render, and keying on it would navigate again on a\n * `router.refresh()`.\n */\nfunction PlaceOrderNavigateOnSuccess({ successHref, orderId, userErrors }: PlaceOrderNavigateOnSuccessProps) {\n const { replace } = useStorefrontNavigation();\n const successKey = JSON.stringify(successHref);\n\n useEffect(() => {\n if (!orderId || userErrors.length > 0) return;\n const authored: PageRef | string = JSON.parse(successKey);\n if (typeof authored !== 'string') {\n replace({ ...authored, params: { ...authored.params, orderGroup: orderId } });\n return;\n }\n const destination = resolveSiteRelativeHref(authored);\n if (!destination.safe) {\n warnUnsafeSuccessHref(authored, destination.reason);\n return;\n }\n if (destination.href.includes('{')) {\n warnTemplateSuccessHref(authored);\n return;\n }\n replace(destination.href);\n }, [orderId, successKey, userErrors, replace]);\n\n return null;\n}\n\n/** The message props FR-4 adds, unnested — one field per client-synthesized `PaymentUserError` code\n * this CTA can render. Ten from T31; `inFlightMessage` joins them for T170's own code,\n * `unconfirmedMessage` for T176's, which renders in the status node instead of the alert, and\n * `unavailableMethodMessage` for T192's. */\nexport type AuthoredPlaceOrderMessages = Readonly<{\n missingSubmissionMessage: string;\n missingMethodMessage: string;\n invalidTransactionMessage: string;\n networkErrorMessage: string;\n missingDocumentMessage: string;\n invalidDocumentMessage: string;\n unsavedBillingAddressMessage: string;\n invalidCardDataMessage: string;\n unsupportedNetworkMessage: string;\n invalidSecurityCodeMessage: string;\n gatewayErrorMessage: string;\n inFlightMessage: string;\n unconfirmedMessage: string;\n unavailableMethodMessage: string;\n}>;\n\n/**\n * Builds the code -> copy map `resolveErrorMessage` reads (Decision 1, FR-4). The codes are literal\n * strings, never imported constants: importing them from card-entry.tsx / saved-cards.tsx /\n * use-place-order.ts / use-payment-submit-gate.ts / gateway.ts here would make this file a matter ->\n * matter dependency (R5) — `resolvePaymentSubmitGate` and `use-place-order.ts` stay untouched and this\n * component still imports nothing from either module beyond the hooks it already called. Exported for\n * direct unit testing, mirroring card-entry.tsx's convention for its own pure helpers:\n * place-order.test.tsx imports the five files' own real exported code constants and asserts this\n * function's returned key set equals their union.\n */\nexport function buildAuthoredErrorMessages(messages: AuthoredPlaceOrderMessages): Readonly<Record<string, string>> {\n return {\n MISSING_PAYMENT_SUBMISSION: messages.missingSubmissionMessage,\n MISSING_PAYMENT_METHOD_SELECTION: messages.missingMethodMessage,\n INVALID_TRANSACTION_DATA: messages.invalidTransactionMessage,\n NETWORK_ERROR: messages.networkErrorMessage,\n MISSING_CARDHOLDER_DOCUMENT: messages.missingDocumentMessage,\n INVALID_CARDHOLDER_DOCUMENT: messages.invalidDocumentMessage,\n UNSAVED_BILLING_ADDRESS: messages.unsavedBillingAddressMessage,\n INVALID_CARD_DATA: messages.invalidCardDataMessage,\n UNSUPPORTED_CARD_NETWORK: messages.unsupportedNetworkMessage,\n INVALID_SECURITY_CODE: messages.invalidSecurityCodeMessage,\n GATEWAY_ERROR: messages.gatewayErrorMessage,\n PLACE_ORDER_IN_FLIGHT: messages.inFlightMessage,\n PLACE_ORDER_UNCONFIRMED: messages.unconfirmedMessage,\n UNAVAILABLE_PAYMENT_METHOD: messages.unavailableMethodMessage,\n };\n}\n\n/**\n * Resolves the alert's rendered message for one client-synthesized `PaymentUserError`: the authored\n * copy for its `code` when this component owns one, otherwise the error's own `message` unchanged\n * (US-2 AC2 — a server-returned code this component does not author must render verbatim).\n *\n * `||`, not `??` (fix pass, finding 7): a store author can write `\"\"` for a code's authored message —\n * a valid, if unusual, `type: 'string'` prop value — and `??` only falls through on `null`/`undefined`,\n * so an authored empty string would render as an empty `role=\"alert\"` on a genuine gateway refusal,\n * leaving the shopper with no feedback at all where the unauthored default always rendered\n * `error.message`. Falling through on any falsy authored value is the exception on this surface, not\n * the rule: eight sibling `??` resolutions elsewhere (`access-code-sign-in.tsx`, `region.tsx`) stay on\n * `??`; `billing-address.tsx`'s `fieldLabels` fallback (fix pass round 2, finding N1) is fixed the\n * same way, for the same reason.\n */\nexport function resolveErrorMessage(error: PaymentUserError, authored: Readonly<Record<string, string>>): string {\n return authored[error.code] || error.message;\n}\n\ntype PlaceOrderFeedbackProps = Readonly<{\n placing: boolean;\n placingMessage: string | undefined;\n firstError: PaymentUserError | undefined;\n unconfirmed: boolean;\n succeeded: boolean;\n successMessage: string;\n displayOrderId: string | null;\n authoredErrorMessages: Readonly<Record<string, string>>;\n}>;\n\n/**\n * The CTA's feedback nodes: the authored placing message, the alert for a refusal, the status notice for\n * an order that could not be confirmed (T176), and the success line. Rendered as the CTA's own children,\n * so none of them adds a wrapper.\n */\nfunction PlaceOrderFeedback({\n placing,\n placingMessage,\n firstError,\n unconfirmed,\n succeeded,\n successMessage,\n displayOrderId,\n authoredErrorMessages,\n}: PlaceOrderFeedbackProps) {\n return (\n <>\n {placing && placingMessage?.trim() ? <output data-fs-place-order-placing=\"\">{placingMessage}</output> : null}\n {firstError && !unconfirmed ? (\n <div role=\"alert\" data-fs-place-order-error=\"\">\n {resolveErrorMessage(firstError, authoredErrorMessages)}\n </div>\n ) : null}\n {firstError && unconfirmed && !succeeded ? (\n <output data-fs-place-order-unconfirmed=\"\">{resolveErrorMessage(firstError, authoredErrorMessages)}</output>\n ) : null}\n {succeeded ? (\n <output data-fs-place-order-success=\"\">\n <span data-fs-place-order-success-message=\"\">{successMessage}</span>\n {displayOrderId ? <span data-fs-place-order-success-order-id=\"\">{displayOrderId}</span> : null}\n </output>\n ) : null}\n </>\n );\n}\n\n/**\n * T212: where focus moves after a refusal. Only a refusal raised before anything left the browser\n * (`reachedGateway === false`) that names an element the shopper must fix has a target; a result the\n * gateway returned never does, whatever its code.\n */\nfunction refusalFocusTarget(refusals: readonly PaymentUserError[], reachedGateway: boolean) {\n const [refusal] = refusals;\n return reachedGateway === false && refusal ? refusalTargetOf(refusal) : null;\n}\n\nexport function PlaceOrder({\n label = 'Place order',\n placingLabel = 'Placing order...',\n placingMessage,\n resumeLabel = 'Complete your order',\n successMessage = 'Order placed successfully.',\n missingSubmissionMessage = 'Enter your payment details before placing the order.',\n missingMethodMessage = 'Choose a payment method before placing the order.',\n invalidTransactionMessage = 'Unable to start the payment. Please try again.',\n networkErrorMessage = 'Unable to complete the request. Please try again.',\n missingDocumentMessage = 'Enter your document before placing the order.',\n invalidDocumentMessage = 'Enter a valid document before placing the order.',\n unavailableMethodMessage = 'Choose another payment method before placing the order.',\n unsavedBillingAddressMessage = 'Save your billing address before placing the order.',\n invalidCardDataMessage = 'Enter valid card details before placing the order.',\n unsupportedNetworkMessage = 'This card is not from a network the store accepts. Use another card or choose another payment method.',\n invalidSecurityCodeMessage = 'Enter a valid security code before placing the order.',\n gatewayErrorMessage = 'Unable to complete the payment. Please try again.',\n inFlightMessage = 'This order is already being placed. Please wait.',\n unconfirmedMessage = 'We could not confirm your order yet. Your payment may still be processing, so please do not pay again.',\n successHref = ORDER_PLACED_PAGE,\n $data: $dataProp,\n $actions: $actionsProp,\n className,\n ...props\n}: PlaceOrderProps) {\n const $data = useDataOverride($dataProp);\n const $actions = useActionsOverride($actionsProp);\n // T28: this instance's own stable identity, so its publish effect below retracts only its own key\n // (Decision 4) — never a second composed PlaceOrder's still-in-flight one.\n const instanceKey = useId();\n // Also enforces the PaymentSectionRoot/PaymentSectionController ancestor: usePayment() throws\n // outside that subtree (see the module doc comment) — the first of the two guards to run, since its\n // result feeds usePlaceOrder's own argument below.\n //\n // Fix pass, finding S-F1 (High, duplicate-transaction route (a)): `sectionPlacing` is the shared\n // fact this instance also *writes* below — read back so this CTA's own `disabled` can OR it in.\n // Without this, a second composed PlaceOrder stayed enabled for the whole time a first instance's\n // sequence was open: each instance's `usePlaceOrder()` call owns its own independent `placing`/\n // `inFlight` guard, so nothing local to a second CTA ever knew a sibling had already opened a\n // transaction. This never makes this CTA's own subtree inert (FR-6/Decision 5 are untouched) — it\n // only widens the *button's* own disabled condition.\n //\n // T29: `attempt`/`setAttempt` are this same contract's own record of an order-placement attempt —\n // read here (never mirrored locally) so a remount renders the surviving truth instead of this\n // instance's own fresh, reset local state (see `succeeded`/`resumable` below).\n const { draft, placing: sectionPlacing, setPlacing, attempt, setAttempt, focusRefusal } = usePayment();\n // T24's submit gate: an already-resolved client-side refusal (a missing/malformed cardholder\n // document, or an unsaved billing address), forwarded verbatim into usePlaceOrder's own opaque\n // argument — still not a card field, since the hook only ever receives the resolved verdict.\n const submitGate = usePaymentSubmitGate();\n const { placeOrder, placing, userErrors, orderId } = usePlaceOrder({\n $data,\n $actions,\n attempt,\n setAttempt,\n billingAddressDifferent: draft.billingAddressDifferent,\n submitGate,\n });\n const authoredErrorMessages = buildAuthoredErrorMessages({\n missingSubmissionMessage,\n missingMethodMessage,\n invalidTransactionMessage,\n networkErrorMessage,\n missingDocumentMessage,\n invalidDocumentMessage,\n unsavedBillingAddressMessage,\n invalidCardDataMessage,\n unsupportedNetworkMessage,\n invalidSecurityCodeMessage,\n gatewayErrorMessage,\n inFlightMessage,\n unconfirmedMessage,\n unavailableMethodMessage,\n });\n const [attempted, setAttempted] = useState(false);\n\n // T28 (FR-1/FR-7): mirrors this CTA's own in-flight state onto the payment context so the sibling\n // entry leaves can freeze while an order-placement sequence is open. Retracts only this instance's\n // key on unmount, so a second composed PlaceOrder's own live sequence is never unblocked by this one\n // settling or unmounting (Decision 4, R5).\n //\n // Fix pass, finding F7 (assumption A-3): a *layout* effect, not a passive one — it must commit in\n // the same frame as `placing`'s own render, so no intermediate paint ever shows this CTA's button\n // still enabled beside leaves that are about to go inert (or the reverse, on release). A passive\n // `useEffect` here leaves a ~1-frame window where a fast key-repeat could land.\n //\n // T29 (FR-5, INV-5): the cleanup's own release is now conditional on `placing` — closed over from\n // the same render as this effect instance, so it reflects this CTA's own sequence at the moment it\n // unmounts. `placing` is true for the whole span from before `startTransaction()`/`gatewayCallback()`\n // to `run()`/`resume()` settling (unchanged by this task), so an unmount while it is still true is\n // exactly an unmount mid-sequence (the overlay closing with no `keepMounted`) — the `run()`/`resume()`\n // closure this CTA started keeps writing the surviving attempt's phase after this CTA is gone\n // (NFR-3), and nothing else will ever flip this key back, so the release must not happen. A routine\n // re-render where `placing` itself just flipped self-corrects immediately after, via this same\n // effect's next body call, which re-publishes the current value directly.\n //\n // Fix pass (Critical finding): this instance's own key in `usePayment()`'s ref-counted set is\n // therefore genuinely never retracted once abandoned here — by design, since nothing can safely\n // predict at unmount time whether the closure is about to resolve to a terminal phase or is still\n // truly in flight. What bounds the damage is `usePaymentMethodSelection`'s own `placing` derivation,\n // which folds the shared attempt's phase into every reader of this fact: once the abandoned closure\n // finally writes `refused` or `settled`, `placing` reads `false` again for this root regardless of\n // how many stale keys the ref-counted set still carries. `blockedByOtherInstance`/`resumable` below\n // read that same, already-corrected `sectionPlacing` value, so they need no separate escape hatch of\n // their own for this case.\n useLayoutEffect(() => {\n setPlacing(instanceKey, placing);\n return () => {\n if (placing) return;\n setPlacing(instanceKey, false);\n };\n }, [instanceKey, placing, setPlacing]);\n\n const [firstError] = userErrors;\n // T29: a settled attempt renders as succeeded even across a remount, where this component's own\n // `attempted`/`userErrors` restart at their pre-attempt defaults (FR-1) but the shared `attempt`\n // does not. On the same mount, `attempted && !placing && userErrors.length === 0` already covers it\n // (both a clean `run()` and a clean `resume()` settle through the same wrapper), so this only adds\n // the case local state cannot see.\n const settledAttemptOrderId = attempt?.phase === 'settled' ? attempt.orderId : null;\n const succeeded = (attempted && !placing && userErrors.length === 0) || attempt?.phase === 'settled';\n // T29 (FR-2, FR-3): the next click finalizes rather than re-runs the sequence. Never true once\n // `succeeded` is (phases are mutually exclusive), and `placing` already takes priority in the label\n // below, so this needs no exclusion of its own here. The `'sent'` check is defensive-only today: no\n // write site in `run()` rests there (it writes `finalizing` directly, same tick, specs/make-an-order-\n // attempt-survive-a.md §2) — kept in case a future write path ever rests there again, rather than\n // silently treating that phase as non-resumable.\n const resumable = attempt?.phase === 'sent' || attempt?.phase === 'unresolved';\n // Local `orderId` (this mount's own settle) is preferred; a remounted CTA reading a settled attempt\n // has none of its own yet, so it falls back to the record's.\n const displayOrderId = orderId ?? settledAttemptOrderId;\n // T176 (FR-10, INV-11): the card was handed to the gateway and the order could not be confirmed, so\n // the payment may still be processing. That is a pending state, not a refusal: it renders in its own\n // status node, never in the alert stores style as an error, and never beside a success line — another\n // composed CTA can settle the shared record while this one still holds the outcome.\n const unconfirmed = firstError?.code === 'PLACE_ORDER_UNCONFIRMED';\n\n // T29: `sectionPlacing` overrides `resumable` below, not the other way round — a CTA that unmounted\n // mid-sequence (FR-5) leaves its own key published forever, because the `run()`/`resume()` closure it\n // abandoned settles through *local* state (`setPlacing(false)` inside `usePlaceOrder`'s own `settle`)\n // that has nowhere left to render once that CTA is gone, so the shared key it once set is never\n // retracted by anything else either. A resumable attempt must still be reachable through that stale\n // lock: `resume()` cannot re-pay by construction (Decision 3), so overriding a stuck `sectionPlacing`\n // here is safe exactly when it matters — a lock a *different*, still-genuinely-placing instance holds\n // is never resumable at the same time (the shared attempt is one fact — Decision 1 — so a real\n // concurrent opener keeps this attempt at `opening`/`finalizing`, not `sent`/`unresolved`).\n const blockedByOtherInstance = sectionPlacing && !resumable;\n\n function handleClick() {\n // FR-2 (T56): `setAttempted(true)` moved off the click and onto settlement, so `succeeded`\n // means \"an attempt settled with no refusals\" rather than \"a click happened and nothing is\n // in flight\". `placeOrder()` resolves; it never rejects (T13's own contract), and this\n // component reflects its state from the hook's own return value on every render rather than\n // from the awaited result — a rejection handler here would be dead code, and (review finding\n // F3) setting `attempted` from one would not \"keep the CTA disabled\": it would make\n // `succeeded` `true` with the attempt's real outcome unknown, the exact false-success frame\n // FR-2 exists to prevent.\n //\n // Review finding F1: settling `attempted` is not enough on its own past the first attempt.\n // Once an attempt settles, `attempted` stays `true` until something lowers it — and nothing\n // did, so a second click's own synchronous commit (`placeOrder` resets `userErrors` to `[]`\n // unconditionally, and a refusal leaves `placing` `false`) satisfied `succeeded` immediately,\n // one microtask before the new refusal arrived. Resetting `attempted` here, in the same\n // synchronous batch as that reset, makes every attempt — not just the first — start its own\n // click commit from \"not attempted\"; the `.then` below raises it again only once *this*\n // attempt's own outcome is in.\n setAttempted(false);\n //\n // T212: a refusal raised before anything left the browser (`reachedGateway === false`) that names an\n // element the shopper must fix moves focus there, once, as the continuation of this one click. A\n // result the gateway returned never does, whatever its code. Imperative on purpose, unlike the rest\n // of this component: derived from render state it would also fire on a remount or a re-render.\n void placeOrder().then(({ userErrors: refusals, reachedGateway }) => {\n setAttempted(true);\n const target = refusalFocusTarget(refusals, reachedGateway);\n if (target) focusRefusal(target);\n });\n }\n\n return (\n <div\n {...props}\n className={className}\n data-fs-place-order=\"\"\n {...(placing ? { 'data-fs-place-order-pending': '' } : {})}\n >\n <Button\n onClick={handleClick}\n disabled={placing || succeeded || blockedByOtherInstance}\n aria-busy={placing || undefined}\n data-fs-place-order-button=\"\"\n {...(placing ? { 'data-fs-place-order-button-pending': '' } : {})}\n >\n {placing ? placingLabel : resumable ? resumeLabel : label}\n </Button>\n <PlaceOrderFeedback\n placing={placing}\n placingMessage={placingMessage}\n firstError={firstError}\n unconfirmed={unconfirmed}\n succeeded={succeeded}\n successMessage={successMessage}\n displayOrderId={displayOrderId}\n authoredErrorMessages={authoredErrorMessages}\n />\n <PlaceOrderNavigateOnSuccess successHref={successHref} orderId={displayOrderId} userErrors={userErrors} />\n </div>\n );\n}\n"],"mappings":"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"}
@@ -135,17 +135,17 @@ function findBestInstallment(plans) {
135
135
  }
136
136
  function normalizeOffer(offer) {
137
137
  return {
138
- price: offer.price.amount,
139
- listPrice: offer.listPrice.amount,
140
- spotPrice: offer.spotPrice.amount,
138
+ price: Number(offer.price.amount),
139
+ listPrice: Number(offer.listPrice.amount),
140
+ spotPrice: Number(offer.spotPrice.amount),
141
141
  currency: offer.price.currencyCode,
142
142
  installmentPlans: offer.installmentPlans.map((plan) => ({
143
143
  paymentMethod: plan.paymentMethod,
144
144
  paymentType: plan.paymentType,
145
145
  installments: plan.installments.map((inst) => ({
146
146
  count: inst.count,
147
- value: inst.value.amount,
148
- totalAmount: inst.totalAmount.amount,
147
+ value: Number(inst.value.amount),
148
+ totalAmount: Number(inst.totalAmount.amount),
149
149
  interestRate: inst.interestRate,
150
150
  interestFree: inst.interestFree
151
151
  }))
@@ -1 +1 @@
1
- {"version":3,"file":"pricing.js","names":[],"sources":["../../../src/matter/pricing/pricing.tsx"],"sourcesContent":["'use client';\n\nimport { useReactiveVar } from '@apollo/client/react';\nimport { defineComponent } from '@vtex/fs-core';\nimport type { ComponentPropsWithRef } from 'react';\nimport { createContext, Suspense, useContext } from 'react';\nimport { PopoverTrigger } from '../../particles/popover/popover.js';\nimport { TabsPanel, TabsTab } from '../../particles/tabs/tabs.js';\nimport { useStorefrontContext } from '../../sdk/context/storefront-context.js';\nimport { useDataOverride } from '../../sdk/data/data-override-context.js';\nimport { HotDataProvider } from '../../sdk/data/hot-data-provider.js';\nimport { graphql } from '../../sdk/generated/gql.js';\nimport type { VariantPricingDataFragment } from '../../sdk/generated/graphql.js';\nimport { resolveDefaultSeller } from '../../sdk/seller.js';\nimport { publishedVariantIdFor, selectedVariantVar } from '../../sdk/state/variant-selector.js';\n\n// ---------------------------------------------------------------------------\n// GraphQL Fragment\n// ---------------------------------------------------------------------------\n\nconst fragment = /* GraphQL */ `\n fragment PricingData on Query {\n productBySlug(slug: $slug) {\n __typename\n id\n variants(first: 1) {\n edges {\n node {\n sellers {\n isDefault\n offer {\n price { amount currencyCode }\n listPrice { amount currencyCode }\n spotPrice { amount currencyCode }\n installmentPlans {\n paymentMethod\n paymentType\n installments {\n count\n value { amount currencyCode }\n totalAmount { amount currencyCode }\n interestRate\n interestFree\n }\n }\n discountHighlights\n promotions {\n name\n }\n }\n }\n }\n }\n }\n }\n }\n`;\n\n// The variant offer slice, authored via graphql() so HotDataProvider gets a TypedDocumentNode.\n// Declared so codegen scans the source and emits VariantPricingDataFragment; the fragment is spread\n// into variantQuery at the GraphQL layer, so the variable is unused at runtime.\nconst _variantFragment = graphql(`\n fragment VariantPricingData on Variant {\n __typename\n id\n sellers {\n isDefault\n offer {\n price { amount currencyCode }\n listPrice { amount currencyCode }\n spotPrice { amount currencyCode }\n installmentPlans {\n paymentMethod\n paymentType\n installments {\n count\n value { amount currencyCode }\n totalAmount { amount currencyCode }\n interestRate\n interestFree\n }\n }\n discountHighlights\n promotions {\n name\n }\n }\n }\n }\n`);\n\nconst variantQuery = graphql(`\n query VariantPricingQuery($id: ID!) {\n node(id: $id) {\n __typename\n ... on Variant {\n ...VariantPricingData\n }\n }\n }\n`);\n\n// ---------------------------------------------------------------------------\n// Raw data types (shape of the fragment result)\n// ---------------------------------------------------------------------------\n\ntype MoneyValue = {\n amount: number;\n currencyCode: string;\n};\n\ntype RawPromotion = {\n name: string;\n};\n\ntype RawOffer = {\n price: MoneyValue;\n listPrice: MoneyValue;\n spotPrice: MoneyValue;\n installmentPlans: Array<{\n paymentMethod: string;\n paymentType: string;\n installments: Array<{\n count: number;\n value: MoneyValue;\n totalAmount: MoneyValue;\n interestRate: number;\n interestFree: boolean;\n }>;\n }>;\n discountHighlights: string[];\n promotions: RawPromotion[];\n};\n\ntype RawPricingData = {\n // __typename/id are optional so existing fixtures (which omit them) still typecheck; the real\n // page query always supplies id, which scopes the published variant selection to this product.\n __typename?: string;\n id?: string;\n variants: {\n edges: Array<{\n node: {\n sellers: Array<{\n isDefault: boolean;\n offer: RawOffer | null;\n }>;\n };\n }>;\n };\n};\n\ntype VariantSlice = VariantPricingDataFragment;\n\ntype NormalizedPricingOffer = {\n price: number;\n listPrice: number;\n spotPrice: number;\n currency: string;\n installmentPlans: InstallmentPlanData[];\n discountHighlights: string[];\n promotions: PromotionData[];\n};\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ntype InstallmentData = {\n count: number;\n value: number;\n totalAmount: number;\n interestRate: number;\n interestFree: boolean;\n};\n\ntype InstallmentPlanData = {\n paymentMethod: string;\n paymentType: string;\n installments: InstallmentData[];\n};\n\ntype PromotionData = {\n name: string;\n};\n\ntype PricingContextData = {\n price: number;\n listPrice: number;\n spotPrice: number;\n currency: string;\n /** Undefined only for a directly-rendered view: `Intl` reads it as the platform default. */\n locale: string | undefined;\n installmentPlans: InstallmentPlanData[];\n discountHighlights: string[];\n promotions: PromotionData[];\n hasDiscount: boolean;\n hasSpotDiscount: boolean;\n discountPercentage: number;\n spotDiscountPercentage: number;\n bestInstallment: InstallmentData | null;\n};\n\ntype PricingContextValue = PricingContextData | null;\n\ntype InstallmentPlanItemContextData = {\n paymentMethod: string;\n paymentType: string;\n installments: InstallmentData[];\n bestInstallment: InstallmentData | null;\n};\n\nconst PRICING_CONTEXT_UNSET = Symbol('PricingContextUnset');\n\nexport type PricingRootProps = ComponentPropsWithRef<'div'> & {\n $data?: RawPricingData | null;\n /** Page-supplied viewed SKU; pre-selects the offer on first paint. A published swatch selection\n * wins over it once the shopper interacts. */\n selectedVariantId?: string;\n};\n\nexport type PricingSellingPriceProps = ComponentPropsWithRef<'span'>;\n\nexport type PricingListPriceProps = ComponentPropsWithRef<'span'>;\n\nexport type PricingSpotPriceProps = ComponentPropsWithRef<'span'>;\n\nexport type PricingInstallmentsProps = ComponentPropsWithRef<'div'>;\n\nexport type PricingInstallmentPlansProps = ComponentPropsWithRef<'div'>;\n\nexport type PricingInstallmentPlanProps = ComponentPropsWithRef<'div'>;\n\nexport type PricingInstallmentsForPlanProps = ComponentPropsWithRef<'div'>;\n\nexport type PricingPaymentMethodsTriggerProps = ComponentPropsWithRef<'button'>;\n\nexport type PricingPaymentMethodsListProps = ComponentPropsWithRef<'div'>;\n\nexport type PricingPaymentMethodsTabListProps = ComponentPropsWithRef<'div'>;\n\nexport type PricingPaymentMethodsTabPanelsProps = ComponentPropsWithRef<'div'>;\n\nexport type PricingPaymentMethodNameProps = ComponentPropsWithRef<'span'>;\n\nexport type PricingInstallmentProps = ComponentPropsWithRef<'span'> & {\n template?: string;\n interestFreeLabel?: string;\n};\n\nexport type PricingDiscountProps = ComponentPropsWithRef<'span'> & {\n template?: string;\n format?: 'percentage' | 'absolute';\n};\n\nexport type PricingHighlightsProps = ComponentPropsWithRef<'div'>;\n\nexport type PricingHighlightProps = ComponentPropsWithRef<'span'>;\n\nexport type PricingPromotionsProps = ComponentPropsWithRef<'div'>;\n\nexport type PricingPromotionProps = ComponentPropsWithRef<'span'> & {\n template?: string;\n};\n\nexport type PricingSpotDiscountProps = ComponentPropsWithRef<'span'> & {\n template?: string;\n};\n\n// ---------------------------------------------------------------------------\n// Context\n// ---------------------------------------------------------------------------\n\nconst PricingContext = createContext<PricingContextValue | typeof PRICING_CONTEXT_UNSET>(PRICING_CONTEXT_UNSET);\n\nconst InstallmentItemContext = createContext<InstallmentData | null>(null);\n\nconst InstallmentPlanItemContext = createContext<InstallmentPlanItemContextData | null>(null);\n\nconst HighlightItemContext = createContext<string | null>(null);\n\nconst PromotionItemContext = createContext<PromotionData | null>(null);\n\nfunction usePricing(): PricingContextValue {\n const ctx = useContext(PricingContext);\n if (ctx === PRICING_CONTEXT_UNSET) {\n throw new Error('Pricing components must be used inside PricingRoot.');\n }\n return ctx;\n}\n\nfunction useInstallmentItem(): InstallmentData {\n const ctx = useContext(InstallmentItemContext);\n if (!ctx) {\n throw new Error('PricingInstallment must be used inside PricingInstallments.');\n }\n return ctx;\n}\n\nexport function useInstallmentPlanItem(\n caller = 'PricingInstallmentPlan',\n parent = 'PricingInstallmentPlans',\n): InstallmentPlanItemContextData {\n const ctx = useContext(InstallmentPlanItemContext);\n if (!ctx) {\n throw new Error(`${caller} must be used inside ${parent}.`);\n }\n return ctx;\n}\n\nfunction useHighlightItem(): string {\n const ctx = useContext(HighlightItemContext);\n if (ctx === null) {\n throw new Error('PricingHighlight must be used inside PricingHighlights.');\n }\n return ctx;\n}\n\nfunction usePromotionItem(): PromotionData {\n const ctx = useContext(PromotionItemContext);\n if (!ctx) {\n throw new Error('PricingPromotion must be used inside PricingPromotions.');\n }\n return ctx;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction formatPrice(value: number, locale: string | undefined, currency: string): string {\n return new Intl.NumberFormat(locale, { style: 'currency', currency }).format(value);\n}\n\nfunction findBestInstallment(plans: InstallmentPlanData[]): InstallmentData | null {\n const allInstallments = plans.flatMap((plan) => plan.installments);\n if (allInstallments.length === 0) return null;\n\n const interestFree = allInstallments.filter((i) => i.interestFree);\n if (interestFree.length > 0) {\n return interestFree.reduce((best, current) => (current.count > best.count ? current : best));\n }\n\n return allInstallments.reduce((best, current) => (current.count > best.count ? current : best));\n}\n\n// ---------------------------------------------------------------------------\n// Transform\n// ---------------------------------------------------------------------------\n\nfunction normalizeOffer(offer: RawOffer): NormalizedPricingOffer {\n return {\n price: offer.price.amount,\n listPrice: offer.listPrice.amount,\n spotPrice: offer.spotPrice.amount,\n currency: offer.price.currencyCode,\n installmentPlans: offer.installmentPlans.map((plan) => ({\n paymentMethod: plan.paymentMethod,\n paymentType: plan.paymentType,\n installments: plan.installments.map((inst) => ({\n count: inst.count,\n value: inst.value.amount,\n totalAmount: inst.totalAmount.amount,\n interestRate: inst.interestRate,\n interestFree: inst.interestFree,\n })),\n })),\n discountHighlights: offer.discountHighlights,\n promotions: offer.promotions.map((promotion) => ({ name: promotion.name })),\n };\n}\n\n// Resolves a variant's default seller and normalizes its offer, or null when that seller has no\n// offer. Shared by the product-level and selected-variant transforms so the default-seller + offer\n// gate lives in one place.\nfunction pricingOfferFromVariant(variant: {\n sellers: readonly { isDefault: boolean; offer: RawOffer | null }[];\n}): NormalizedPricingOffer | null {\n const seller = resolveDefaultSeller(variant.sellers);\n const offer = seller?.offer;\n if (!offer) return null;\n\n return normalizeOffer(offer);\n}\n\nfunction transformPricingData(data: RawPricingData): NormalizedPricingOffer | null {\n const edge = data.variants.edges[0];\n if (!edge) return null;\n\n return pricingOfferFromVariant(edge.node);\n}\n\nexport function transformVariantPricingData(variant: VariantSlice): NormalizedPricingOffer | null {\n return pricingOfferFromVariant(variant);\n}\n\n// ---------------------------------------------------------------------------\n// Definitions\n// ---------------------------------------------------------------------------\n\nexport const PricingRootDefinition = defineComponent<PricingRootProps>({\n name: 'PricingRoot',\n importPath: '@vtex/faststore/components',\n component: PricingRoot,\n fragment,\n fetchStrategy: 'lazy',\n skeleton: PricingSkeleton,\n editor: { label: 'Pricing', category: 'commerce' },\n schema: {\n selectedVariantId: { type: 'string', label: 'Selected Variant ID' },\n },\n guideline:\n 'Root container for the PDP pricing block; all other Pricing sub-components must be descendants of it. Automatically recomputes the offer when a shopper picks a VariantSelector swatch (it reads the published variant selection); the selectedVariantId prop is an optional pre-selection fallback. Falls back silently to the product-level offer on variant fetch error. See pricing.md.',\n});\n\nexport const PricingSellingPriceDefinition = defineComponent<PricingSellingPriceProps>({\n name: 'PricingSellingPrice',\n importPath: '@vtex/faststore/components',\n component: PricingSellingPrice,\n editor: { label: 'Selling Price', category: 'commerce' },\n schema: {},\n guideline: 'Displays the current selling price; must be a descendant of PricingRoot.',\n});\n\nexport const PricingListPriceDefinition = defineComponent<PricingListPriceProps>({\n name: 'PricingListPrice',\n importPath: '@vtex/faststore/components',\n component: PricingListPrice,\n editor: { label: 'List Price', category: 'commerce' },\n schema: {},\n guideline:\n 'Displays the original (strikethrough) list price; only renders when a discount exists. Must be a descendant of PricingRoot.',\n});\n\nexport const PricingSpotPriceDefinition = defineComponent<PricingSpotPriceProps>({\n name: 'PricingSpotPrice',\n importPath: '@vtex/faststore/components',\n component: PricingSpotPrice,\n editor: { label: 'Spot Price', category: 'commerce' },\n schema: {},\n guideline:\n 'Displays the best cash/instant-payment price (e.g. Pix); only renders when spotPrice is lower than the selling price. Must be a descendant of PricingRoot.',\n});\n\nexport const PricingInstallmentsDefinition = defineComponent<PricingInstallmentsProps>({\n name: 'PricingInstallments',\n importPath: '@vtex/faststore/components',\n component: PricingInstallments,\n editor: { label: 'Installments', category: 'commerce' },\n schema: {},\n guideline:\n 'Shortcut container that exposes the single best installment across all plans; use PricingInstallmentPlans instead when a per-payment-method breakdown is needed. Must be a descendant of PricingRoot.',\n});\n\nexport const PricingInstallmentPlansDefinition = defineComponent<PricingInstallmentPlansProps>({\n name: 'PricingInstallmentPlans',\n importPath: '@vtex/faststore/components',\n component: PricingInstallmentPlans,\n editor: { label: 'Installment Plans', category: 'commerce' },\n schema: {},\n guideline:\n 'Renders one row per payment method; use PricingInstallments instead when only the single best plan is needed. Must be a descendant of PricingRoot.',\n});\n\nexport const PricingInstallmentPlanDefinition = defineComponent<PricingInstallmentPlanProps>({\n name: 'PricingInstallmentPlan',\n importPath: '@vtex/faststore/components',\n component: PricingInstallmentPlan,\n editor: { label: 'Installment Plan', category: 'commerce' },\n schema: {},\n guideline:\n 'Renders a single plan row inside PricingInstallmentPlans; nest PricingInstallmentsForPlan inside it to list every installment tier instead of just the best one. Must be a descendant of PricingInstallmentPlans.',\n});\n\nexport const PricingInstallmentsForPlanDefinition = defineComponent<PricingInstallmentsForPlanProps>({\n name: 'PricingInstallmentsForPlan',\n importPath: '@vtex/faststore/components',\n component: PricingInstallmentsForPlan,\n editor: { label: 'Installments For Plan', category: 'commerce' },\n schema: {},\n guideline:\n 'Iterates every installment tier (1x, 2x, … Nx) of the enclosing plan; must be a descendant of PricingInstallmentPlan.',\n});\n\nexport const PricingPaymentMethodsTriggerDefinition = defineComponent<PricingPaymentMethodsTriggerProps>({\n name: 'PricingPaymentMethodsTrigger',\n importPath: '@vtex/faststore/components',\n component: PricingPaymentMethodsTrigger,\n editor: { label: 'Payment Methods Trigger', category: 'action' },\n schema: {},\n guideline: 'Button that opens the payment-methods disclosure panel; must be a descendant of PopoverRoot.',\n});\n\nexport const PricingPaymentMethodsListDefinition = defineComponent<PricingPaymentMethodsListProps>({\n name: 'PricingPaymentMethodsList',\n importPath: '@vtex/faststore/components',\n component: PricingPaymentMethodsList,\n editor: { label: 'Payment Methods List', category: 'commerce' },\n schema: {},\n guideline:\n 'Flat disclosure panel content listing every payment plan; place inside PopoverPopup, DialogPopup, or DrawerPopup. Must be a descendant of PricingRoot.',\n});\n\nexport const PricingPaymentMethodsTabListDefinition = defineComponent<PricingPaymentMethodsTabListProps>({\n name: 'PricingPaymentMethodsTabList',\n importPath: '@vtex/faststore/components',\n component: PricingPaymentMethodsTabList,\n editor: { label: 'Payment Methods Tab List', category: 'commerce' },\n schema: {},\n guideline:\n 'Emits one tab per payment plan for the tab-grouped disclosure pattern; must be a descendant of TabsList (which is inside TabsRoot). Pair with PricingPaymentMethodsTabPanels.',\n});\n\nexport const PricingPaymentMethodsTabPanelsDefinition = defineComponent<PricingPaymentMethodsTabPanelsProps>({\n name: 'PricingPaymentMethodsTabPanels',\n importPath: '@vtex/faststore/components',\n component: PricingPaymentMethodsTabPanels,\n editor: { label: 'Payment Methods Tab Panels', category: 'commerce' },\n schema: {},\n guideline:\n 'Emits one panel per payment plan for the tab-grouped disclosure pattern; must be a sibling of TabsList under TabsRoot (not nested inside TabsList). Pair with PricingPaymentMethodsTabList.',\n});\n\nexport const PricingPaymentMethodNameDefinition = defineComponent<PricingPaymentMethodNameProps>({\n name: 'PricingPaymentMethodName',\n importPath: '@vtex/faststore/components',\n component: PricingPaymentMethodName,\n editor: { label: 'Payment Method Name', category: 'commerce' },\n schema: {},\n guideline:\n 'Renders the enclosing plan\\'s payment method name (e.g. \"Visa\", \"Pix\"); must be inside a plan context — PricingInstallmentPlan, PricingPaymentMethodsTabList, or PricingPaymentMethodsTabPanels.',\n});\n\nexport const PricingInstallmentDefinition = defineComponent<PricingInstallmentProps>({\n name: 'PricingInstallment',\n importPath: '@vtex/faststore/components',\n component: PricingInstallment,\n editor: { label: 'Installment', category: 'commerce' },\n schema: {\n template: { type: 'string', default: '{count}x de {value}', label: 'Template' },\n interestFreeLabel: { type: 'string', default: 'sem juros', label: 'Interest-free label' },\n },\n guideline:\n 'Renders a single installment line using {count} and {value} template placeholders; must be a descendant of PricingInstallments, PricingInstallmentPlan, or PricingInstallmentsForPlan.',\n});\n\nexport const PricingDiscountDefinition = defineComponent<PricingDiscountProps>({\n name: 'PricingDiscount',\n importPath: '@vtex/faststore/components',\n component: PricingDiscount,\n editor: { label: 'Discount Badge', category: 'commerce' },\n schema: {\n format: { type: ['percentage', 'absolute'] as const, default: 'percentage', label: 'Discount Format' },\n template: { type: 'string', label: 'Template' },\n },\n guideline:\n 'Discount badge for the listPrice-vs-price markdown; use PricingSpotDiscount instead for the spotPrice-vs-price (Pix/cash) percentage. The format prop switches between a percentage (-25%, default) and an absolute amount (-R$ 10,00); the template supports {percentage} and {amount} placeholders and defaults to the format-appropriate one. Recomputes automatically on swatch change. Must be a descendant of PricingRoot.',\n});\n\nexport const PricingSpotDiscountDefinition = defineComponent<PricingSpotDiscountProps>({\n name: 'PricingSpotDiscount',\n importPath: '@vtex/faststore/components',\n component: PricingSpotDiscount,\n editor: { label: 'Spot Discount Badge', category: 'commerce' },\n schema: {\n template: { type: 'string', default: '-{percentage}%', label: 'Template' },\n },\n guideline:\n 'Discount badge for the spotPrice-vs-price (cash/Pix) percentage; use PricingDiscount instead for the listPrice-vs-price percentage. Must be a descendant of PricingRoot.',\n});\n\nexport const PricingHighlightsDefinition = defineComponent<PricingHighlightsProps>({\n name: 'PricingHighlights',\n importPath: '@vtex/faststore/components',\n component: PricingHighlights,\n editor: { label: 'Highlights', category: 'commerce' },\n schema: {},\n guideline:\n 'Iterates the offer\\'s discount highlight labels (e.g. \"Black Friday\", \"Exclusivo\"); place PricingHighlight as a child. Must be a descendant of PricingRoot.',\n});\n\nexport const PricingHighlightDefinition = defineComponent<PricingHighlightProps>({\n name: 'PricingHighlight',\n importPath: '@vtex/faststore/components',\n component: PricingHighlight,\n editor: { label: 'Highlight', category: 'commerce' },\n schema: {},\n guideline: 'Renders a single highlight label as a span; must be a descendant of PricingHighlights.',\n});\n\nexport const PricingPromotionsDefinition = defineComponent<PricingPromotionsProps>({\n name: 'PricingPromotions',\n importPath: '@vtex/faststore/components',\n component: PricingPromotions,\n editor: { label: 'Promotions', category: 'commerce' },\n schema: {},\n guideline:\n 'Iterates the offer\\'s structured promotions (e.g. \"Compre 3 leve 2\"); place PricingPromotion as a child. Must be a descendant of PricingRoot.',\n});\n\nexport const PricingPromotionDefinition = defineComponent<PricingPromotionProps>({\n name: 'PricingPromotion',\n importPath: '@vtex/faststore/components',\n component: PricingPromotion,\n editor: { label: 'Promotion', category: 'commerce' },\n schema: {\n template: { type: 'string', default: '{name}', label: 'Template' },\n },\n guideline:\n 'Renders a single promotion using the {name} template placeholder; must be a descendant of PricingPromotions.',\n});\n\n// ---------------------------------------------------------------------------\n// Implementations\n// ---------------------------------------------------------------------------\n\nexport function PricingRoot({ $data: $dataProp, selectedVariantId, children, ...props }: PricingRootProps) {\n const { locale, currency } = useStorefrontContext();\n const productSlice = useDataOverride($dataProp) ?? null;\n\n // The VariantSelector matter publishes the shopper's in-page selection here; reading it lets\n // pricing recompute when a swatch changes without a page navigation. Scope the published selection\n // to this product so a swatch picked on another PDP does not leak in after client-side navigation.\n // The explicit selectedVariantId prop is the pre-selection fallback; the live selection wins.\n const publishedSelection = useReactiveVar(selectedVariantVar);\n const publishedVariantId = publishedVariantIdFor(publishedSelection, productSlice?.id ?? null);\n const activeVariantId = publishedVariantId ?? selectedVariantId;\n\n if (activeVariantId) {\n return (\n <Suspense fallback={null}>\n <HotDataProvider\n query={variantQuery}\n variables={{ id: activeVariantId }}\n field=\"node\"\n fallbackData={productSlice}\n >\n <PricingProvider fallbackProductSlice={productSlice} currency={currency} locale={locale} {...props}>\n {children}\n </PricingProvider>\n </HotDataProvider>\n </Suspense>\n );\n }\n\n const transformed = productSlice ? transformPricingData(productSlice) : null;\n\n return (\n <PricingView transformed={transformed} currency={currency} locale={locale} {...props}>\n {children}\n </PricingView>\n );\n}\n\n/**\n * What `PricingRoot` hands its inner views: the container props plus the locale and currency it read\n * from the storefront context. They are internal parameters, not a public prop — `PricingRootProps`\n * no longer carries either.\n */\ntype PricingViewBaseProps = ComponentPropsWithRef<'div'> & {\n currency?: string;\n locale?: string;\n};\n\ntype PricingProviderProps = PricingViewBaseProps & {\n fallbackProductSlice: RawPricingData | null;\n};\n\n// Reads the override written by the nested HotDataProvider: a Variant node when the variant fetch\n// succeeds, or the product slice (fallbackData) on error/null. Dispatch on __typename and always\n// source the product path from the explicit fallback prop so a mis-passed Product node id can never\n// crash the variant transform.\nfunction PricingProvider({ fallbackProductSlice, ...viewProps }: PricingProviderProps) {\n const override = useDataOverride<unknown>(null);\n const overrideTypename = (override as { __typename?: string } | null)?.__typename;\n\n let transformed: NormalizedPricingOffer | null = null;\n if (overrideTypename === 'Variant') {\n transformed = transformVariantPricingData(override as VariantSlice);\n } else if (fallbackProductSlice) {\n transformed = transformPricingData(fallbackProductSlice);\n }\n\n return <PricingView transformed={transformed} {...viewProps} />;\n}\n\ntype PricingViewProps = PricingViewBaseProps & {\n transformed: NormalizedPricingOffer | null;\n};\n\nfunction PricingView({\n transformed,\n currency: currencyProp,\n locale: localeProp,\n className,\n children,\n ...props\n}: PricingViewProps) {\n let contextValue: PricingContextValue = null;\n\n if (transformed) {\n const { price, listPrice, spotPrice, installmentPlans, discountHighlights, promotions } = transformed;\n // `PricingRoot` always hands these down from the context; the offer's own currency is the same\n // channel's by construction, so it is a fallback only for a directly-rendered view.\n const currency = currencyProp ?? transformed.currency;\n // `PricingRoot` always supplies it from the context; a directly-rendered view falls back to the\n // platform default rather than a Brazilian one.\n const locale = localeProp;\n const hasDiscount = listPrice > price;\n const hasSpotDiscount = spotPrice < price;\n const discountPercentage = hasDiscount ? Math.round(((listPrice - price) / listPrice) * 100) : 0;\n const spotDiscountPercentage = hasSpotDiscount ? Math.round(((price - spotPrice) / price) * 100) : 0;\n const bestInstallment = findBestInstallment(installmentPlans);\n\n contextValue = {\n price,\n listPrice,\n spotPrice,\n currency,\n locale,\n installmentPlans,\n discountHighlights,\n promotions,\n hasDiscount,\n hasSpotDiscount,\n discountPercentage,\n spotDiscountPercentage,\n bestInstallment,\n };\n }\n\n return (\n <PricingContext value={contextValue}>\n <div {...props} className={className} data-fs-pricing=\"\">\n {children}\n </div>\n </PricingContext>\n );\n}\n\nexport function PricingSellingPrice({ className, children, ...props }: PricingSellingPriceProps) {\n const ctx = usePricing();\n if (!ctx) return null;\n\n const formatted = formatPrice(ctx.price, ctx.locale, ctx.currency);\n\n return (\n <span {...props} className={className} data-fs-pricing-selling-price=\"\">\n {children ?? formatted}\n </span>\n );\n}\n\nexport function PricingListPrice({ className, children, ...props }: PricingListPriceProps) {\n const ctx = usePricing();\n if (!ctx || !ctx.hasDiscount) return null;\n\n const formatted = formatPrice(ctx.listPrice, ctx.locale, ctx.currency);\n\n return (\n <span {...props} className={className} data-fs-pricing-list-price=\"\">\n {children ?? formatted}\n </span>\n );\n}\n\nexport function PricingSpotPrice({ className, children, ...props }: PricingSpotPriceProps) {\n const ctx = usePricing();\n if (!ctx || !ctx.hasSpotDiscount) return null;\n\n const formatted = formatPrice(ctx.spotPrice, ctx.locale, ctx.currency);\n\n return (\n <span {...props} className={className} data-fs-pricing-spot-price=\"\">\n {children ?? formatted}\n </span>\n );\n}\n\nexport function PricingInstallments({ className, children, ...props }: PricingInstallmentsProps) {\n const ctx = usePricing();\n if (!ctx || !ctx.bestInstallment) return null;\n\n return (\n <InstallmentItemContext value={ctx.bestInstallment}>\n <div {...props} className={className} data-fs-pricing-installments=\"\">\n {children}\n </div>\n </InstallmentItemContext>\n );\n}\n\nexport function PricingInstallmentPlans({ className, children, ...props }: PricingInstallmentPlansProps) {\n const ctx = usePricing();\n if (!ctx || ctx.installmentPlans.length === 0) return null;\n\n const sortedPlans = ctx.installmentPlans\n .map((plan) => ({ plan, bestInstallment: findBestInstallment([plan]) }))\n .sort((a, b) => {\n const aCount = a.bestInstallment?.count ?? Number.POSITIVE_INFINITY;\n const bCount = b.bestInstallment?.count ?? Number.POSITIVE_INFINITY;\n return aCount - bCount;\n });\n\n return (\n <div {...props} className={className} data-fs-pricing-installment-plans=\"\">\n {sortedPlans.map(({ plan, bestInstallment }, index) => (\n <InstallmentPlanItemContext\n key={`${plan.paymentType}-${plan.paymentMethod}-${index}`}\n value={{\n paymentMethod: plan.paymentMethod,\n paymentType: plan.paymentType,\n installments: plan.installments,\n bestInstallment,\n }}\n >\n {children}\n </InstallmentPlanItemContext>\n ))}\n </div>\n );\n}\n\nexport function PricingInstallmentPlan({ className, children, ...props }: PricingInstallmentPlanProps) {\n const plan = useInstallmentPlanItem();\n if (!plan.bestInstallment) return null;\n\n return (\n <InstallmentItemContext value={plan.bestInstallment}>\n <div\n {...props}\n className={className}\n data-fs-pricing-installment-plan=\"\"\n data-fs-pricing-installment-plan-type={plan.paymentType}\n >\n {children}\n </div>\n </InstallmentItemContext>\n );\n}\n\nexport function PricingInstallmentsForPlan({ className, children, ...props }: PricingInstallmentsForPlanProps) {\n const plan = useInstallmentPlanItem('PricingInstallmentsForPlan', 'PricingInstallmentPlan');\n if (plan.installments.length === 0) return null;\n\n return (\n <div {...props} className={className} data-fs-pricing-installments-for-plan=\"\">\n {plan.installments.map((installment, index) => (\n <InstallmentItemContext key={`${installment.count}-${index}`} value={installment}>\n {children}\n </InstallmentItemContext>\n ))}\n </div>\n );\n}\n\nexport function PricingPaymentMethodsTrigger({ className, children, ...props }: PricingPaymentMethodsTriggerProps) {\n return (\n <PopoverTrigger {...props} className={className} data-fs-pricing-payment-methods-trigger=\"\">\n {children}\n </PopoverTrigger>\n );\n}\n\nexport function PricingPaymentMethodsList({ className, children, ...props }: PricingPaymentMethodsListProps) {\n const ctx = usePricing();\n if (!ctx || ctx.installmentPlans.length === 0) return null;\n\n return (\n <div {...props} className={className} data-fs-pricing-payment-methods-list=\"\">\n <PricingInstallmentPlans>{children}</PricingInstallmentPlans>\n </div>\n );\n}\n\nfunction sortPlansForTabs(plans: InstallmentPlanData[]) {\n return plans\n .map((plan) => ({\n plan,\n bestInstallment: findBestInstallment([plan]),\n tabValue: `${plan.paymentType}-${plan.paymentMethod}`,\n }))\n .sort((a, b) => {\n const aCount = a.bestInstallment?.count ?? Number.POSITIVE_INFINITY;\n const bCount = b.bestInstallment?.count ?? Number.POSITIVE_INFINITY;\n return aCount - bCount;\n });\n}\n\nexport function PricingPaymentMethodsTabList({ className, children, ...props }: PricingPaymentMethodsTabListProps) {\n const ctx = usePricing();\n if (!ctx || ctx.installmentPlans.length === 0) return null;\n\n return (\n <div {...props} className={className} data-fs-pricing-payment-methods-tab-list=\"\">\n {sortPlansForTabs(ctx.installmentPlans).map(({ plan, bestInstallment, tabValue }) => (\n <InstallmentPlanItemContext\n key={tabValue}\n value={{\n paymentMethod: plan.paymentMethod,\n paymentType: plan.paymentType,\n installments: plan.installments,\n bestInstallment,\n }}\n >\n <TabsTab value={tabValue}>{children}</TabsTab>\n </InstallmentPlanItemContext>\n ))}\n </div>\n );\n}\n\nexport function PricingPaymentMethodsTabPanels({ className, children, ...props }: PricingPaymentMethodsTabPanelsProps) {\n const ctx = usePricing();\n if (!ctx || ctx.installmentPlans.length === 0) return null;\n\n return (\n <div {...props} className={className} data-fs-pricing-payment-methods-tab-panels=\"\">\n {sortPlansForTabs(ctx.installmentPlans).map(({ plan, bestInstallment, tabValue }) => (\n <InstallmentPlanItemContext\n key={tabValue}\n value={{\n paymentMethod: plan.paymentMethod,\n paymentType: plan.paymentType,\n installments: plan.installments,\n bestInstallment,\n }}\n >\n <TabsPanel value={tabValue}>{children}</TabsPanel>\n </InstallmentPlanItemContext>\n ))}\n </div>\n );\n}\n\nexport function PricingPaymentMethodName({ className, children, ...props }: PricingPaymentMethodNameProps) {\n const plan = useInstallmentPlanItem();\n\n return (\n <span {...props} className={className} data-fs-pricing-payment-method-name=\"\">\n {children ?? plan.paymentMethod}\n </span>\n );\n}\n\nexport function PricingInstallment({\n template = '{count}x de {value}',\n interestFreeLabel = 'sem juros',\n className,\n children,\n ...props\n}: PricingInstallmentProps) {\n const installment = useInstallmentItem();\n const ctx = usePricing();\n if (!ctx) return null;\n\n const formattedValue = formatPrice(installment.value, ctx.locale, ctx.currency);\n const base = template.replace('{count}', String(installment.count)).replace('{value}', formattedValue);\n const text = installment.interestFree && interestFreeLabel ? `${base} ${interestFreeLabel}` : base;\n\n return (\n <span {...props} className={className} data-fs-pricing-installment=\"\">\n {children ?? text}\n </span>\n );\n}\n\nexport function PricingDiscount({\n template,\n format = 'percentage',\n className,\n children,\n ...props\n}: PricingDiscountProps) {\n const ctx = usePricing();\n if (!ctx || !ctx.hasDiscount) return null;\n\n const amount = ctx.listPrice - ctx.price;\n const formattedAmount = formatPrice(amount, ctx.locale, ctx.currency);\n const resolvedTemplate = template ?? (format === 'absolute' ? '-{amount}' : '-{percentage}%');\n const text = resolvedTemplate\n .replaceAll('{percentage}', String(ctx.discountPercentage))\n .replaceAll('{amount}', formattedAmount);\n\n return (\n <span {...props} className={className} data-fs-pricing-discount=\"\">\n {children ?? text}\n </span>\n );\n}\n\nexport function PricingSpotDiscount({\n template = '-{percentage}%',\n className,\n children,\n ...props\n}: PricingSpotDiscountProps) {\n const ctx = usePricing();\n if (!ctx || ctx.spotDiscountPercentage <= 0) return null;\n\n const text = template.replace('{percentage}', String(ctx.spotDiscountPercentage));\n\n return (\n <span {...props} className={className} data-fs-pricing-spot-discount=\"\">\n {children ?? text}\n </span>\n );\n}\n\nexport function PricingHighlights({ className, children, ...props }: PricingHighlightsProps) {\n const ctx = usePricing();\n if (!ctx || ctx.discountHighlights.length === 0) return null;\n\n return (\n <div {...props} className={className} data-fs-pricing-highlights=\"\">\n {ctx.discountHighlights.map((highlight, index) => (\n <HighlightItemContext key={`${highlight}-${index}`} value={highlight}>\n {children}\n </HighlightItemContext>\n ))}\n </div>\n );\n}\n\nexport function PricingHighlight({ className, children, ...props }: PricingHighlightProps) {\n const highlight = useHighlightItem();\n\n return (\n <span {...props} className={className} data-fs-pricing-highlight=\"\">\n {children ?? highlight}\n </span>\n );\n}\n\nexport function PricingPromotions({ className, children, ...props }: PricingPromotionsProps) {\n const ctx = usePricing();\n if (!ctx || ctx.promotions.length === 0) return null;\n\n return (\n <div {...props} className={className} data-fs-pricing-promotions=\"\">\n {ctx.promotions.map((promotion, index) => (\n <PromotionItemContext key={`${promotion.name}-${index}`} value={promotion}>\n {children}\n </PromotionItemContext>\n ))}\n </div>\n );\n}\n\nexport function PricingPromotion({ template = '{name}', className, children, ...props }: PricingPromotionProps) {\n const promotion = usePromotionItem();\n const text = template.replace('{name}', promotion.name);\n\n return (\n <span {...props} className={className} data-fs-pricing-promotion=\"\">\n {children ?? text}\n </span>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Skeleton\n// ---------------------------------------------------------------------------\n\nexport function PricingSkeleton({ className, ...props }: ComponentPropsWithRef<'div'>) {\n return (\n <div {...props} className={className} data-fs-pricing-skeleton=\"\" aria-hidden=\"true\">\n <span data-fs-pricing-skeleton-line=\"\" />\n <span data-fs-pricing-skeleton-line=\"\" />\n </div>\n );\n}\n\nPricingRoot.Skeleton = PricingSkeleton;\n\n// ---------------------------------------------------------------------------\n// Namespace export\n// ---------------------------------------------------------------------------\n\nexport const Pricing = {\n Root: PricingRoot,\n SellingPrice: PricingSellingPrice,\n ListPrice: PricingListPrice,\n SpotPrice: PricingSpotPrice,\n Installments: PricingInstallments,\n InstallmentPlans: PricingInstallmentPlans,\n InstallmentPlan: PricingInstallmentPlan,\n InstallmentsForPlan: PricingInstallmentsForPlan,\n Installment: PricingInstallment,\n PaymentMethodsTrigger: PricingPaymentMethodsTrigger,\n PaymentMethodsList: PricingPaymentMethodsList,\n PaymentMethodsTabList: PricingPaymentMethodsTabList,\n PaymentMethodsTabPanels: PricingPaymentMethodsTabPanels,\n PaymentMethodName: PricingPaymentMethodName,\n Discount: PricingDiscount,\n SpotDiscount: PricingSpotDiscount,\n Highlights: PricingHighlights,\n Highlight: PricingHighlight,\n Promotions: PricingPromotions,\n Promotion: PricingPromotion,\n Skeleton: PricingSkeleton,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"pricing.js","names":[],"sources":["../../../src/matter/pricing/pricing.tsx"],"sourcesContent":["'use client';\n\nimport { useReactiveVar } from '@apollo/client/react';\nimport { defineComponent } from '@vtex/fs-core';\nimport type { ComponentPropsWithRef } from 'react';\nimport { createContext, Suspense, useContext } from 'react';\nimport { PopoverTrigger } from '../../particles/popover/popover.js';\nimport { TabsPanel, TabsTab } from '../../particles/tabs/tabs.js';\nimport { useStorefrontContext } from '../../sdk/context/storefront-context.js';\nimport { useDataOverride } from '../../sdk/data/data-override-context.js';\nimport { HotDataProvider } from '../../sdk/data/hot-data-provider.js';\nimport { graphql } from '../../sdk/generated/gql.js';\nimport type { VariantPricingDataFragment } from '../../sdk/generated/graphql.js';\nimport { resolveDefaultSeller } from '../../sdk/seller.js';\nimport { publishedVariantIdFor, selectedVariantVar } from '../../sdk/state/variant-selector.js';\n\n// ---------------------------------------------------------------------------\n// GraphQL Fragment\n// ---------------------------------------------------------------------------\n\nconst fragment = /* GraphQL */ `\n fragment PricingData on Query {\n productBySlug(slug: $slug) {\n __typename\n id\n variants(first: 1) {\n edges {\n node {\n sellers {\n isDefault\n offer {\n price { amount currencyCode }\n listPrice { amount currencyCode }\n spotPrice { amount currencyCode }\n installmentPlans {\n paymentMethod\n paymentType\n installments {\n count\n value { amount currencyCode }\n totalAmount { amount currencyCode }\n interestRate\n interestFree\n }\n }\n discountHighlights\n promotions {\n name\n }\n }\n }\n }\n }\n }\n }\n }\n`;\n\n// The variant offer slice, authored via graphql() so HotDataProvider gets a TypedDocumentNode.\n// Declared so codegen scans the source and emits VariantPricingDataFragment; the fragment is spread\n// into variantQuery at the GraphQL layer, so the variable is unused at runtime.\nconst _variantFragment = graphql(`\n fragment VariantPricingData on Variant {\n __typename\n id\n sellers {\n isDefault\n offer {\n price { amount currencyCode }\n listPrice { amount currencyCode }\n spotPrice { amount currencyCode }\n installmentPlans {\n paymentMethod\n paymentType\n installments {\n count\n value { amount currencyCode }\n totalAmount { amount currencyCode }\n interestRate\n interestFree\n }\n }\n discountHighlights\n promotions {\n name\n }\n }\n }\n }\n`);\n\nconst variantQuery = graphql(`\n query VariantPricingQuery($id: ID!) {\n node(id: $id) {\n __typename\n ... on Variant {\n ...VariantPricingData\n }\n }\n }\n`);\n\n// ---------------------------------------------------------------------------\n// Raw data types (shape of the fragment result)\n// ---------------------------------------------------------------------------\n\ntype MoneyValue = {\n amount: number;\n currencyCode: string;\n};\n\ntype RawPromotion = {\n name: string;\n};\n\ntype RawOffer = {\n price: MoneyValue;\n listPrice: MoneyValue;\n spotPrice: MoneyValue;\n installmentPlans: Array<{\n paymentMethod: string;\n paymentType: string;\n installments: Array<{\n count: number;\n value: MoneyValue;\n totalAmount: MoneyValue;\n interestRate: number;\n interestFree: boolean;\n }>;\n }>;\n discountHighlights: string[];\n promotions: RawPromotion[];\n};\n\ntype RawPricingData = {\n // __typename/id are optional so existing fixtures (which omit them) still typecheck; the real\n // page query always supplies id, which scopes the published variant selection to this product.\n __typename?: string;\n id?: string;\n variants: {\n edges: Array<{\n node: {\n sellers: Array<{\n isDefault: boolean;\n offer: RawOffer | null;\n }>;\n };\n }>;\n };\n};\n\ntype VariantSlice = VariantPricingDataFragment;\n\ntype NormalizedPricingOffer = {\n price: number;\n listPrice: number;\n spotPrice: number;\n currency: string;\n installmentPlans: InstallmentPlanData[];\n discountHighlights: string[];\n promotions: PromotionData[];\n};\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ntype InstallmentData = {\n count: number;\n value: number;\n totalAmount: number;\n interestRate: number;\n interestFree: boolean;\n};\n\ntype InstallmentPlanData = {\n paymentMethod: string;\n paymentType: string;\n installments: InstallmentData[];\n};\n\ntype PromotionData = {\n name: string;\n};\n\ntype PricingContextData = {\n price: number;\n listPrice: number;\n spotPrice: number;\n currency: string;\n /** Undefined only for a directly-rendered view: `Intl` reads it as the platform default. */\n locale: string | undefined;\n installmentPlans: InstallmentPlanData[];\n discountHighlights: string[];\n promotions: PromotionData[];\n hasDiscount: boolean;\n hasSpotDiscount: boolean;\n discountPercentage: number;\n spotDiscountPercentage: number;\n bestInstallment: InstallmentData | null;\n};\n\ntype PricingContextValue = PricingContextData | null;\n\ntype InstallmentPlanItemContextData = {\n paymentMethod: string;\n paymentType: string;\n installments: InstallmentData[];\n bestInstallment: InstallmentData | null;\n};\n\nconst PRICING_CONTEXT_UNSET = Symbol('PricingContextUnset');\n\nexport type PricingRootProps = ComponentPropsWithRef<'div'> & {\n $data?: RawPricingData | null;\n /** Page-supplied viewed SKU; pre-selects the offer on first paint. A published swatch selection\n * wins over it once the shopper interacts. */\n selectedVariantId?: string;\n};\n\nexport type PricingSellingPriceProps = ComponentPropsWithRef<'span'>;\n\nexport type PricingListPriceProps = ComponentPropsWithRef<'span'>;\n\nexport type PricingSpotPriceProps = ComponentPropsWithRef<'span'>;\n\nexport type PricingInstallmentsProps = ComponentPropsWithRef<'div'>;\n\nexport type PricingInstallmentPlansProps = ComponentPropsWithRef<'div'>;\n\nexport type PricingInstallmentPlanProps = ComponentPropsWithRef<'div'>;\n\nexport type PricingInstallmentsForPlanProps = ComponentPropsWithRef<'div'>;\n\nexport type PricingPaymentMethodsTriggerProps = ComponentPropsWithRef<'button'>;\n\nexport type PricingPaymentMethodsListProps = ComponentPropsWithRef<'div'>;\n\nexport type PricingPaymentMethodsTabListProps = ComponentPropsWithRef<'div'>;\n\nexport type PricingPaymentMethodsTabPanelsProps = ComponentPropsWithRef<'div'>;\n\nexport type PricingPaymentMethodNameProps = ComponentPropsWithRef<'span'>;\n\nexport type PricingInstallmentProps = ComponentPropsWithRef<'span'> & {\n template?: string;\n interestFreeLabel?: string;\n};\n\nexport type PricingDiscountProps = ComponentPropsWithRef<'span'> & {\n template?: string;\n format?: 'percentage' | 'absolute';\n};\n\nexport type PricingHighlightsProps = ComponentPropsWithRef<'div'>;\n\nexport type PricingHighlightProps = ComponentPropsWithRef<'span'>;\n\nexport type PricingPromotionsProps = ComponentPropsWithRef<'div'>;\n\nexport type PricingPromotionProps = ComponentPropsWithRef<'span'> & {\n template?: string;\n};\n\nexport type PricingSpotDiscountProps = ComponentPropsWithRef<'span'> & {\n template?: string;\n};\n\n// ---------------------------------------------------------------------------\n// Context\n// ---------------------------------------------------------------------------\n\nconst PricingContext = createContext<PricingContextValue | typeof PRICING_CONTEXT_UNSET>(PRICING_CONTEXT_UNSET);\n\nconst InstallmentItemContext = createContext<InstallmentData | null>(null);\n\nconst InstallmentPlanItemContext = createContext<InstallmentPlanItemContextData | null>(null);\n\nconst HighlightItemContext = createContext<string | null>(null);\n\nconst PromotionItemContext = createContext<PromotionData | null>(null);\n\nfunction usePricing(): PricingContextValue {\n const ctx = useContext(PricingContext);\n if (ctx === PRICING_CONTEXT_UNSET) {\n throw new Error('Pricing components must be used inside PricingRoot.');\n }\n return ctx;\n}\n\nfunction useInstallmentItem(): InstallmentData {\n const ctx = useContext(InstallmentItemContext);\n if (!ctx) {\n throw new Error('PricingInstallment must be used inside PricingInstallments.');\n }\n return ctx;\n}\n\nexport function useInstallmentPlanItem(\n caller = 'PricingInstallmentPlan',\n parent = 'PricingInstallmentPlans',\n): InstallmentPlanItemContextData {\n const ctx = useContext(InstallmentPlanItemContext);\n if (!ctx) {\n throw new Error(`${caller} must be used inside ${parent}.`);\n }\n return ctx;\n}\n\nfunction useHighlightItem(): string {\n const ctx = useContext(HighlightItemContext);\n if (ctx === null) {\n throw new Error('PricingHighlight must be used inside PricingHighlights.');\n }\n return ctx;\n}\n\nfunction usePromotionItem(): PromotionData {\n const ctx = useContext(PromotionItemContext);\n if (!ctx) {\n throw new Error('PricingPromotion must be used inside PricingPromotions.');\n }\n return ctx;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction formatPrice(value: number, locale: string | undefined, currency: string): string {\n return new Intl.NumberFormat(locale, { style: 'currency', currency }).format(value);\n}\n\nfunction findBestInstallment(plans: InstallmentPlanData[]): InstallmentData | null {\n const allInstallments = plans.flatMap((plan) => plan.installments);\n if (allInstallments.length === 0) return null;\n\n const interestFree = allInstallments.filter((i) => i.interestFree);\n if (interestFree.length > 0) {\n return interestFree.reduce((best, current) => (current.count > best.count ? current : best));\n }\n\n return allInstallments.reduce((best, current) => (current.count > best.count ? current : best));\n}\n\n// ---------------------------------------------------------------------------\n// Transform\n// ---------------------------------------------------------------------------\n\n// The GraphQL `Decimal` scalar is serialized as a string over the wire; convert it here so every\n// later comparison and subtraction works on numbers.\nfunction normalizeOffer(offer: RawOffer): NormalizedPricingOffer {\n return {\n price: Number(offer.price.amount),\n listPrice: Number(offer.listPrice.amount),\n spotPrice: Number(offer.spotPrice.amount),\n currency: offer.price.currencyCode,\n installmentPlans: offer.installmentPlans.map((plan) => ({\n paymentMethod: plan.paymentMethod,\n paymentType: plan.paymentType,\n installments: plan.installments.map((inst) => ({\n count: inst.count,\n value: Number(inst.value.amount),\n totalAmount: Number(inst.totalAmount.amount),\n interestRate: inst.interestRate,\n interestFree: inst.interestFree,\n })),\n })),\n discountHighlights: offer.discountHighlights,\n promotions: offer.promotions.map((promotion) => ({ name: promotion.name })),\n };\n}\n\n// Resolves a variant's default seller and normalizes its offer, or null when that seller has no\n// offer. Shared by the product-level and selected-variant transforms so the default-seller + offer\n// gate lives in one place.\nfunction pricingOfferFromVariant(variant: {\n sellers: readonly { isDefault: boolean; offer: RawOffer | null }[];\n}): NormalizedPricingOffer | null {\n const seller = resolveDefaultSeller(variant.sellers);\n const offer = seller?.offer;\n if (!offer) return null;\n\n return normalizeOffer(offer);\n}\n\nfunction transformPricingData(data: RawPricingData): NormalizedPricingOffer | null {\n const edge = data.variants.edges[0];\n if (!edge) return null;\n\n return pricingOfferFromVariant(edge.node);\n}\n\nexport function transformVariantPricingData(variant: VariantSlice): NormalizedPricingOffer | null {\n return pricingOfferFromVariant(variant);\n}\n\n// ---------------------------------------------------------------------------\n// Definitions\n// ---------------------------------------------------------------------------\n\nexport const PricingRootDefinition = defineComponent<PricingRootProps>({\n name: 'PricingRoot',\n importPath: '@vtex/faststore/components',\n component: PricingRoot,\n fragment,\n fetchStrategy: 'lazy',\n skeleton: PricingSkeleton,\n editor: { label: 'Pricing', category: 'commerce' },\n schema: {\n selectedVariantId: { type: 'string', label: 'Selected Variant ID' },\n },\n guideline:\n 'Root container for the PDP pricing block; all other Pricing sub-components must be descendants of it. Automatically recomputes the offer when a shopper picks a VariantSelector swatch (it reads the published variant selection); the selectedVariantId prop is an optional pre-selection fallback. Falls back silently to the product-level offer on variant fetch error. See pricing.md.',\n});\n\nexport const PricingSellingPriceDefinition = defineComponent<PricingSellingPriceProps>({\n name: 'PricingSellingPrice',\n importPath: '@vtex/faststore/components',\n component: PricingSellingPrice,\n editor: { label: 'Selling Price', category: 'commerce' },\n schema: {},\n guideline: 'Displays the current selling price; must be a descendant of PricingRoot.',\n});\n\nexport const PricingListPriceDefinition = defineComponent<PricingListPriceProps>({\n name: 'PricingListPrice',\n importPath: '@vtex/faststore/components',\n component: PricingListPrice,\n editor: { label: 'List Price', category: 'commerce' },\n schema: {},\n guideline:\n 'Displays the original (strikethrough) list price; only renders when a discount exists. Must be a descendant of PricingRoot.',\n});\n\nexport const PricingSpotPriceDefinition = defineComponent<PricingSpotPriceProps>({\n name: 'PricingSpotPrice',\n importPath: '@vtex/faststore/components',\n component: PricingSpotPrice,\n editor: { label: 'Spot Price', category: 'commerce' },\n schema: {},\n guideline:\n 'Displays the best cash/instant-payment price (e.g. Pix); only renders when spotPrice is lower than the selling price. Must be a descendant of PricingRoot.',\n});\n\nexport const PricingInstallmentsDefinition = defineComponent<PricingInstallmentsProps>({\n name: 'PricingInstallments',\n importPath: '@vtex/faststore/components',\n component: PricingInstallments,\n editor: { label: 'Installments', category: 'commerce' },\n schema: {},\n guideline:\n 'Shortcut container that exposes the single best installment across all plans; use PricingInstallmentPlans instead when a per-payment-method breakdown is needed. Must be a descendant of PricingRoot.',\n});\n\nexport const PricingInstallmentPlansDefinition = defineComponent<PricingInstallmentPlansProps>({\n name: 'PricingInstallmentPlans',\n importPath: '@vtex/faststore/components',\n component: PricingInstallmentPlans,\n editor: { label: 'Installment Plans', category: 'commerce' },\n schema: {},\n guideline:\n 'Renders one row per payment method; use PricingInstallments instead when only the single best plan is needed. Must be a descendant of PricingRoot.',\n});\n\nexport const PricingInstallmentPlanDefinition = defineComponent<PricingInstallmentPlanProps>({\n name: 'PricingInstallmentPlan',\n importPath: '@vtex/faststore/components',\n component: PricingInstallmentPlan,\n editor: { label: 'Installment Plan', category: 'commerce' },\n schema: {},\n guideline:\n 'Renders a single plan row inside PricingInstallmentPlans; nest PricingInstallmentsForPlan inside it to list every installment tier instead of just the best one. Must be a descendant of PricingInstallmentPlans.',\n});\n\nexport const PricingInstallmentsForPlanDefinition = defineComponent<PricingInstallmentsForPlanProps>({\n name: 'PricingInstallmentsForPlan',\n importPath: '@vtex/faststore/components',\n component: PricingInstallmentsForPlan,\n editor: { label: 'Installments For Plan', category: 'commerce' },\n schema: {},\n guideline:\n 'Iterates every installment tier (1x, 2x, … Nx) of the enclosing plan; must be a descendant of PricingInstallmentPlan.',\n});\n\nexport const PricingPaymentMethodsTriggerDefinition = defineComponent<PricingPaymentMethodsTriggerProps>({\n name: 'PricingPaymentMethodsTrigger',\n importPath: '@vtex/faststore/components',\n component: PricingPaymentMethodsTrigger,\n editor: { label: 'Payment Methods Trigger', category: 'action' },\n schema: {},\n guideline: 'Button that opens the payment-methods disclosure panel; must be a descendant of PopoverRoot.',\n});\n\nexport const PricingPaymentMethodsListDefinition = defineComponent<PricingPaymentMethodsListProps>({\n name: 'PricingPaymentMethodsList',\n importPath: '@vtex/faststore/components',\n component: PricingPaymentMethodsList,\n editor: { label: 'Payment Methods List', category: 'commerce' },\n schema: {},\n guideline:\n 'Flat disclosure panel content listing every payment plan; place inside PopoverPopup, DialogPopup, or DrawerPopup. Must be a descendant of PricingRoot.',\n});\n\nexport const PricingPaymentMethodsTabListDefinition = defineComponent<PricingPaymentMethodsTabListProps>({\n name: 'PricingPaymentMethodsTabList',\n importPath: '@vtex/faststore/components',\n component: PricingPaymentMethodsTabList,\n editor: { label: 'Payment Methods Tab List', category: 'commerce' },\n schema: {},\n guideline:\n 'Emits one tab per payment plan for the tab-grouped disclosure pattern; must be a descendant of TabsList (which is inside TabsRoot). Pair with PricingPaymentMethodsTabPanels.',\n});\n\nexport const PricingPaymentMethodsTabPanelsDefinition = defineComponent<PricingPaymentMethodsTabPanelsProps>({\n name: 'PricingPaymentMethodsTabPanels',\n importPath: '@vtex/faststore/components',\n component: PricingPaymentMethodsTabPanels,\n editor: { label: 'Payment Methods Tab Panels', category: 'commerce' },\n schema: {},\n guideline:\n 'Emits one panel per payment plan for the tab-grouped disclosure pattern; must be a sibling of TabsList under TabsRoot (not nested inside TabsList). Pair with PricingPaymentMethodsTabList.',\n});\n\nexport const PricingPaymentMethodNameDefinition = defineComponent<PricingPaymentMethodNameProps>({\n name: 'PricingPaymentMethodName',\n importPath: '@vtex/faststore/components',\n component: PricingPaymentMethodName,\n editor: { label: 'Payment Method Name', category: 'commerce' },\n schema: {},\n guideline:\n 'Renders the enclosing plan\\'s payment method name (e.g. \"Visa\", \"Pix\"); must be inside a plan context — PricingInstallmentPlan, PricingPaymentMethodsTabList, or PricingPaymentMethodsTabPanels.',\n});\n\nexport const PricingInstallmentDefinition = defineComponent<PricingInstallmentProps>({\n name: 'PricingInstallment',\n importPath: '@vtex/faststore/components',\n component: PricingInstallment,\n editor: { label: 'Installment', category: 'commerce' },\n schema: {\n template: { type: 'string', default: '{count}x de {value}', label: 'Template' },\n interestFreeLabel: { type: 'string', default: 'sem juros', label: 'Interest-free label' },\n },\n guideline:\n 'Renders a single installment line using {count} and {value} template placeholders; must be a descendant of PricingInstallments, PricingInstallmentPlan, or PricingInstallmentsForPlan.',\n});\n\nexport const PricingDiscountDefinition = defineComponent<PricingDiscountProps>({\n name: 'PricingDiscount',\n importPath: '@vtex/faststore/components',\n component: PricingDiscount,\n editor: { label: 'Discount Badge', category: 'commerce' },\n schema: {\n format: { type: ['percentage', 'absolute'] as const, default: 'percentage', label: 'Discount Format' },\n template: { type: 'string', label: 'Template' },\n },\n guideline:\n 'Discount badge for the listPrice-vs-price markdown; use PricingSpotDiscount instead for the spotPrice-vs-price (Pix/cash) percentage. The format prop switches between a percentage (-25%, default) and an absolute amount (-R$ 10,00); the template supports {percentage} and {amount} placeholders and defaults to the format-appropriate one. Recomputes automatically on swatch change. Must be a descendant of PricingRoot.',\n});\n\nexport const PricingSpotDiscountDefinition = defineComponent<PricingSpotDiscountProps>({\n name: 'PricingSpotDiscount',\n importPath: '@vtex/faststore/components',\n component: PricingSpotDiscount,\n editor: { label: 'Spot Discount Badge', category: 'commerce' },\n schema: {\n template: { type: 'string', default: '-{percentage}%', label: 'Template' },\n },\n guideline:\n 'Discount badge for the spotPrice-vs-price (cash/Pix) percentage; use PricingDiscount instead for the listPrice-vs-price percentage. Must be a descendant of PricingRoot.',\n});\n\nexport const PricingHighlightsDefinition = defineComponent<PricingHighlightsProps>({\n name: 'PricingHighlights',\n importPath: '@vtex/faststore/components',\n component: PricingHighlights,\n editor: { label: 'Highlights', category: 'commerce' },\n schema: {},\n guideline:\n 'Iterates the offer\\'s discount highlight labels (e.g. \"Black Friday\", \"Exclusivo\"); place PricingHighlight as a child. Must be a descendant of PricingRoot.',\n});\n\nexport const PricingHighlightDefinition = defineComponent<PricingHighlightProps>({\n name: 'PricingHighlight',\n importPath: '@vtex/faststore/components',\n component: PricingHighlight,\n editor: { label: 'Highlight', category: 'commerce' },\n schema: {},\n guideline: 'Renders a single highlight label as a span; must be a descendant of PricingHighlights.',\n});\n\nexport const PricingPromotionsDefinition = defineComponent<PricingPromotionsProps>({\n name: 'PricingPromotions',\n importPath: '@vtex/faststore/components',\n component: PricingPromotions,\n editor: { label: 'Promotions', category: 'commerce' },\n schema: {},\n guideline:\n 'Iterates the offer\\'s structured promotions (e.g. \"Compre 3 leve 2\"); place PricingPromotion as a child. Must be a descendant of PricingRoot.',\n});\n\nexport const PricingPromotionDefinition = defineComponent<PricingPromotionProps>({\n name: 'PricingPromotion',\n importPath: '@vtex/faststore/components',\n component: PricingPromotion,\n editor: { label: 'Promotion', category: 'commerce' },\n schema: {\n template: { type: 'string', default: '{name}', label: 'Template' },\n },\n guideline:\n 'Renders a single promotion using the {name} template placeholder; must be a descendant of PricingPromotions.',\n});\n\n// ---------------------------------------------------------------------------\n// Implementations\n// ---------------------------------------------------------------------------\n\nexport function PricingRoot({ $data: $dataProp, selectedVariantId, children, ...props }: PricingRootProps) {\n const { locale, currency } = useStorefrontContext();\n const productSlice = useDataOverride($dataProp) ?? null;\n\n // The VariantSelector matter publishes the shopper's in-page selection here; reading it lets\n // pricing recompute when a swatch changes without a page navigation. Scope the published selection\n // to this product so a swatch picked on another PDP does not leak in after client-side navigation.\n // The explicit selectedVariantId prop is the pre-selection fallback; the live selection wins.\n const publishedSelection = useReactiveVar(selectedVariantVar);\n const publishedVariantId = publishedVariantIdFor(publishedSelection, productSlice?.id ?? null);\n const activeVariantId = publishedVariantId ?? selectedVariantId;\n\n if (activeVariantId) {\n return (\n <Suspense fallback={null}>\n <HotDataProvider\n query={variantQuery}\n variables={{ id: activeVariantId }}\n field=\"node\"\n fallbackData={productSlice}\n >\n <PricingProvider fallbackProductSlice={productSlice} currency={currency} locale={locale} {...props}>\n {children}\n </PricingProvider>\n </HotDataProvider>\n </Suspense>\n );\n }\n\n const transformed = productSlice ? transformPricingData(productSlice) : null;\n\n return (\n <PricingView transformed={transformed} currency={currency} locale={locale} {...props}>\n {children}\n </PricingView>\n );\n}\n\n/**\n * What `PricingRoot` hands its inner views: the container props plus the locale and currency it read\n * from the storefront context. They are internal parameters, not a public prop — `PricingRootProps`\n * no longer carries either.\n */\ntype PricingViewBaseProps = ComponentPropsWithRef<'div'> & {\n currency?: string;\n locale?: string;\n};\n\ntype PricingProviderProps = PricingViewBaseProps & {\n fallbackProductSlice: RawPricingData | null;\n};\n\n// Reads the override written by the nested HotDataProvider: a Variant node when the variant fetch\n// succeeds, or the product slice (fallbackData) on error/null. Dispatch on __typename and always\n// source the product path from the explicit fallback prop so a mis-passed Product node id can never\n// crash the variant transform.\nfunction PricingProvider({ fallbackProductSlice, ...viewProps }: PricingProviderProps) {\n const override = useDataOverride<unknown>(null);\n const overrideTypename = (override as { __typename?: string } | null)?.__typename;\n\n let transformed: NormalizedPricingOffer | null = null;\n if (overrideTypename === 'Variant') {\n transformed = transformVariantPricingData(override as VariantSlice);\n } else if (fallbackProductSlice) {\n transformed = transformPricingData(fallbackProductSlice);\n }\n\n return <PricingView transformed={transformed} {...viewProps} />;\n}\n\ntype PricingViewProps = PricingViewBaseProps & {\n transformed: NormalizedPricingOffer | null;\n};\n\nfunction PricingView({\n transformed,\n currency: currencyProp,\n locale: localeProp,\n className,\n children,\n ...props\n}: PricingViewProps) {\n let contextValue: PricingContextValue = null;\n\n if (transformed) {\n const { price, listPrice, spotPrice, installmentPlans, discountHighlights, promotions } = transformed;\n // `PricingRoot` always hands these down from the context; the offer's own currency is the same\n // channel's by construction, so it is a fallback only for a directly-rendered view.\n const currency = currencyProp ?? transformed.currency;\n // `PricingRoot` always supplies it from the context; a directly-rendered view falls back to the\n // platform default rather than a Brazilian one.\n const locale = localeProp;\n const hasDiscount = listPrice > price;\n const hasSpotDiscount = spotPrice < price;\n const discountPercentage = hasDiscount ? Math.round(((listPrice - price) / listPrice) * 100) : 0;\n const spotDiscountPercentage = hasSpotDiscount ? Math.round(((price - spotPrice) / price) * 100) : 0;\n const bestInstallment = findBestInstallment(installmentPlans);\n\n contextValue = {\n price,\n listPrice,\n spotPrice,\n currency,\n locale,\n installmentPlans,\n discountHighlights,\n promotions,\n hasDiscount,\n hasSpotDiscount,\n discountPercentage,\n spotDiscountPercentage,\n bestInstallment,\n };\n }\n\n return (\n <PricingContext value={contextValue}>\n <div {...props} className={className} data-fs-pricing=\"\">\n {children}\n </div>\n </PricingContext>\n );\n}\n\nexport function PricingSellingPrice({ className, children, ...props }: PricingSellingPriceProps) {\n const ctx = usePricing();\n if (!ctx) return null;\n\n const formatted = formatPrice(ctx.price, ctx.locale, ctx.currency);\n\n return (\n <span {...props} className={className} data-fs-pricing-selling-price=\"\">\n {children ?? formatted}\n </span>\n );\n}\n\nexport function PricingListPrice({ className, children, ...props }: PricingListPriceProps) {\n const ctx = usePricing();\n if (!ctx || !ctx.hasDiscount) return null;\n\n const formatted = formatPrice(ctx.listPrice, ctx.locale, ctx.currency);\n\n return (\n <span {...props} className={className} data-fs-pricing-list-price=\"\">\n {children ?? formatted}\n </span>\n );\n}\n\nexport function PricingSpotPrice({ className, children, ...props }: PricingSpotPriceProps) {\n const ctx = usePricing();\n if (!ctx || !ctx.hasSpotDiscount) return null;\n\n const formatted = formatPrice(ctx.spotPrice, ctx.locale, ctx.currency);\n\n return (\n <span {...props} className={className} data-fs-pricing-spot-price=\"\">\n {children ?? formatted}\n </span>\n );\n}\n\nexport function PricingInstallments({ className, children, ...props }: PricingInstallmentsProps) {\n const ctx = usePricing();\n if (!ctx || !ctx.bestInstallment) return null;\n\n return (\n <InstallmentItemContext value={ctx.bestInstallment}>\n <div {...props} className={className} data-fs-pricing-installments=\"\">\n {children}\n </div>\n </InstallmentItemContext>\n );\n}\n\nexport function PricingInstallmentPlans({ className, children, ...props }: PricingInstallmentPlansProps) {\n const ctx = usePricing();\n if (!ctx || ctx.installmentPlans.length === 0) return null;\n\n const sortedPlans = ctx.installmentPlans\n .map((plan) => ({ plan, bestInstallment: findBestInstallment([plan]) }))\n .sort((a, b) => {\n const aCount = a.bestInstallment?.count ?? Number.POSITIVE_INFINITY;\n const bCount = b.bestInstallment?.count ?? Number.POSITIVE_INFINITY;\n return aCount - bCount;\n });\n\n return (\n <div {...props} className={className} data-fs-pricing-installment-plans=\"\">\n {sortedPlans.map(({ plan, bestInstallment }, index) => (\n <InstallmentPlanItemContext\n key={`${plan.paymentType}-${plan.paymentMethod}-${index}`}\n value={{\n paymentMethod: plan.paymentMethod,\n paymentType: plan.paymentType,\n installments: plan.installments,\n bestInstallment,\n }}\n >\n {children}\n </InstallmentPlanItemContext>\n ))}\n </div>\n );\n}\n\nexport function PricingInstallmentPlan({ className, children, ...props }: PricingInstallmentPlanProps) {\n const plan = useInstallmentPlanItem();\n if (!plan.bestInstallment) return null;\n\n return (\n <InstallmentItemContext value={plan.bestInstallment}>\n <div\n {...props}\n className={className}\n data-fs-pricing-installment-plan=\"\"\n data-fs-pricing-installment-plan-type={plan.paymentType}\n >\n {children}\n </div>\n </InstallmentItemContext>\n );\n}\n\nexport function PricingInstallmentsForPlan({ className, children, ...props }: PricingInstallmentsForPlanProps) {\n const plan = useInstallmentPlanItem('PricingInstallmentsForPlan', 'PricingInstallmentPlan');\n if (plan.installments.length === 0) return null;\n\n return (\n <div {...props} className={className} data-fs-pricing-installments-for-plan=\"\">\n {plan.installments.map((installment, index) => (\n <InstallmentItemContext key={`${installment.count}-${index}`} value={installment}>\n {children}\n </InstallmentItemContext>\n ))}\n </div>\n );\n}\n\nexport function PricingPaymentMethodsTrigger({ className, children, ...props }: PricingPaymentMethodsTriggerProps) {\n return (\n <PopoverTrigger {...props} className={className} data-fs-pricing-payment-methods-trigger=\"\">\n {children}\n </PopoverTrigger>\n );\n}\n\nexport function PricingPaymentMethodsList({ className, children, ...props }: PricingPaymentMethodsListProps) {\n const ctx = usePricing();\n if (!ctx || ctx.installmentPlans.length === 0) return null;\n\n return (\n <div {...props} className={className} data-fs-pricing-payment-methods-list=\"\">\n <PricingInstallmentPlans>{children}</PricingInstallmentPlans>\n </div>\n );\n}\n\nfunction sortPlansForTabs(plans: InstallmentPlanData[]) {\n return plans\n .map((plan) => ({\n plan,\n bestInstallment: findBestInstallment([plan]),\n tabValue: `${plan.paymentType}-${plan.paymentMethod}`,\n }))\n .sort((a, b) => {\n const aCount = a.bestInstallment?.count ?? Number.POSITIVE_INFINITY;\n const bCount = b.bestInstallment?.count ?? Number.POSITIVE_INFINITY;\n return aCount - bCount;\n });\n}\n\nexport function PricingPaymentMethodsTabList({ className, children, ...props }: PricingPaymentMethodsTabListProps) {\n const ctx = usePricing();\n if (!ctx || ctx.installmentPlans.length === 0) return null;\n\n return (\n <div {...props} className={className} data-fs-pricing-payment-methods-tab-list=\"\">\n {sortPlansForTabs(ctx.installmentPlans).map(({ plan, bestInstallment, tabValue }) => (\n <InstallmentPlanItemContext\n key={tabValue}\n value={{\n paymentMethod: plan.paymentMethod,\n paymentType: plan.paymentType,\n installments: plan.installments,\n bestInstallment,\n }}\n >\n <TabsTab value={tabValue}>{children}</TabsTab>\n </InstallmentPlanItemContext>\n ))}\n </div>\n );\n}\n\nexport function PricingPaymentMethodsTabPanels({ className, children, ...props }: PricingPaymentMethodsTabPanelsProps) {\n const ctx = usePricing();\n if (!ctx || ctx.installmentPlans.length === 0) return null;\n\n return (\n <div {...props} className={className} data-fs-pricing-payment-methods-tab-panels=\"\">\n {sortPlansForTabs(ctx.installmentPlans).map(({ plan, bestInstallment, tabValue }) => (\n <InstallmentPlanItemContext\n key={tabValue}\n value={{\n paymentMethod: plan.paymentMethod,\n paymentType: plan.paymentType,\n installments: plan.installments,\n bestInstallment,\n }}\n >\n <TabsPanel value={tabValue}>{children}</TabsPanel>\n </InstallmentPlanItemContext>\n ))}\n </div>\n );\n}\n\nexport function PricingPaymentMethodName({ className, children, ...props }: PricingPaymentMethodNameProps) {\n const plan = useInstallmentPlanItem();\n\n return (\n <span {...props} className={className} data-fs-pricing-payment-method-name=\"\">\n {children ?? plan.paymentMethod}\n </span>\n );\n}\n\nexport function PricingInstallment({\n template = '{count}x de {value}',\n interestFreeLabel = 'sem juros',\n className,\n children,\n ...props\n}: PricingInstallmentProps) {\n const installment = useInstallmentItem();\n const ctx = usePricing();\n if (!ctx) return null;\n\n const formattedValue = formatPrice(installment.value, ctx.locale, ctx.currency);\n const base = template.replace('{count}', String(installment.count)).replace('{value}', formattedValue);\n const text = installment.interestFree && interestFreeLabel ? `${base} ${interestFreeLabel}` : base;\n\n return (\n <span {...props} className={className} data-fs-pricing-installment=\"\">\n {children ?? text}\n </span>\n );\n}\n\nexport function PricingDiscount({\n template,\n format = 'percentage',\n className,\n children,\n ...props\n}: PricingDiscountProps) {\n const ctx = usePricing();\n if (!ctx || !ctx.hasDiscount) return null;\n\n const amount = ctx.listPrice - ctx.price;\n const formattedAmount = formatPrice(amount, ctx.locale, ctx.currency);\n const resolvedTemplate = template ?? (format === 'absolute' ? '-{amount}' : '-{percentage}%');\n const text = resolvedTemplate\n .replaceAll('{percentage}', String(ctx.discountPercentage))\n .replaceAll('{amount}', formattedAmount);\n\n return (\n <span {...props} className={className} data-fs-pricing-discount=\"\">\n {children ?? text}\n </span>\n );\n}\n\nexport function PricingSpotDiscount({\n template = '-{percentage}%',\n className,\n children,\n ...props\n}: PricingSpotDiscountProps) {\n const ctx = usePricing();\n if (!ctx || ctx.spotDiscountPercentage <= 0) return null;\n\n const text = template.replace('{percentage}', String(ctx.spotDiscountPercentage));\n\n return (\n <span {...props} className={className} data-fs-pricing-spot-discount=\"\">\n {children ?? text}\n </span>\n );\n}\n\nexport function PricingHighlights({ className, children, ...props }: PricingHighlightsProps) {\n const ctx = usePricing();\n if (!ctx || ctx.discountHighlights.length === 0) return null;\n\n return (\n <div {...props} className={className} data-fs-pricing-highlights=\"\">\n {ctx.discountHighlights.map((highlight, index) => (\n <HighlightItemContext key={`${highlight}-${index}`} value={highlight}>\n {children}\n </HighlightItemContext>\n ))}\n </div>\n );\n}\n\nexport function PricingHighlight({ className, children, ...props }: PricingHighlightProps) {\n const highlight = useHighlightItem();\n\n return (\n <span {...props} className={className} data-fs-pricing-highlight=\"\">\n {children ?? highlight}\n </span>\n );\n}\n\nexport function PricingPromotions({ className, children, ...props }: PricingPromotionsProps) {\n const ctx = usePricing();\n if (!ctx || ctx.promotions.length === 0) return null;\n\n return (\n <div {...props} className={className} data-fs-pricing-promotions=\"\">\n {ctx.promotions.map((promotion, index) => (\n <PromotionItemContext key={`${promotion.name}-${index}`} value={promotion}>\n {children}\n </PromotionItemContext>\n ))}\n </div>\n );\n}\n\nexport function PricingPromotion({ template = '{name}', className, children, ...props }: PricingPromotionProps) {\n const promotion = usePromotionItem();\n const text = template.replace('{name}', promotion.name);\n\n return (\n <span {...props} className={className} data-fs-pricing-promotion=\"\">\n {children ?? text}\n </span>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Skeleton\n// ---------------------------------------------------------------------------\n\nexport function PricingSkeleton({ className, ...props }: ComponentPropsWithRef<'div'>) {\n return (\n <div {...props} className={className} data-fs-pricing-skeleton=\"\" aria-hidden=\"true\">\n <span data-fs-pricing-skeleton-line=\"\" />\n <span data-fs-pricing-skeleton-line=\"\" />\n </div>\n );\n}\n\nPricingRoot.Skeleton = PricingSkeleton;\n\n// ---------------------------------------------------------------------------\n// Namespace export\n// ---------------------------------------------------------------------------\n\nexport const Pricing = {\n Root: PricingRoot,\n SellingPrice: PricingSellingPrice,\n ListPrice: PricingListPrice,\n SpotPrice: PricingSpotPrice,\n Installments: PricingInstallments,\n InstallmentPlans: PricingInstallmentPlans,\n InstallmentPlan: PricingInstallmentPlan,\n InstallmentsForPlan: PricingInstallmentsForPlan,\n Installment: PricingInstallment,\n PaymentMethodsTrigger: PricingPaymentMethodsTrigger,\n PaymentMethodsList: PricingPaymentMethodsList,\n PaymentMethodsTabList: PricingPaymentMethodsTabList,\n PaymentMethodsTabPanels: PricingPaymentMethodsTabPanels,\n PaymentMethodName: PricingPaymentMethodName,\n Discount: PricingDiscount,\n SpotDiscount: PricingSpotDiscount,\n Highlights: PricingHighlights,\n Highlight: PricingHighlight,\n Promotions: PricingPromotions,\n Promotion: PricingPromotion,\n Skeleton: PricingSkeleton,\n};\n"],"mappings":"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"}