@vtex/faststore 0.0.10 → 0.0.11

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 (506) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/README.md +0 -1
  3. package/dist/actions.json +6 -1
  4. package/dist/catalog.json +789 -1701
  5. package/dist/cli/index.d.ts +66 -28
  6. package/dist/cli/index.js +7371 -512
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/cli/server-runtime.js +41 -60
  9. package/dist/cli/server-runtime.js.map +1 -1
  10. package/dist/client.d.ts +3 -3
  11. package/dist/client.js +2 -2
  12. package/dist/components.d.ts +63 -57
  13. package/dist/components.js +60 -54
  14. package/dist/content-types.json +5785 -754
  15. package/dist/core/dist/define-component.d.ts +1 -1
  16. package/dist/core/dist/define-content-type.d.ts +50 -2
  17. package/dist/core/dist/define-content-type.js +107 -3
  18. package/dist/core/dist/define-content-type.js.map +1 -1
  19. package/dist/core/dist/index.d.ts +2 -2
  20. package/dist/docs/access-code-field.md +1 -1
  21. package/dist/docs/access-code-sign-in.md +126 -77
  22. package/dist/docs/account-address-book.md +210 -95
  23. package/dist/docs/account-menu.md +14 -15
  24. package/dist/docs/account-saved-cards.md +44 -39
  25. package/dist/docs/alert-dialog.md +3 -1
  26. package/dist/docs/avatar.md +4 -2
  27. package/dist/docs/billing-address.md +99 -30
  28. package/dist/docs/binding-switcher.md +5 -2
  29. package/dist/docs/buy-button.md +7 -8
  30. package/dist/docs/card-entry.md +39 -26
  31. package/dist/docs/card-summary.md +18 -8
  32. package/dist/docs/cardholder-document.md +5 -3
  33. package/dist/docs/carousel.md +5 -4
  34. package/dist/docs/cart-destination.md +39 -26
  35. package/dist/docs/cart-item.md +29 -14
  36. package/dist/docs/cart-totalizer.md +7 -5
  37. package/dist/docs/cart.md +135 -41
  38. package/dist/docs/challenge-return.md +135 -0
  39. package/dist/docs/client-preferences-fieldset.md +10 -5
  40. package/dist/docs/client-preferences.md +31 -8
  41. package/dist/docs/client-profile-fieldset.md +20 -6
  42. package/dist/docs/client-profile.md +12 -3
  43. package/dist/docs/copy-text.md +9 -7
  44. package/dist/docs/document-field.md +1 -1
  45. package/dist/docs/email-field.md +2 -1
  46. package/dist/docs/email-identification.md +12 -2
  47. package/dist/docs/footer-copyright.md +4 -2
  48. package/dist/docs/form.md +54 -18
  49. package/dist/docs/free-shipping-progress.md +6 -5
  50. package/dist/docs/identity-edit.md +8 -2
  51. package/dist/docs/identity-summary.md +18 -5
  52. package/dist/docs/installments.md +46 -32
  53. package/dist/docs/my-account-profile.md +16 -11
  54. package/dist/docs/navigation-link.md +5 -3
  55. package/dist/docs/order-cancel.md +3 -1
  56. package/dist/docs/order-delivery-address.md +7 -5
  57. package/dist/docs/order-delivery-group.md +1 -3
  58. package/dist/docs/order-details-back.md +1 -1
  59. package/dist/docs/order-details-header.md +1 -4
  60. package/dist/docs/order-invoice-download.md +60 -0
  61. package/dist/docs/order-list-row.md +1 -1
  62. package/dist/docs/order-list-search.md +13 -20
  63. package/dist/docs/order-list-views.md +11 -17
  64. package/dist/docs/order-list.md +12 -5
  65. package/dist/docs/order-payment.md +9 -7
  66. package/dist/docs/order-placed-date.md +1 -1
  67. package/dist/docs/order-placed-payment-summary.md +28 -15
  68. package/dist/docs/order-placed.md +49 -14
  69. package/dist/docs/order-progress.md +1 -1
  70. package/dist/docs/order-status-badge.md +20 -9
  71. package/dist/docs/order-summary.md +2 -2
  72. package/dist/docs/order-tracking-link.md +58 -0
  73. package/dist/docs/payment-method-badges.md +30 -4
  74. package/dist/docs/payment-methods.md +1 -1
  75. package/dist/docs/payment.md +36 -17
  76. package/dist/docs/phone-field.md +4 -4
  77. package/dist/docs/place-order.md +84 -36
  78. package/dist/docs/postal-code-field.md +3 -1
  79. package/dist/docs/pricing.md +21 -23
  80. package/dist/docs/product-gallery.md +19 -20
  81. package/dist/docs/product-information.md +13 -9
  82. package/dist/docs/product-list.md +7 -6
  83. package/dist/docs/product-shelf.md +0 -1
  84. package/dist/docs/promotion.md +4 -2
  85. package/dist/docs/region.md +23 -15
  86. package/dist/docs/save-card.md +7 -6
  87. package/dist/docs/saved-cards.md +65 -36
  88. package/dist/docs/shipping-address.md +57 -21
  89. package/dist/docs/shipping-simulator.md +53 -15
  90. package/dist/docs/sign-in-disclosure.md +176 -0
  91. package/dist/docs/sign-in-form.md +78 -47
  92. package/dist/docs/sign-in-redirect.md +4 -2
  93. package/dist/docs/sign-in.md +173 -0
  94. package/dist/docs/toast.md +15 -4
  95. package/dist/docs/variant-selector.md +15 -11
  96. package/dist/graphql/types.d.ts +4 -14
  97. package/dist/index.d.ts +2 -2
  98. package/dist/internal/client.d.ts +1 -3
  99. package/dist/internal/client.js +1 -1
  100. package/dist/internal/server.d.ts +7 -4
  101. package/dist/internal/server.js +7 -4
  102. package/dist/matter/access-code-sign-in/access-code-sign-in.d.ts +250 -66
  103. package/dist/matter/access-code-sign-in/access-code-sign-in.js +459 -188
  104. package/dist/matter/access-code-sign-in/access-code-sign-in.js.map +1 -1
  105. package/dist/matter/account-address-book/account-address-book-delete.d.ts +78 -40
  106. package/dist/matter/account-address-book/account-address-book-delete.js +86 -50
  107. package/dist/matter/account-address-book/account-address-book-delete.js.map +1 -1
  108. package/dist/matter/account-address-book/account-address-book-deliverability.d.ts +21 -4
  109. package/dist/matter/account-address-book/account-address-book-deliverability.js +45 -17
  110. package/dist/matter/account-address-book/account-address-book-deliverability.js.map +1 -1
  111. package/dist/matter/account-address-book/account-address-book-form-parts.d.ts +74 -19
  112. package/dist/matter/account-address-book/account-address-book-form-parts.js +77 -26
  113. package/dist/matter/account-address-book/account-address-book-form-parts.js.map +1 -1
  114. package/dist/matter/account-address-book/account-address-book-profile-notice.d.ts +27 -6
  115. package/dist/matter/account-address-book/account-address-book-profile-notice.js +55 -28
  116. package/dist/matter/account-address-book/account-address-book-profile-notice.js.map +1 -1
  117. package/dist/matter/account-address-book/account-address-book.d.ts +67 -14
  118. package/dist/matter/account-address-book/account-address-book.js +74 -33
  119. package/dist/matter/account-address-book/account-address-book.js.map +1 -1
  120. package/dist/matter/account-address-book/account-address-country-switch.js +3 -3
  121. package/dist/matter/account-address-book/account-address-country-switch.js.map +1 -1
  122. package/dist/matter/account-address-book/account-address-country.d.ts +66 -20
  123. package/dist/matter/account-address-book/account-address-country.js +83 -49
  124. package/dist/matter/account-address-book/account-address-country.js.map +1 -1
  125. package/dist/matter/account-address-book/account-address-form-context.d.ts +8 -4
  126. package/dist/matter/account-address-book/account-address-form-context.js.map +1 -1
  127. package/dist/matter/account-address-book/account-address-form.d.ts +468 -45
  128. package/dist/matter/account-address-book/account-address-form.js +518 -155
  129. package/dist/matter/account-address-book/account-address-form.js.map +1 -1
  130. package/dist/matter/account-address-book/account-address-record.d.ts +27 -6
  131. package/dist/matter/account-address-book/account-address-record.js +32 -17
  132. package/dist/matter/account-address-book/account-address-record.js.map +1 -1
  133. package/dist/matter/account-menu/account-menu.d.ts +34 -17
  134. package/dist/matter/account-menu/account-menu.js +46 -54
  135. package/dist/matter/account-menu/account-menu.js.map +1 -1
  136. package/dist/matter/account-menu-identity/account-menu-identity.js +1 -1
  137. package/dist/matter/account-saved-cards/account-saved-cards.d.ts +108 -28
  138. package/dist/matter/account-saved-cards/account-saved-cards.js +177 -122
  139. package/dist/matter/account-saved-cards/account-saved-cards.js.map +1 -1
  140. package/dist/matter/billing-address/billing-address.d.ts +156 -74
  141. package/dist/matter/billing-address/billing-address.js +227 -156
  142. package/dist/matter/billing-address/billing-address.js.map +1 -1
  143. package/dist/matter/breadcrumb/breadcrumb.d.ts +21 -3
  144. package/dist/matter/breadcrumb/breadcrumb.js +24 -9
  145. package/dist/matter/breadcrumb/breadcrumb.js.map +1 -1
  146. package/dist/matter/buy-button/buy-button.d.ts +8 -11
  147. package/dist/matter/buy-button/buy-button.js +10 -19
  148. package/dist/matter/buy-button/buy-button.js.map +1 -1
  149. package/dist/matter/card-entry/card-capture.js +12 -4
  150. package/dist/matter/card-entry/card-capture.js.map +1 -1
  151. package/dist/matter/card-entry/card-entry.d.ts +123 -32
  152. package/dist/matter/card-entry/card-entry.js +348 -221
  153. package/dist/matter/card-entry/card-entry.js.map +1 -1
  154. package/dist/matter/cart/cart-namespace.d.ts +7 -1
  155. package/dist/matter/cart/cart-namespace.js +7 -1
  156. package/dist/matter/cart/cart-namespace.js.map +1 -1
  157. package/dist/matter/cart/cart.d.ts +402 -61
  158. package/dist/matter/cart/cart.js +624 -153
  159. package/dist/matter/cart/cart.js.map +1 -1
  160. package/dist/matter/cart-destination/cart-destination.d.ts +30 -19
  161. package/dist/matter/cart-destination/cart-destination.js +160 -70
  162. package/dist/matter/cart-destination/cart-destination.js.map +1 -1
  163. package/dist/matter/cart-item/cart-item.d.ts +144 -17
  164. package/dist/matter/cart-item/cart-item.js +166 -49
  165. package/dist/matter/cart-item/cart-item.js.map +1 -1
  166. package/dist/matter/cart-item-compositions/cart-item-compositions.js +1 -1
  167. package/dist/matter/cart-item-compositions/cart-item-compositions.js.map +1 -1
  168. package/dist/matter/cart-item-customizations/cart-item-customizations.js +1 -1
  169. package/dist/matter/cart-item-customizations/cart-item-customizations.js.map +1 -1
  170. package/dist/matter/cart-item-discounts/cart-item-discounts.js +1 -1
  171. package/dist/matter/cart-item-discounts/cart-item-discounts.js.map +1 -1
  172. package/dist/matter/cart-item-seller-info/cart-item-seller-info.js +1 -1
  173. package/dist/matter/cart-item-seller-info/cart-item-seller-info.js.map +1 -1
  174. package/dist/matter/cart-item-variations/cart-item-variations.js +1 -1
  175. package/dist/matter/cart-item-variations/cart-item-variations.js.map +1 -1
  176. package/dist/matter/cart-totalizer/cart-totalizer.d.ts +43 -9
  177. package/dist/matter/cart-totalizer/cart-totalizer.js +46 -17
  178. package/dist/matter/cart-totalizer/cart-totalizer.js.map +1 -1
  179. package/dist/matter/challenge-return/challenge-return.d.ts +62 -0
  180. package/dist/matter/challenge-return/challenge-return.js +241 -0
  181. package/dist/matter/challenge-return/challenge-return.js.map +1 -0
  182. package/dist/matter/client-preferences/client-preferences-fieldset.d.ts +86 -17
  183. package/dist/matter/client-preferences/client-preferences-fieldset.js +126 -54
  184. package/dist/matter/client-preferences/client-preferences-fieldset.js.map +1 -1
  185. package/dist/matter/client-preferences/client-preferences.d.ts +50 -7
  186. package/dist/matter/client-preferences/client-preferences.js +84 -15
  187. package/dist/matter/client-preferences/client-preferences.js.map +1 -1
  188. package/dist/matter/client-profile/client-profile.d.ts +44 -9
  189. package/dist/matter/client-profile/client-profile.js +64 -24
  190. package/dist/matter/client-profile/client-profile.js.map +1 -1
  191. package/dist/matter/client-profile-form/client-profile-fieldset.d.ts +119 -22
  192. package/dist/matter/client-profile-form/client-profile-fieldset.js +161 -73
  193. package/dist/matter/client-profile-form/client-profile-fieldset.js.map +1 -1
  194. package/dist/matter/delivery-options/delivery-options-accordion.d.ts +49 -4
  195. package/dist/matter/delivery-options/delivery-options-accordion.js +67 -14
  196. package/dist/matter/delivery-options/delivery-options-accordion.js.map +1 -1
  197. package/dist/matter/delivery-options/delivery-options-controller.d.ts +69 -9
  198. package/dist/matter/delivery-options/delivery-options-controller.js +80 -14
  199. package/dist/matter/delivery-options/delivery-options-controller.js.map +1 -1
  200. package/dist/matter/delivery-options/delivery-options.d.ts +37 -2
  201. package/dist/matter/delivery-options/delivery-options.js +75 -12
  202. package/dist/matter/delivery-options/delivery-options.js.map +1 -1
  203. package/dist/matter/delivery-options/use-delivery-option-selection.d.ts +1 -0
  204. package/dist/matter/delivery-options/use-delivery-option-selection.js +1 -1
  205. package/dist/matter/delivery-options/use-delivery-option-selection.js.map +1 -1
  206. package/dist/matter/email-identification/email-identification.d.ts +25 -3
  207. package/dist/matter/email-identification/email-identification.js +49 -12
  208. package/dist/matter/email-identification/email-identification.js.map +1 -1
  209. package/dist/matter/free-shipping-progress/free-shipping-progress.d.ts +79 -7
  210. package/dist/matter/free-shipping-progress/free-shipping-progress.js +77 -20
  211. package/dist/matter/free-shipping-progress/free-shipping-progress.js.map +1 -1
  212. package/dist/matter/identity-edit/identity-edit.d.ts +52 -10
  213. package/dist/matter/identity-edit/identity-edit.js +47 -19
  214. package/dist/matter/identity-edit/identity-edit.js.map +1 -1
  215. package/dist/matter/identity-summary/identity-summary.d.ts +76 -22
  216. package/dist/matter/identity-summary/identity-summary.js +95 -45
  217. package/dist/matter/identity-summary/identity-summary.js.map +1 -1
  218. package/dist/matter/installments/installments-select.d.ts +98 -16
  219. package/dist/matter/installments/installments-select.js +156 -48
  220. package/dist/matter/installments/installments-select.js.map +1 -1
  221. package/dist/matter/installments/installments.d.ts +96 -16
  222. package/dist/matter/installments/installments.js +115 -40
  223. package/dist/matter/installments/installments.js.map +1 -1
  224. package/dist/matter/installments/use-installments-selection.d.ts +1 -0
  225. package/dist/matter/installments/use-installments-selection.js +8 -3
  226. package/dist/matter/installments/use-installments-selection.js.map +1 -1
  227. package/dist/matter/my-account-profile/my-account-profile.d.ts +358 -103
  228. package/dist/matter/my-account-profile/my-account-profile.js +370 -174
  229. package/dist/matter/my-account-profile/my-account-profile.js.map +1 -1
  230. package/dist/matter/order-cancel/order-cancel.d.ts +65 -19
  231. package/dist/matter/order-cancel/order-cancel.js +118 -51
  232. package/dist/matter/order-cancel/order-cancel.js.map +1 -1
  233. package/dist/matter/order-delivery-address/order-delivery-address.d.ts +8 -18
  234. package/dist/matter/order-delivery-address/order-delivery-address.js +14 -23
  235. package/dist/matter/order-delivery-address/order-delivery-address.js.map +1 -1
  236. package/dist/matter/order-delivery-group/order-delivery-group.d.ts +40 -24
  237. package/dist/matter/order-delivery-group/order-delivery-group.js +64 -74
  238. package/dist/matter/order-delivery-group/order-delivery-group.js.map +1 -1
  239. package/dist/matter/order-details-header/order-details-header.d.ts +32 -15
  240. package/dist/matter/order-details-header/order-details-header.js +66 -58
  241. package/dist/matter/order-details-header/order-details-header.js.map +1 -1
  242. package/dist/matter/order-invoice-download/order-invoice-download.d.ts +78 -0
  243. package/dist/matter/order-invoice-download/order-invoice-download.js +173 -0
  244. package/dist/matter/order-invoice-download/order-invoice-download.js.map +1 -0
  245. package/dist/matter/order-list/order-list.d.ts +164 -19
  246. package/dist/matter/order-list/order-list.js +229 -87
  247. package/dist/matter/order-list/order-list.js.map +1 -1
  248. package/dist/matter/order-list-row/order-list-row.d.ts +6 -1
  249. package/dist/matter/order-list-row/order-list-row.js +3 -2
  250. package/dist/matter/order-list-row/order-list-row.js.map +1 -1
  251. package/dist/matter/order-list-search/order-list-search.d.ts +18 -26
  252. package/dist/matter/order-list-search/order-list-search.js +30 -69
  253. package/dist/matter/order-list-search/order-list-search.js.map +1 -1
  254. package/dist/matter/order-list-views/order-list-views.d.ts +15 -22
  255. package/dist/matter/order-list-views/order-list-views.js +22 -68
  256. package/dist/matter/order-list-views/order-list-views.js.map +1 -1
  257. package/dist/matter/order-payment/order-payment.d.ts +33 -10
  258. package/dist/matter/order-payment/order-payment.js +44 -39
  259. package/dist/matter/order-payment/order-payment.js.map +1 -1
  260. package/dist/matter/order-placed/order-placed-deliveries.d.ts +144 -12
  261. package/dist/matter/order-placed/order-placed-deliveries.js +115 -40
  262. package/dist/matter/order-placed/order-placed-deliveries.js.map +1 -1
  263. package/dist/matter/order-placed/order-placed.d.ts +198 -31
  264. package/dist/matter/order-placed/order-placed.js +230 -139
  265. package/dist/matter/order-placed/order-placed.js.map +1 -1
  266. package/dist/matter/order-placed-date/order-placed-date.d.ts +5 -8
  267. package/dist/matter/order-placed-date/order-placed-date.js +7 -8
  268. package/dist/matter/order-placed-date/order-placed-date.js.map +1 -1
  269. package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.d.ts +90 -17
  270. package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js +93 -117
  271. package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js.map +1 -1
  272. package/dist/matter/order-progress/order-progress.d.ts +19 -8
  273. package/dist/matter/order-progress/order-progress.js +37 -45
  274. package/dist/matter/order-progress/order-progress.js.map +1 -1
  275. package/dist/matter/order-summary/order-summary.d.ts +19 -9
  276. package/dist/matter/order-summary/order-summary.js +38 -44
  277. package/dist/matter/order-summary/order-summary.js.map +1 -1
  278. package/dist/matter/order-tracking-link/order-tracking-link.d.ts +43 -0
  279. package/dist/matter/order-tracking-link/order-tracking-link.js +107 -0
  280. package/dist/matter/order-tracking-link/order-tracking-link.js.map +1 -0
  281. package/dist/matter/payment/payment-card-capture.js +17 -10
  282. package/dist/matter/payment/payment-card-capture.js.map +1 -1
  283. package/dist/matter/payment/payment-controller.d.ts +4 -2
  284. package/dist/matter/payment/payment-controller.js +30 -9
  285. package/dist/matter/payment/payment-controller.js.map +1 -1
  286. package/dist/matter/payment/payment-method-badges.js +1 -1
  287. package/dist/matter/payment/payment.d.ts +69 -19
  288. package/dist/matter/payment/payment.js +101 -35
  289. package/dist/matter/payment/payment.js.map +1 -1
  290. package/dist/matter/payment/use-payment-method-selection.d.ts +25 -4
  291. package/dist/matter/payment/use-payment-method-selection.js +94 -32
  292. package/dist/matter/payment/use-payment-method-selection.js.map +1 -1
  293. package/dist/matter/payment/use-payment-submit-gate.d.ts +14 -3
  294. package/dist/matter/payment/use-payment-submit-gate.js +47 -8
  295. package/dist/matter/payment/use-payment-submit-gate.js.map +1 -1
  296. package/dist/matter/place-order/place-order.d.ts +171 -57
  297. package/dist/matter/place-order/place-order.js +376 -185
  298. package/dist/matter/place-order/place-order.js.map +1 -1
  299. package/dist/matter/pricing/pricing.d.ts +152 -13
  300. package/dist/matter/pricing/pricing.js +153 -52
  301. package/dist/matter/pricing/pricing.js.map +1 -1
  302. package/dist/matter/product-information/product-information.d.ts +27 -4
  303. package/dist/matter/product-information/product-information.js +32 -15
  304. package/dist/matter/product-information/product-information.js.map +1 -1
  305. package/dist/matter/product-list/product-list.d.ts +24 -6
  306. package/dist/matter/product-list/product-list.js +32 -26
  307. package/dist/matter/product-list/product-list.js.map +1 -1
  308. package/dist/matter/product-shelf/product-shelf.d.ts +1 -3
  309. package/dist/matter/product-shelf/product-shelf.js +2 -15
  310. package/dist/matter/product-shelf/product-shelf.js.map +1 -1
  311. package/dist/matter/region/region.d.ts +33 -16
  312. package/dist/matter/region/region.js +59 -52
  313. package/dist/matter/region/region.js.map +1 -1
  314. package/dist/matter/save-card/save-card.d.ts +43 -8
  315. package/dist/matter/save-card/save-card.js +61 -23
  316. package/dist/matter/save-card/save-card.js.map +1 -1
  317. package/dist/matter/saved-cards/saved-cards.d.ts +113 -21
  318. package/dist/matter/saved-cards/saved-cards.js +349 -77
  319. package/dist/matter/saved-cards/saved-cards.js.map +1 -1
  320. package/dist/matter/shipping-address/address-payload.js +25 -0
  321. package/dist/matter/shipping-address/address-payload.js.map +1 -0
  322. package/dist/matter/shipping-address/country-descriptors.js +71 -71
  323. package/dist/matter/shipping-address/country-descriptors.js.map +1 -1
  324. package/dist/matter/shipping-address/library-country-descriptors.js +136 -0
  325. package/dist/matter/shipping-address/library-country-descriptors.js.map +1 -0
  326. package/dist/matter/shipping-address/shipping-address.d.ts +312 -45
  327. package/dist/matter/shipping-address/shipping-address.js +443 -188
  328. package/dist/matter/shipping-address/shipping-address.js.map +1 -1
  329. package/dist/matter/shipping-simulator/shipping-simulator.d.ts +250 -24
  330. package/dist/matter/shipping-simulator/shipping-simulator.js +257 -51
  331. package/dist/matter/shipping-simulator/shipping-simulator.js.map +1 -1
  332. package/dist/matter/sign-in/sign-in.d.ts +108 -0
  333. package/dist/matter/sign-in/sign-in.js +285 -0
  334. package/dist/matter/sign-in/sign-in.js.map +1 -0
  335. package/dist/matter/sign-in-disclosure/sign-in-disclosure.d.ts +81 -0
  336. package/dist/matter/sign-in-disclosure/sign-in-disclosure.js +232 -0
  337. package/dist/matter/sign-in-disclosure/sign-in-disclosure.js.map +1 -0
  338. package/dist/matter/sign-in-form/sign-in-form.d.ts +93 -62
  339. package/dist/matter/sign-in-form/sign-in-form.js +134 -144
  340. package/dist/matter/sign-in-form/sign-in-form.js.map +1 -1
  341. package/dist/particles/binding-switcher/binding-switcher.d.ts +29 -8
  342. package/dist/particles/binding-switcher/binding-switcher.js +37 -26
  343. package/dist/particles/binding-switcher/binding-switcher.js.map +1 -1
  344. package/dist/particles/card-summary/card-summary.d.ts +38 -8
  345. package/dist/particles/card-summary/card-summary.js +55 -22
  346. package/dist/particles/card-summary/card-summary.js.map +1 -1
  347. package/dist/particles/carousel/carousel.d.ts +99 -11
  348. package/dist/particles/carousel/carousel.js +103 -35
  349. package/dist/particles/carousel/carousel.js.map +1 -1
  350. package/dist/particles/copy-text/copy-text.js +5 -15
  351. package/dist/particles/copy-text/copy-text.js.map +1 -1
  352. package/dist/particles/dialog/dialog.d.ts +14 -6
  353. package/dist/particles/dialog/dialog.js +6 -3
  354. package/dist/particles/dialog/dialog.js.map +1 -1
  355. package/dist/particles/drawer/drawer.js +1 -1
  356. package/dist/particles/drawer/drawer.js.map +1 -1
  357. package/dist/particles/email-field/email-field.d.ts +2 -1
  358. package/dist/particles/email-field/email-field.js +2 -1
  359. package/dist/particles/email-field/email-field.js.map +1 -1
  360. package/dist/particles/footer-link-group/footer-link-group.js +1 -0
  361. package/dist/particles/footer-link-group/footer-link-group.js.map +1 -1
  362. package/dist/particles/form/form.d.ts +85 -13
  363. package/dist/particles/form/form.js +91 -42
  364. package/dist/particles/form/form.js.map +1 -1
  365. package/dist/particles/gallery/gallery.d.ts +129 -12
  366. package/dist/particles/gallery/gallery.js +121 -34
  367. package/dist/particles/gallery/gallery.js.map +1 -1
  368. package/dist/particles/order-details-back/order-details-back.d.ts +5 -3
  369. package/dist/particles/order-details-back/order-details-back.js +8 -10
  370. package/dist/particles/order-details-back/order-details-back.js.map +1 -1
  371. package/dist/particles/order-status-badge/order-status-badge.d.ts +3 -3
  372. package/dist/particles/order-status-badge/order-status-badge.js +4 -20
  373. package/dist/particles/order-status-badge/order-status-badge.js.map +1 -1
  374. package/dist/particles/password-field/password-field.d.ts +1 -1
  375. package/dist/particles/password-field/password-field.js +2 -4
  376. package/dist/particles/password-field/password-field.js.map +1 -1
  377. package/dist/particles/phone-field/phone-field.d.ts +4 -4
  378. package/dist/particles/phone-field/phone-field.js +8 -11
  379. package/dist/particles/phone-field/phone-field.js.map +1 -1
  380. package/dist/particles/spinner/spinner.d.ts +24 -4
  381. package/dist/particles/spinner/spinner.js +25 -9
  382. package/dist/particles/spinner/spinner.js.map +1 -1
  383. package/dist/particles/switch/switch.d.ts +4 -1
  384. package/dist/particles/switch/switch.js +3 -1
  385. package/dist/particles/switch/switch.js.map +1 -1
  386. package/dist/particles/toast/toast.d.ts +29 -3
  387. package/dist/particles/toast/toast.js +34 -10
  388. package/dist/particles/toast/toast.js.map +1 -1
  389. package/dist/schema.graphql +164 -56
  390. package/dist/sdk/address/address-fields.js +4 -4
  391. package/dist/sdk/address/address-fields.js.map +1 -1
  392. package/dist/sdk/address/constants.js +1 -6
  393. package/dist/sdk/address/constants.js.map +1 -1
  394. package/dist/sdk/address/messages.js +44 -44
  395. package/dist/sdk/address/messages.js.map +1 -1
  396. package/dist/sdk/address/postal-code.js +15 -2
  397. package/dist/sdk/address/postal-code.js.map +1 -1
  398. package/dist/sdk/address/types.d.ts +5 -3
  399. package/dist/sdk/address/validate-address.js +3 -3
  400. package/dist/sdk/address/validate-address.js.map +1 -1
  401. package/dist/sdk/analytics/use-analytics-actions.d.ts +1 -1
  402. package/dist/sdk/analytics/use-analytics-actions.js.map +1 -1
  403. package/dist/sdk/cart/use-cart-actions.js.map +1 -1
  404. package/dist/sdk/data/index.js +2 -2
  405. package/dist/sdk/data/reactive-list-item-data-provider.js +2 -2
  406. package/dist/sdk/generated/gql.js +1 -1
  407. package/dist/sdk/generated/gql.js.map +1 -1
  408. package/dist/sdk/generated/graphql.d.ts +20 -5
  409. package/dist/sdk/generated/graphql.js +6 -0
  410. package/dist/sdk/generated/graphql.js.map +1 -1
  411. package/dist/sdk/i18n/format-error-code.js +23 -0
  412. package/dist/sdk/i18n/format-error-code.js.map +1 -0
  413. package/dist/sdk/i18n/message-formatter.d.ts +22 -0
  414. package/dist/sdk/i18n/message-formatter.js +140 -0
  415. package/dist/sdk/i18n/message-formatter.js.map +1 -0
  416. package/dist/sdk/i18n/use-message-formatter.d.ts +8 -0
  417. package/dist/sdk/i18n/use-message-formatter.js +18 -0
  418. package/dist/sdk/i18n/use-message-formatter.js.map +1 -0
  419. package/dist/sdk/identity/use-identity-actions.js.map +1 -1
  420. package/dist/sdk/navigation/redirect.d.ts +2 -0
  421. package/dist/sdk/navigation/redirect.js +19 -1
  422. package/dist/sdk/navigation/redirect.js.map +1 -1
  423. package/dist/sdk/navigation/types.d.ts +13 -0
  424. package/dist/sdk/payment/bin-format.js +20 -0
  425. package/dist/sdk/payment/bin-format.js.map +1 -0
  426. package/dist/sdk/payment/challenge-return.js +37 -0
  427. package/dist/sdk/payment/challenge-return.js.map +1 -0
  428. package/dist/sdk/payment/confirmation-last-four.js +39 -0
  429. package/dist/sdk/payment/confirmation-last-four.js.map +1 -0
  430. package/dist/sdk/payment/gateway.d.ts +1 -1
  431. package/dist/sdk/payment/gateway.js +8 -2
  432. package/dist/sdk/payment/gateway.js.map +1 -1
  433. package/dist/sdk/payment/operations.d.ts +1 -0
  434. package/dist/sdk/payment/operations.js +28 -6
  435. package/dist/sdk/payment/operations.js.map +1 -1
  436. package/dist/sdk/payment/resumed-purchase.d.ts +1 -0
  437. package/dist/sdk/payment/resumed-purchase.js +119 -0
  438. package/dist/sdk/payment/resumed-purchase.js.map +1 -0
  439. package/dist/sdk/payment/security-code-mask.js +16 -23
  440. package/dist/sdk/payment/security-code-mask.js.map +1 -1
  441. package/dist/sdk/payment/submission-registry.js +6 -2
  442. package/dist/sdk/payment/submission-registry.js.map +1 -1
  443. package/dist/sdk/payment/use-payment-actions.d.ts +18 -3
  444. package/dist/sdk/payment/use-payment-actions.js +23 -3
  445. package/dist/sdk/payment/use-payment-actions.js.map +1 -1
  446. package/dist/sdk/payment/use-place-order.d.ts +10 -2
  447. package/dist/sdk/payment/use-place-order.js +138 -76
  448. package/dist/sdk/payment/use-place-order.js.map +1 -1
  449. package/dist/sdk/provider/storefront-provider.d.ts +1 -7
  450. package/dist/sdk/provider/storefront-provider.js +4 -11
  451. package/dist/sdk/provider/storefront-provider.js.map +1 -1
  452. package/dist/sdk/seo/entity-landing.d.ts +24 -0
  453. package/dist/sdk/seo/entity-landing.js +30 -0
  454. package/dist/sdk/seo/entity-landing.js.map +1 -0
  455. package/dist/sdk/seo/page-alternates.d.ts +3 -2
  456. package/dist/sdk/seo/page-alternates.js +4 -2
  457. package/dist/sdk/seo/page-alternates.js.map +1 -1
  458. package/dist/sdk/seo/search-landing.d.ts +42 -0
  459. package/dist/sdk/seo/search-landing.js +85 -0
  460. package/dist/sdk/seo/search-landing.js.map +1 -0
  461. package/dist/sdk/session/mock-session.d.ts +9 -0
  462. package/dist/sdk/session/mock-session.js +31 -0
  463. package/dist/sdk/session/mock-session.js.map +1 -0
  464. package/dist/sdk/session/read-server-session.d.ts +3 -0
  465. package/dist/sdk/session/read-server-session.js +5 -0
  466. package/dist/sdk/session/read-server-session.js.map +1 -1
  467. package/dist/sdk/session/return-path-segment.d.ts +10 -0
  468. package/dist/sdk/session/return-path-segment.js +15 -0
  469. package/dist/sdk/session/return-path-segment.js.map +1 -0
  470. package/dist/sdk/session/use-session-actions.js.map +1 -1
  471. package/dist/sdk/shipping/use-cart-shipping-simulation.js.map +1 -1
  472. package/dist/sdk/shipping/use-shipping-actions.js.map +1 -1
  473. package/dist/sdk/shipping/use-shipping-simulation.js.map +1 -1
  474. package/dist/utils/safe-href.d.ts +2 -0
  475. package/package.json +4 -3
  476. package/skills/storefront-asset/SKILL.md +2 -2
  477. package/skills/storefront-asset/references/api-side.md +27 -14
  478. package/skills/storefront-asset/references/findings.md +5 -2
  479. package/src/styles/tailwind.css +8 -0
  480. package/dist/matter/shipping-address/country-descriptors.d.ts +0 -1
  481. package/dist/message-locales.json +0 -7
  482. package/dist/sdk/i18n/client.d.ts +0 -4
  483. package/dist/sdk/i18n/client.js +0 -4
  484. package/dist/sdk/i18n/locales.d.ts +0 -8
  485. package/dist/sdk/i18n/locales.js +0 -57
  486. package/dist/sdk/i18n/locales.js.map +0 -1
  487. package/dist/sdk/i18n/messages/en-US.js +0 -183
  488. package/dist/sdk/i18n/messages/en-US.js.map +0 -1
  489. package/dist/sdk/i18n/messages/en-US.json +0 -178
  490. package/dist/sdk/i18n/messages/en-US.json.d.ts +0 -182
  491. package/dist/sdk/i18n/messages/es-ES.js +0 -183
  492. package/dist/sdk/i18n/messages/es-ES.js.map +0 -1
  493. package/dist/sdk/i18n/messages/es-ES.json +0 -178
  494. package/dist/sdk/i18n/messages/pt-BR.js +0 -183
  495. package/dist/sdk/i18n/messages/pt-BR.js.map +0 -1
  496. package/dist/sdk/i18n/messages/pt-BR.json +0 -178
  497. package/dist/sdk/i18n/provider.d.ts +0 -1
  498. package/dist/sdk/i18n/provider.js +0 -30
  499. package/dist/sdk/i18n/provider.js.map +0 -1
  500. package/dist/sdk/i18n/server.d.ts +0 -28
  501. package/dist/sdk/i18n/server.js +0 -59
  502. package/dist/sdk/i18n/server.js.map +0 -1
  503. package/dist/utils/resolve-authored-copy.js +0 -18
  504. package/dist/utils/resolve-authored-copy.js.map +0 -1
  505. package/dist/utils/substitute-template.js +0 -33
  506. package/dist/utils/substitute-template.js.map +0 -1
@@ -1,18 +1,49 @@
1
1
  "use client";
2
2
  import { defineComponent } from "../../core/dist/define-component.js";
3
+ import { defineContentType } from "../../core/dist/define-content-type.js";
3
4
  import "../../core/dist/index.js";
4
5
  import { useStorefrontContext } from "../../sdk/context/storefront-context.js";
6
+ import { useMessageFormatter } from "../../sdk/i18n/use-message-formatter.js";
5
7
  import { useActionsOverride } from "../../sdk/actions/actions-override-context.js";
6
- import { resolveAuthoredCopy } from "../../utils/resolve-authored-copy.js";
8
+ import { formatErrorCode } from "../../sdk/i18n/format-error-code.js";
7
9
  import { Select } from "../../particles/select/select.js";
8
10
  import { useInstallmentsSelection } from "./use-installments-selection.js";
9
11
  import { installmentLabel } from "./installments.js";
10
12
  import { jsx, jsxs } from "react/jsx-runtime";
11
- const InstallmentsSelectDefinition = defineComponent({
12
- name: "InstallmentsSelect",
13
- importPath: "@vtex/faststore/components",
14
- component: InstallmentsSelect,
15
- fragment: `
13
+ //#region src/matter/installments/installments-select.tsx
14
+ /**
15
+ * `InstallmentsSelect` matter (T90, specs/render-installments-as-a-radio-group.md;
16
+ * docs/features/credit-card/rfc.md § D4, "a radio/select"). The collapsed sibling of `Installments`:
17
+ * the same installment tiers, the same server-bound selection, and the same write path, rendered as a
18
+ * single closed Base UI Select control instead of a stacked `RadioGroup` — for a narrow payment
19
+ * column, a drawer, or a mobile checkout where twelve stacked rows do not fit (Decision 1: a second
20
+ * registered component, never a rendering prop on `Installments`).
21
+ *
22
+ * Reads and dispatches through `useInstallmentsSelection()` — the same engine `Installments` uses —
23
+ * so matching, tier resolution, state derivation, the BIN-confirmation pending gate, and the dispatch
24
+ * itself cannot drift between the two surfaces (Decision 3). Formats each option with the same
25
+ * `installmentLabel` function the radio surface uses (FR-5), driven by the same three message fields,
26
+ * so a store moving between surfaces carries its copy across unchanged.
27
+ *
28
+ * Declares its own `fragment InstallmentsSelectData on Query`, selection-set-identical to
29
+ * `InstallmentsData` under a distinct name (Decision 4) — two registered components must not share one
30
+ * fragment *name*, which would collide once both sit on a page.
31
+ *
32
+ * The popup is composed inside `Select.Portal`, teleported to `<body>` (Decision 5, reversing this
33
+ * spec's own first draft): both shipped `Select` consumers (`billing-address.tsx`, `shipping-address.tsx`)
34
+ * do the same, and the payment controller composes this leaf inside overlay popups where the portal's
35
+ * clipping protection matters. The accepted cost — a store's descendant-selector styling and compound
36
+ * swatches cannot reach the popup's internals — is recorded there, not solved here.
37
+ *
38
+ * The closed control's text is resolved locally from this component's own `tiers` (Decision 6), never
39
+ * from Base UI's automatic item-label lookup, so it is correct before the popup has ever been opened;
40
+ * a bound count matching no rendered tier shows the authorable `placeholder` instead of a fabricated
41
+ * label (FR-8). `Select.Label` always renders (Decision 13), giving the control a programmatic
42
+ * accessible name (FR-14) with no mode prop — the FPM forbids a `showX` switch inside one component. No
43
+ * `modal` prop is authored (Decision 14): the particle's own default (`true`) is inherited unchanged,
44
+ * matching both shipped consumers.
45
+ */
46
+ const fragment = `
16
47
  fragment InstallmentsSelectData on Query {
17
48
  payment {
18
49
  __typename
@@ -29,6 +60,7 @@ const InstallmentsSelectDefinition = defineComponent({
29
60
  currencyCode
30
61
  }
31
62
  interestRate
63
+ interestFree
32
64
  }
33
65
  }
34
66
  selectedInstallment {
@@ -37,43 +69,117 @@ const InstallmentsSelectDefinition = defineComponent({
37
69
  }
38
70
  }
39
71
  }
40
- `,
72
+ `;
73
+ const InstallmentsSelectContent = defineContentType({
74
+ id: "installments-select",
75
+ title: "Installments Select",
76
+ description: "Copy for the installment options, the control label, its placeholder and a refused pick.",
77
+ schema: {
78
+ type: "object",
79
+ additionalProperties: false,
80
+ properties: {
81
+ installmentTemplate: {
82
+ type: "string",
83
+ title: "Installment",
84
+ description: "`value` is the formatted per-installment value.",
85
+ format: "icu-message",
86
+ messageSource: "{count}x of {value}",
87
+ messageArguments: {
88
+ type: "object",
89
+ properties: {
90
+ count: { type: "integer" },
91
+ value: { type: "string" }
92
+ }
93
+ },
94
+ messageExample: {
95
+ count: 3,
96
+ value: "$35.00"
97
+ }
98
+ },
99
+ interestFreeLabel: {
100
+ type: "string",
101
+ title: "Interest-free label",
102
+ description: "Appended when a tier is interest-free.",
103
+ format: "icu-message",
104
+ messageSource: "interest-free"
105
+ },
106
+ interestTemplate: {
107
+ type: "string",
108
+ title: "Interest",
109
+ description: "Appended when a tier is not interest-free. `rate` is the formatted percentage: an order form rate of 100 is `1`.",
110
+ format: "icu-message",
111
+ messageSource: "{rate}% interest",
112
+ messageArguments: {
113
+ type: "object",
114
+ properties: { rate: { type: "string" } }
115
+ },
116
+ messageExample: { rate: "1.5" }
117
+ },
118
+ label: {
119
+ type: "string",
120
+ title: "Label",
121
+ description: "The control's visible accessible name.",
122
+ format: "icu-message",
123
+ messageSource: "Installments"
124
+ },
125
+ placeholder: {
126
+ type: "string",
127
+ title: "Placeholder",
128
+ description: "Shown on the closed control when the bound count matches no rendered tier.",
129
+ format: "icu-message",
130
+ messageSource: "Select an installment plan"
131
+ },
132
+ invalidInstallmentMessage: {
133
+ type: "string",
134
+ title: "Invalid installment message",
135
+ description: "Shown when the picked installment plan is no longer offered.",
136
+ format: "icu-message",
137
+ messageSource: "This installment plan is no longer available. Choose another one."
138
+ },
139
+ missingMethodMessage: {
140
+ type: "string",
141
+ title: "Missing payment method message",
142
+ description: "Shown when an installment plan is picked before a payment method.",
143
+ format: "icu-message",
144
+ messageSource: "Choose a payment method before choosing an installment plan."
145
+ },
146
+ genericErrorMessage: {
147
+ type: "string",
148
+ title: "Selection failure message",
149
+ description: "Shown when a pick fails: a network failure or a fault the shopper cannot fix.",
150
+ format: "icu-message",
151
+ messageSource: "Unable to select the installment plan. Please try again."
152
+ }
153
+ }
154
+ }
155
+ });
156
+ /**
157
+ * The message for each code an installment pick can return. Same codes and fields as `INSTALLMENTS_ERROR_FIELDS`. A code this map does not
158
+ * know shows genericErrorMessage.
159
+ */
160
+ const INSTALLMENTS_SELECT_ERROR_FIELDS = {
161
+ MISSING_CART_CONTEXT: "genericErrorMessage",
162
+ CART_NOT_FOUND: "genericErrorMessage",
163
+ MISSING_PAYMENT_METHOD_SELECTION: "missingMethodMessage",
164
+ INVALID_INSTALLMENT_COUNT: "invalidInstallmentMessage",
165
+ NETWORK_ERROR: "genericErrorMessage"
166
+ };
167
+ const InstallmentsSelectDefinition = defineComponent({
168
+ name: "InstallmentsSelect",
169
+ importPath: "@vtex/faststore/components",
170
+ component: InstallmentsSelect,
171
+ fragment,
41
172
  fetchStrategy: "reactive",
42
173
  requiresContext: "payment",
43
174
  actions: { payment: ["setInstallments"] },
44
175
  docPath: "./installments.md",
176
+ content: InstallmentsSelectContent,
45
177
  editor: {
46
178
  label: "Installments Select",
47
179
  category: "commerce"
48
180
  },
49
- schema: {
50
- installmentTemplate: {
51
- type: "string",
52
- default: "{count}x of {value}",
53
- label: "Installment template"
54
- },
55
- interestFreeLabel: {
56
- type: "string",
57
- default: "interest-free",
58
- label: "Interest-free label"
59
- },
60
- interestTemplate: {
61
- type: "string",
62
- default: "{rate}% interest",
63
- label: "Interest template"
64
- },
65
- label: {
66
- type: "string",
67
- default: "Installments",
68
- label: "Accessible label"
69
- },
70
- placeholder: {
71
- type: "string",
72
- default: "Select an installment plan",
73
- label: "Placeholder"
74
- }
75
- },
76
- guideline: "Collapsed installment picker for checkout: a single closed control (Base UI Select) showing the persisted selection's label, expanding into one option per tier the matched option carries — count, per-installment value, and interest, formatted identically to Installments (the API guarantees a 1x tier is present in every option). Reads the same Query.payment data and dispatches the same $actions.payment.setInstallments as Installments — the two are alternative renderings of one engine, so pick whichever fits the layout: this one for a narrow column, a drawer, or a mobile checkout; Installments when stacked rows fit. Must be inside a PaymentSectionRoot or PaymentSectionController — place it as a sibling of CardEntry and SavedCards, never nested inside either. Renders its own options from real data — no children. The popup is portalled to <body>: the label, trigger, value, icon, and inline error stay reachable from a store's style array, but the option list does not — see installments.md."
181
+ schema: {},
182
+ guideline: "Collapsed installment picker for checkout: a single closed control (Base UI Select) showing the persisted selection's label, expanding into one option per tier the matched option carries — count, per-installment value, and interest, formatted identically to Installments (the API guarantees a 1x tier is present in every option). Its copy comes from the $content fields installmentTemplate, interestFreeLabel, interestTemplate, label and placeholder. Reads the same Query.payment data and dispatches the same $actions.payment.setInstallments as Installments — the two are alternative renderings of one engine, so pick whichever fits the layout: this one for a narrow column, a drawer, or a mobile checkout; Installments when stacked rows fit. Renders nothing until a new card's entry is valid (length, Luhn, expiration, security code) or a saved card is selected, and nothing when no payment method the store offers carries a tier above 1x. Picking an option dispatches $actions.payment.setInstallments; the mutation returns the cart, whose total is the greater of the order form's value and the selected payment's value, so a CartTotal elsewhere on the page shows the interest-inclusive total from the normalized cache. Must be inside a PaymentSectionRoot or PaymentSectionController — place it as a sibling of CardEntry and SavedCards, never nested inside either. Renders its own options from real data — no children. The popup is portalled to <body>: the label, trigger, value, icon, and inline error stay reachable from a store's style array, but the option list does not — see installments.md."
77
183
  });
78
184
  /**
79
185
  * Resolves `Select.Root`'s `onValueChange` value into a dispatch, or a no-op. Exported so a test can
@@ -88,14 +194,20 @@ function handleInstallmentSelectValueChange(value, selectInstallment) {
88
194
  if (value === null) return;
89
195
  selectInstallment(Number(value));
90
196
  }
91
- function InstallmentsSelect({ installmentTemplate = "{count}x of {value}", interestFreeLabel = "interest-free", interestTemplate = "{rate}% interest", label, placeholder = "Select an installment plan", $data, $actions: $actionsProp, className, ...props }) {
197
+ function InstallmentsSelect({ $content, $locale, $data, $actions: $actionsProp, className, ...props }) {
92
198
  const $actions = useActionsOverride($actionsProp);
93
199
  const { locale } = useStorefrontContext();
94
- const { tiers, selectedCount, state, isPending, selectionError, selectInstallment, placing, cardPaymentCollapsed } = useInstallmentsSelection({
200
+ const { format } = useMessageFormatter(InstallmentsSelectContent, $content);
201
+ const messages = {
202
+ installment: (args) => format("installmentTemplate", args),
203
+ interestFree: () => format("interestFreeLabel"),
204
+ interest: (args) => format("interestTemplate", args)
205
+ };
206
+ const { tiers, selectedCount, state, isPending, selectionError, selectInstallment, placing, cardPaymentCollapsed, visible } = useInstallmentsSelection({
95
207
  $data,
96
208
  $actions
97
209
  });
98
- if (cardPaymentCollapsed) return null;
210
+ if (cardPaymentCollapsed || !visible) return null;
99
211
  return /* @__PURE__ */ jsxs("div", {
100
212
  ...props,
101
213
  className,
@@ -109,7 +221,7 @@ function InstallmentsSelect({ installmentTemplate = "{count}x of {value}", inter
109
221
  children: [selectionError ? /* @__PURE__ */ jsx("div", {
110
222
  role: "alert",
111
223
  "data-fs-installments-error": "",
112
- children: selectionError
224
+ children: formatErrorCode(InstallmentsSelectContent, INSTALLMENTS_SELECT_ERROR_FIELDS, selectionError, format, "genericErrorMessage")
113
225
  }) : null, tiers.length > 0 ? /* @__PURE__ */ jsxs(Select.Root, {
114
226
  value: String(selectedCount),
115
227
  onValueChange: (value) => handleInstallmentSelectValueChange(value, selectInstallment),
@@ -117,7 +229,7 @@ function InstallmentsSelect({ installmentTemplate = "{count}x of {value}", inter
117
229
  children: [
118
230
  /* @__PURE__ */ jsx(Select.Label, {
119
231
  "data-fs-installments-label": "",
120
- children: resolveAuthoredCopy(label, "Installments")
232
+ children: format("label")
121
233
  }),
122
234
  /* @__PURE__ */ jsxs(Select.Trigger, {
123
235
  "data-fs-installments-trigger": "",
@@ -129,10 +241,8 @@ function InstallmentsSelect({ installmentTemplate = "{count}x of {value}", inter
129
241
  return tier ? installmentLabel({
130
242
  tier,
131
243
  locale,
132
- installmentTemplate,
133
- interestFreeLabel,
134
- interestTemplate
135
- }) : placeholder;
244
+ messages
245
+ }) : format("placeholder");
136
246
  }
137
247
  }), /* @__PURE__ */ jsx(Select.Icon, {
138
248
  "data-fs-installments-icon": "",
@@ -143,9 +253,7 @@ function InstallmentsSelect({ installmentTemplate = "{count}x of {value}", inter
143
253
  const text = installmentLabel({
144
254
  tier,
145
255
  locale,
146
- installmentTemplate,
147
- interestFreeLabel,
148
- interestTemplate
256
+ messages
149
257
  });
150
258
  return /* @__PURE__ */ jsx(Select.Item, {
151
259
  value: String(tier.count),
@@ -162,6 +270,6 @@ function InstallmentsSelect({ installmentTemplate = "{count}x of {value}", inter
162
270
  });
163
271
  }
164
272
  //#endregion
165
- export { InstallmentsSelect, InstallmentsSelectDefinition, handleInstallmentSelectValueChange };
273
+ export { INSTALLMENTS_SELECT_ERROR_FIELDS, InstallmentsSelect, InstallmentsSelectContent, InstallmentsSelectDefinition, handleInstallmentSelectValueChange };
166
274
 
167
275
  //# sourceMappingURL=installments-select.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"installments-select.js","names":[],"sources":["../../../src/matter/installments/installments-select.tsx"],"sourcesContent":["'use client';\n\nimport { defineComponent } from '@vtex/fs-core';\nimport type { ComponentPropsWithRef } from 'react';\nimport { Select } from '../../particles/select/select.js';\nimport { useActionsOverride } from '../../sdk/actions/actions-override-context.js';\nimport type { ComponentActions } from '../../sdk/actions/types.js';\nimport { useStorefrontContext } from '../../sdk/context/storefront-context.js';\nimport { resolveAuthoredCopy } from '../../utils/resolve-authored-copy.js';\nimport { type InstallmentOption, installmentLabel } from './installments.js';\nimport { useInstallmentsSelection } from './use-installments-selection.js';\n\n/**\n * `InstallmentsSelect` matter (T90, specs/render-installments-as-a-radio-group.md;\n * docs/features/credit-card/rfc.md § D4, \"a radio/select\"). The collapsed sibling of `Installments`:\n * the same installment tiers, the same server-bound selection, and the same write path, rendered as a\n * single closed Base UI Select control instead of a stacked `RadioGroup` — for a narrow payment\n * column, a drawer, or a mobile checkout where twelve stacked rows do not fit (Decision 1: a second\n * registered component, never a rendering prop on `Installments`).\n *\n * Reads and dispatches through `useInstallmentsSelection()` — the same engine `Installments` uses —\n * so matching, tier resolution, state derivation, the BIN-confirmation pending gate, and the dispatch\n * itself cannot drift between the two surfaces (Decision 3). Formats each option with the same\n * `installmentLabel` function the radio surface uses (FR-5), driven by the same four authorable copy\n * props with the same shipped pt-BR defaults, so a store moving between surfaces carries its copy\n * across unchanged.\n *\n * Declares its own `fragment InstallmentsSelectData on Query`, selection-set-identical to\n * `InstallmentsData` under a distinct name (Decision 4) — two registered components must not share one\n * fragment *name*, which would collide once both sit on a page.\n *\n * The popup is composed inside `Select.Portal`, teleported to `<body>` (Decision 5, reversing this\n * spec's own first draft): both shipped `Select` consumers (`billing-address.tsx`, `shipping-address.tsx`)\n * do the same, and the payment controller composes this leaf inside overlay popups where the portal's\n * clipping protection matters. The accepted cost — a store's descendant-selector styling and compound\n * swatches cannot reach the popup's internals — is recorded there, not solved here.\n *\n * The closed control's text is resolved locally from this component's own `tiers` (Decision 6), never\n * from Base UI's automatic item-label lookup, so it is correct before the popup has ever been opened;\n * a bound count matching no rendered tier shows the authorable `placeholder` instead of a fabricated\n * label (FR-8). `Select.Label` always renders (Decision 13), giving the control a programmatic\n * accessible name (FR-14) with no mode prop — the FPM forbids a `showX` switch inside one component. No\n * `modal` prop is authored (Decision 14): the particle's own default (`true`) is inherited unchanged,\n * matching both shipped consumers.\n */\n\n// ---------------------------------------------------------------------------\n// GraphQL Fragment — raw template literal, identical selection set to `InstallmentsData`\n// (`installments.tsx`) apart from the name (Decision 4; INV-8 asserts the two stay identical).\n// `total` stays deselected — neither surface renders or computes against it. `payment { id }` is\n// mandatory: it is what lets the action's echoed `payment` re-normalize the entity these fragments\n// read.\n// ---------------------------------------------------------------------------\n\nconst fragment = /* GraphQL */ `\n fragment InstallmentsSelectData on Query {\n payment {\n __typename\n id\n installmentOptions {\n __typename\n methodId\n bin\n installments {\n __typename\n count\n value {\n amount\n currencyCode\n }\n interestRate\n }\n }\n selectedInstallment {\n __typename\n count\n }\n }\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * `$data` forwarded by the reactive runtime — the unwrapped value of the `payment` top-level field on\n * `InstallmentsSelectData on Query` (arity-1 fragment, ADR-0015), not a `{ payment: … }` wrapper.\n * Every field optional, mirroring `InstallmentsData`: `$data` arrives partial while the entity\n * resolves.\n */\nexport type InstallmentsSelectData = {\n installmentOptions?: readonly InstallmentOption[];\n selectedInstallment?: { count: number } | null;\n} | null;\n\nexport type InstallmentsSelectProps = Omit<ComponentPropsWithRef<'div'>, 'children'> & {\n /** Placeholders `{count}` / `{value}`, matching `Installments`'/`PaymentSummary`'s convention. */\n installmentTemplate?: string;\n /** Appended when a tier's `interestRate` is `0`. */\n interestFreeLabel?: string;\n /** Placeholder `{rate}`; appended instead of `interestFreeLabel` when a tier's `interestRate` is above `0`. */\n interestTemplate?: string;\n /**\n * Accessible name for the control, rendered as `Select.Label` (Decision 13, always renders).\n * Resolved through `resolveAuthoredCopy` (T38): an authored empty or whitespace-only string falls\n * back to the default rather than rendering a nameless combobox.\n */\n label?: string;\n /** Shown on the closed control when the bound count matches no rendered tier (Decision 6/FR-8). */\n placeholder?: string;\n /** `InstallmentsSelectData` slice forwarded by the reactive runtime. */\n $data?: InstallmentsSelectData;\n /** Compiler-injected action surface; carries `payment.setInstallments`. */\n $actions?: ComponentActions;\n};\n\n// ---------------------------------------------------------------------------\n// Definition\n// ---------------------------------------------------------------------------\n\nexport const InstallmentsSelectDefinition = defineComponent<InstallmentsSelectProps>({\n name: 'InstallmentsSelect',\n importPath: '@vtex/faststore/components',\n component: InstallmentsSelect,\n fragment,\n fetchStrategy: 'reactive',\n requiresContext: 'payment',\n actions: { payment: ['setInstallments'] },\n // Required: the catalog builder resolves a doc by the `<basename>.md` convention\n // (`installments-select.md`, which does not exist) and silently drops the key without an explicit\n // docPath — mirrors `PaymentSectionController`'s identical need (`payment-controller.tsx:113`).\n docPath: './installments.md',\n editor: { label: 'Installments Select', category: 'commerce' },\n schema: {\n installmentTemplate: { type: 'string', default: '{count}x of {value}', label: 'Installment template' },\n interestFreeLabel: { type: 'string', default: 'interest-free', label: 'Interest-free label' },\n interestTemplate: { type: 'string', default: '{rate}% interest', label: 'Interest template' },\n label: { type: 'string', default: 'Installments', label: 'Accessible label' },\n placeholder: { type: 'string', default: 'Select an installment plan', label: 'Placeholder' },\n },\n guideline:\n \"Collapsed installment picker for checkout: a single closed control (Base UI Select) showing the persisted selection's label, expanding into one option per tier the matched option carries — count, per-installment value, and interest, formatted identically to Installments (the API guarantees a 1x tier is present in every option). Reads the same Query.payment data and dispatches the same $actions.payment.setInstallments as Installments — the two are alternative renderings of one engine, so pick whichever fits the layout: this one for a narrow column, a drawer, or a mobile checkout; Installments when stacked rows fit. Must be inside a PaymentSectionRoot or PaymentSectionController — place it as a sibling of CardEntry and SavedCards, never nested inside either. Renders its own options from real data — no children. The popup is portalled to <body>: the label, trigger, value, icon, and inline error stay reachable from a store's style array, but the option list does not — see installments.md.\",\n});\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\n/**\n * Resolves `Select.Root`'s `onValueChange` value into a dispatch, or a no-op. Exported so a test can\n * invoke it directly (Decision 7): `SelectRootProps.onValueChange` is `(value: string | null) => void`,\n * unlike `RadioGroupProps`', and `Number(null)` is `0` — `paymentInstallmentSelect` would reject count\n * `0` as `INVALID_INSTALLMENT_COUNT`. Base UI's `Select.Root` never actually calls `onValueChange` with\n * `null` through a user-reachable path once every `Select.Item` carries a non-null `value` (mirrors\n * `billing-address.tsx`'s own `handleCountryChange` reasoning), so this guard has no interaction that\n * could exercise it end-to-end — the direct-invocation test is the only way to cover it.\n */\nexport function handleInstallmentSelectValueChange(\n value: string | null,\n selectInstallment: (count: number) => void,\n): void {\n if (value === null) return;\n selectInstallment(Number(value));\n}\n\nexport function InstallmentsSelect({\n installmentTemplate = '{count}x of {value}',\n interestFreeLabel = 'interest-free',\n interestTemplate = '{rate}% interest',\n label,\n placeholder = 'Select an installment plan',\n $data,\n $actions: $actionsProp,\n className,\n ...props\n}: InstallmentsSelectProps) {\n const $actions = useActionsOverride($actionsProp);\n // T192: the formatting locale is the storefront's, never an authored prop (RFC localization § 10).\n const { locale } = useStorefrontContext();\n const { tiers, selectedCount, state, isPending, selectionError, selectInstallment, placing, cardPaymentCollapsed } =\n useInstallmentsSelection({\n $data,\n $actions,\n });\n\n // T191 (FR-7): nothing renders while the card payment is collapsed. Returned after the last hook, so\n // this instance stays mounted and keeps its local state.\n if (cardPaymentCollapsed) return null;\n\n return (\n <div\n {...props}\n className={className}\n inert={placing}\n aria-disabled={placing || undefined}\n data-fs-installments=\"\"\n data-fs-installments-control=\"select\"\n data-fs-installments-state={state}\n aria-busy={isPending || undefined}\n {...(placing ? { 'data-fs-installments-placing': '' } : {})}\n >\n {selectionError ? (\n <div role=\"alert\" data-fs-installments-error=\"\">\n {selectionError}\n </div>\n ) : null}\n {tiers.length > 0 ? (\n <Select.Root\n value={String(selectedCount)}\n onValueChange={(value) => handleInstallmentSelectValueChange(value, selectInstallment)}\n disabled={isPending}\n >\n <Select.Label data-fs-installments-label=\"\">{resolveAuthoredCopy(label, 'Installments')}</Select.Label>\n <Select.Trigger data-fs-installments-trigger=\"\" disabled={isPending}>\n <Select.Value data-fs-installments-value=\"\">\n {(value) => {\n const tier = tiers.find((candidate) => String(candidate.count) === value);\n return tier\n ? installmentLabel({ tier, locale, installmentTemplate, interestFreeLabel, interestTemplate })\n : placeholder;\n }}\n </Select.Value>\n <Select.Icon data-fs-installments-icon=\"\">▾</Select.Icon>\n </Select.Trigger>\n <Select.Portal>\n <Select.Positioner>\n <Select.Popup>\n <Select.List>\n {tiers.map((tier) => {\n const text = installmentLabel({\n tier,\n locale,\n installmentTemplate,\n interestFreeLabel,\n interestTemplate,\n });\n return (\n <Select.Item\n key={tier.count}\n value={String(tier.count)}\n label={text}\n data-fs-installments-option=\"\"\n >\n <span data-fs-installments-option-label=\"\">{text}</span>\n </Select.Item>\n );\n })}\n </Select.List>\n </Select.Popup>\n </Select.Positioner>\n </Select.Portal>\n </Select.Root>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"installments-select.js","names":[],"sources":["../../../src/matter/installments/installments-select.tsx"],"sourcesContent":["'use client';\n\nimport {\n type ContentValue,\n defineComponent,\n defineContentType,\n type MessageFieldName,\n type MessageLocaleProp,\n} from '@vtex/fs-core';\nimport type { ComponentPropsWithRef } from 'react';\nimport { Select } from '../../particles/select/select.js';\nimport { useActionsOverride } from '../../sdk/actions/actions-override-context.js';\nimport type { ComponentActions } from '../../sdk/actions/types.js';\nimport { useStorefrontContext } from '../../sdk/context/storefront-context.js';\nimport { formatErrorCode } from '../../sdk/i18n/format-error-code.js';\nimport { useMessageFormatter } from '../../sdk/i18n/use-message-formatter.js';\nimport { type InstallmentLabelMessages, type InstallmentOption, installmentLabel } from './installments.js';\nimport { type PaymentInstallmentSelectErrorCode, useInstallmentsSelection } from './use-installments-selection.js';\n\n/**\n * `InstallmentsSelect` matter (T90, specs/render-installments-as-a-radio-group.md;\n * docs/features/credit-card/rfc.md § D4, \"a radio/select\"). The collapsed sibling of `Installments`:\n * the same installment tiers, the same server-bound selection, and the same write path, rendered as a\n * single closed Base UI Select control instead of a stacked `RadioGroup` — for a narrow payment\n * column, a drawer, or a mobile checkout where twelve stacked rows do not fit (Decision 1: a second\n * registered component, never a rendering prop on `Installments`).\n *\n * Reads and dispatches through `useInstallmentsSelection()` — the same engine `Installments` uses —\n * so matching, tier resolution, state derivation, the BIN-confirmation pending gate, and the dispatch\n * itself cannot drift between the two surfaces (Decision 3). Formats each option with the same\n * `installmentLabel` function the radio surface uses (FR-5), driven by the same three message fields,\n * so a store moving between surfaces carries its copy across unchanged.\n *\n * Declares its own `fragment InstallmentsSelectData on Query`, selection-set-identical to\n * `InstallmentsData` under a distinct name (Decision 4) — two registered components must not share one\n * fragment *name*, which would collide once both sit on a page.\n *\n * The popup is composed inside `Select.Portal`, teleported to `<body>` (Decision 5, reversing this\n * spec's own first draft): both shipped `Select` consumers (`billing-address.tsx`, `shipping-address.tsx`)\n * do the same, and the payment controller composes this leaf inside overlay popups where the portal's\n * clipping protection matters. The accepted cost — a store's descendant-selector styling and compound\n * swatches cannot reach the popup's internals — is recorded there, not solved here.\n *\n * The closed control's text is resolved locally from this component's own `tiers` (Decision 6), never\n * from Base UI's automatic item-label lookup, so it is correct before the popup has ever been opened;\n * a bound count matching no rendered tier shows the authorable `placeholder` instead of a fabricated\n * label (FR-8). `Select.Label` always renders (Decision 13), giving the control a programmatic\n * accessible name (FR-14) with no mode prop — the FPM forbids a `showX` switch inside one component. No\n * `modal` prop is authored (Decision 14): the particle's own default (`true`) is inherited unchanged,\n * matching both shipped consumers.\n */\n\n// ---------------------------------------------------------------------------\n// GraphQL Fragment — raw template literal, identical selection set to `InstallmentsData`\n// (`installments.tsx`) apart from the name (Decision 4; INV-8 asserts the two stay identical).\n// `totalAmount` stays deselected — neither surface renders or computes against it. `payment { id }` is\n// mandatory: it is what lets the action's echoed `payment` re-normalize the entity these fragments\n// read.\n// ---------------------------------------------------------------------------\n\nconst fragment = /* GraphQL */ `\n fragment InstallmentsSelectData on Query {\n payment {\n __typename\n id\n installmentOptions {\n __typename\n methodId\n bin\n installments {\n __typename\n count\n value {\n amount\n currencyCode\n }\n interestRate\n interestFree\n }\n }\n selectedInstallment {\n __typename\n count\n }\n }\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * `$data` forwarded by the reactive runtime — the unwrapped value of the `payment` top-level field on\n * `InstallmentsSelectData on Query` (arity-1 fragment, ADR-0015), not a `{ payment: … }` wrapper.\n * Every field optional, mirroring `InstallmentsData`: `$data` arrives partial while the entity\n * resolves.\n */\nexport type InstallmentsSelectData = {\n installmentOptions?: readonly InstallmentOption[];\n selectedInstallment?: { count: number } | null;\n} | null;\n\nexport const InstallmentsSelectContent = defineContentType({\n id: 'installments-select',\n title: 'Installments Select',\n description: 'Copy for the installment options, the control label, its placeholder and a refused pick.',\n schema: {\n type: 'object',\n additionalProperties: false,\n properties: {\n installmentTemplate: {\n type: 'string',\n title: 'Installment',\n description: '`value` is the formatted per-installment value.',\n format: 'icu-message',\n messageSource: '{count}x of {value}',\n messageArguments: {\n type: 'object',\n properties: { count: { type: 'integer' }, value: { type: 'string' } },\n },\n messageExample: { count: 3, value: '$35.00' },\n },\n interestFreeLabel: {\n type: 'string',\n title: 'Interest-free label',\n description: 'Appended when a tier is interest-free.',\n format: 'icu-message',\n messageSource: 'interest-free',\n },\n interestTemplate: {\n type: 'string',\n title: 'Interest',\n description:\n 'Appended when a tier is not interest-free. `rate` is the formatted percentage: an order form rate of 100 is `1`.',\n format: 'icu-message',\n messageSource: '{rate}% interest',\n messageArguments: { type: 'object', properties: { rate: { type: 'string' } } },\n messageExample: { rate: '1.5' },\n },\n label: {\n type: 'string',\n title: 'Label',\n description: \"The control's visible accessible name.\",\n format: 'icu-message',\n messageSource: 'Installments',\n },\n placeholder: {\n type: 'string',\n title: 'Placeholder',\n description: 'Shown on the closed control when the bound count matches no rendered tier.',\n format: 'icu-message',\n messageSource: 'Select an installment plan',\n },\n invalidInstallmentMessage: {\n type: 'string',\n title: 'Invalid installment message',\n description: 'Shown when the picked installment plan is no longer offered.',\n format: 'icu-message',\n messageSource: 'This installment plan is no longer available. Choose another one.',\n },\n missingMethodMessage: {\n type: 'string',\n title: 'Missing payment method message',\n description: 'Shown when an installment plan is picked before a payment method.',\n format: 'icu-message',\n messageSource: 'Choose a payment method before choosing an installment plan.',\n },\n genericErrorMessage: {\n type: 'string',\n title: 'Selection failure message',\n description: 'Shown when a pick fails: a network failure or a fault the shopper cannot fix.',\n format: 'icu-message',\n messageSource: 'Unable to select the installment plan. Please try again.',\n },\n },\n },\n});\n\n/**\n * The message for each code an installment pick can return. Same codes and fields as `INSTALLMENTS_ERROR_FIELDS`. A code this map does not\n * know shows genericErrorMessage.\n */\nexport const INSTALLMENTS_SELECT_ERROR_FIELDS = {\n MISSING_CART_CONTEXT: 'genericErrorMessage',\n CART_NOT_FOUND: 'genericErrorMessage',\n MISSING_PAYMENT_METHOD_SELECTION: 'missingMethodMessage',\n INVALID_INSTALLMENT_COUNT: 'invalidInstallmentMessage',\n NETWORK_ERROR: 'genericErrorMessage',\n} as const satisfies Record<PaymentInstallmentSelectErrorCode, MessageFieldName<typeof InstallmentsSelectContent>>;\n\nexport type InstallmentsSelectProps = Omit<ComponentPropsWithRef<'div'>, 'children'> &\n MessageLocaleProp & {\n /** Merchant-authored copy: the option template, the interest suffixes, the label, the placeholder and the error. */\n $content?: ContentValue<typeof InstallmentsSelectContent>;\n /** `InstallmentsSelectData` slice forwarded by the reactive runtime. */\n $data?: InstallmentsSelectData;\n /** Compiler-injected action surface; carries `payment.setInstallments`. */\n $actions?: ComponentActions;\n };\n\n// ---------------------------------------------------------------------------\n// Definition\n// ---------------------------------------------------------------------------\n\nexport const InstallmentsSelectDefinition = defineComponent<InstallmentsSelectProps>({\n name: 'InstallmentsSelect',\n importPath: '@vtex/faststore/components',\n component: InstallmentsSelect,\n fragment,\n fetchStrategy: 'reactive',\n requiresContext: 'payment',\n actions: { payment: ['setInstallments'] },\n // Required: the catalog builder resolves a doc by the `<basename>.md` convention\n // (`installments-select.md`, which does not exist) and silently drops the key without an explicit\n // docPath — mirrors `PaymentSectionController`'s identical need (`payment-controller.tsx:113`).\n docPath: './installments.md',\n content: InstallmentsSelectContent,\n editor: { label: 'Installments Select', category: 'commerce' },\n schema: {},\n guideline:\n \"Collapsed installment picker for checkout: a single closed control (Base UI Select) showing the persisted selection's label, expanding into one option per tier the matched option carries — count, per-installment value, and interest, formatted identically to Installments (the API guarantees a 1x tier is present in every option). Its copy comes from the $content fields installmentTemplate, interestFreeLabel, interestTemplate, label and placeholder. Reads the same Query.payment data and dispatches the same $actions.payment.setInstallments as Installments — the two are alternative renderings of one engine, so pick whichever fits the layout: this one for a narrow column, a drawer, or a mobile checkout; Installments when stacked rows fit. Renders nothing until a new card's entry is valid (length, Luhn, expiration, security code) or a saved card is selected, and nothing when no payment method the store offers carries a tier above 1x. Picking an option dispatches $actions.payment.setInstallments; the mutation returns the cart, whose total is the greater of the order form's value and the selected payment's value, so a CartTotal elsewhere on the page shows the interest-inclusive total from the normalized cache. Must be inside a PaymentSectionRoot or PaymentSectionController — place it as a sibling of CardEntry and SavedCards, never nested inside either. Renders its own options from real data — no children. The popup is portalled to <body>: the label, trigger, value, icon, and inline error stay reachable from a store's style array, but the option list does not — see installments.md.\",\n});\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\n/**\n * Resolves `Select.Root`'s `onValueChange` value into a dispatch, or a no-op. Exported so a test can\n * invoke it directly (Decision 7): `SelectRootProps.onValueChange` is `(value: string | null) => void`,\n * unlike `RadioGroupProps`', and `Number(null)` is `0` — `paymentInstallmentSelect` would reject count\n * `0` as `INVALID_INSTALLMENT_COUNT`. Base UI's `Select.Root` never actually calls `onValueChange` with\n * `null` through a user-reachable path once every `Select.Item` carries a non-null `value` (mirrors\n * `billing-address.tsx`'s own `handleCountryChange` reasoning), so this guard has no interaction that\n * could exercise it end-to-end — the direct-invocation test is the only way to cover it.\n */\nexport function handleInstallmentSelectValueChange(\n value: string | null,\n selectInstallment: (count: number) => void,\n): void {\n if (value === null) return;\n selectInstallment(Number(value));\n}\n\nexport function InstallmentsSelect({\n $content,\n $locale,\n $data,\n $actions: $actionsProp,\n className,\n ...props\n}: InstallmentsSelectProps) {\n const $actions = useActionsOverride($actionsProp);\n // T192: the formatting locale is the storefront's, never an authored prop (RFC localization § 10).\n const { locale } = useStorefrontContext();\n const { format } = useMessageFormatter(InstallmentsSelectContent, $content);\n const messages: InstallmentLabelMessages = {\n installment: (args) => format('installmentTemplate', args),\n interestFree: () => format('interestFreeLabel'),\n interest: (args) => format('interestTemplate', args),\n };\n const {\n tiers,\n selectedCount,\n state,\n isPending,\n selectionError,\n selectInstallment,\n placing,\n cardPaymentCollapsed,\n visible,\n } = useInstallmentsSelection({\n $data,\n $actions,\n });\n\n // T191 (FR-7): nothing renders while the card payment is collapsed. T201: nor while the entry is not\n // valid, or the store offers no installments — the hook's one `visible` decision, so the two surfaces\n // cannot drift. Returned after the last hook, so this instance stays mounted and keeps its local state.\n if (cardPaymentCollapsed || !visible) return null;\n\n return (\n <div\n {...props}\n className={className}\n inert={placing}\n aria-disabled={placing || undefined}\n data-fs-installments=\"\"\n data-fs-installments-control=\"select\"\n data-fs-installments-state={state}\n aria-busy={isPending || undefined}\n {...(placing ? { 'data-fs-installments-placing': '' } : {})}\n >\n {selectionError ? (\n <div role=\"alert\" data-fs-installments-error=\"\">\n {formatErrorCode(\n InstallmentsSelectContent,\n INSTALLMENTS_SELECT_ERROR_FIELDS,\n selectionError,\n format,\n 'genericErrorMessage',\n )}\n </div>\n ) : null}\n {tiers.length > 0 ? (\n <Select.Root\n value={String(selectedCount)}\n onValueChange={(value) => handleInstallmentSelectValueChange(value, selectInstallment)}\n disabled={isPending}\n >\n <Select.Label data-fs-installments-label=\"\">{format('label')}</Select.Label>\n <Select.Trigger data-fs-installments-trigger=\"\" disabled={isPending}>\n <Select.Value data-fs-installments-value=\"\">\n {(value) => {\n const tier = tiers.find((candidate) => String(candidate.count) === value);\n return tier ? installmentLabel({ tier, locale, messages }) : format('placeholder');\n }}\n </Select.Value>\n <Select.Icon data-fs-installments-icon=\"\">▾</Select.Icon>\n </Select.Trigger>\n <Select.Portal>\n <Select.Positioner>\n <Select.Popup>\n <Select.List>\n {tiers.map((tier) => {\n const text = installmentLabel({ tier, locale, messages });\n return (\n <Select.Item\n key={tier.count}\n value={String(tier.count)}\n label={text}\n data-fs-installments-option=\"\"\n >\n <span data-fs-installments-option-label=\"\">{text}</span>\n </Select.Item>\n );\n })}\n </Select.List>\n </Select.Popup>\n </Select.Positioner>\n </Select.Portal>\n </Select.Root>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { ContentValue, MessageLocaleProp } from "../../core/dist/define-content-type.js";
1
2
  import { ComponentDefinition } from "../../core/dist/define-component.js";
2
3
  import "../../core/dist/index.js";
3
4
  import { ComponentActions } from "../../sdk/actions/types.js";
@@ -11,7 +12,10 @@ export type InstallmentMoney = Readonly<{
11
12
  export type InstallmentTier = Readonly<{
12
13
  count: number;
13
14
  value: InstallmentMoney;
14
- interestRate: number;
15
+ /** Hundredths of a percent. `null` when the order form did not say what the rate is (T230). */
16
+ interestRate: number | null;
17
+ /** `null` exactly when `interestRate` is `null`. Computed by the API, never by this component. */
18
+ interestFree: boolean | null;
15
19
  }>;
16
20
  export type InstallmentOption = Readonly<{
17
21
  methodId: string;
@@ -30,29 +34,105 @@ export type InstallmentsData = {
30
34
  count: number;
31
35
  } | null;
32
36
  } | null;
33
- export type InstallmentsProps = Omit<ComponentPropsWithRef<'div'>, 'children'> & {
34
- /** Placeholders `{count}` / `{value}`, matching `PaymentSummary`'s / `PricingInstallment`'s convention. */
35
- installmentTemplate?: string;
36
- /** Appended when a tier's `interestRate` is `0`. */
37
- interestFreeLabel?: string;
38
- /**
39
- * Placeholder `{rate}`; appended instead of `interestFreeLabel` when a tier's `interestRate` is above `0`.
40
- * `{rate}` is the order form's `interestRate` (hundredths of a percent) divided by 100: `100` renders `1`.
41
- */
42
- interestTemplate?: string;
37
+ export declare const InstallmentsContent: {
38
+ readonly id: "installments";
39
+ readonly title: "Installments";
40
+ readonly description: "Copy for the installment rows, the group legend and a refused pick.";
41
+ readonly schema: {
42
+ readonly type: "object";
43
+ readonly additionalProperties: false;
44
+ readonly properties: {
45
+ readonly installmentTemplate: {
46
+ readonly type: "string";
47
+ readonly title: "Installment";
48
+ readonly description: "`value` is the formatted per-installment value.";
49
+ readonly format: "icu-message";
50
+ readonly messageSource: "{count}x of {value}";
51
+ readonly messageArguments: {
52
+ readonly type: "object";
53
+ readonly properties: {
54
+ readonly count: {
55
+ readonly type: "integer";
56
+ };
57
+ readonly value: {
58
+ readonly type: "string";
59
+ };
60
+ };
61
+ };
62
+ readonly messageExample: {
63
+ readonly count: 3;
64
+ readonly value: "$35.00";
65
+ };
66
+ };
67
+ readonly interestFreeLabel: {
68
+ readonly type: "string";
69
+ readonly title: "Interest-free label";
70
+ readonly description: "Appended when a tier is interest-free.";
71
+ readonly format: "icu-message";
72
+ readonly messageSource: "interest-free";
73
+ };
74
+ readonly interestTemplate: {
75
+ readonly type: "string";
76
+ readonly title: "Interest";
77
+ readonly description: "Appended when a tier is not interest-free. `rate` is the formatted percentage: an order form rate of 100 is `1`.";
78
+ readonly format: "icu-message";
79
+ readonly messageSource: "{rate}% interest";
80
+ readonly messageArguments: {
81
+ readonly type: "object";
82
+ readonly properties: {
83
+ readonly rate: {
84
+ readonly type: "string";
85
+ };
86
+ };
87
+ };
88
+ readonly messageExample: {
89
+ readonly rate: "1.5";
90
+ };
91
+ };
92
+ readonly legend: {
93
+ readonly type: "string";
94
+ readonly title: "Legend";
95
+ readonly description: "The radio group's visible accessible name.";
96
+ readonly format: "icu-message";
97
+ readonly messageSource: "Installments";
98
+ };
99
+ readonly invalidInstallmentMessage: {
100
+ readonly type: "string";
101
+ readonly title: "Invalid installment message";
102
+ readonly description: "Shown when the picked installment plan is no longer offered.";
103
+ readonly format: "icu-message";
104
+ readonly messageSource: "This installment plan is no longer available. Choose another one.";
105
+ };
106
+ readonly missingMethodMessage: {
107
+ readonly type: "string";
108
+ readonly title: "Missing payment method message";
109
+ readonly description: "Shown when an installment plan is picked before a payment method.";
110
+ readonly format: "icu-message";
111
+ readonly messageSource: "Choose a payment method before choosing an installment plan.";
112
+ };
113
+ readonly genericErrorMessage: {
114
+ readonly type: "string";
115
+ readonly title: "Selection failure message";
116
+ readonly description: "Shown when a pick fails: a network failure or a fault the shopper cannot fix.";
117
+ readonly format: "icu-message";
118
+ readonly messageSource: "Unable to select the installment plan. Please try again.";
119
+ };
120
+ };
121
+ };
122
+ };
123
+ export type InstallmentsProps = Omit<ComponentPropsWithRef<'div'>, 'children'> & MessageLocaleProp & {
43
124
  /**
44
- * The radio group's accessible name, rendered as a visible `Fieldset.Legend` (T38, Decision 1).
45
- * Resolved through `resolveAuthoredCopy`: an authored empty or whitespace-only string falls back to
46
- * the default rather than rendering a nameless group.
125
+ * Merchant-authored copy: the row template, the interest suffixes, the legend and the error. A tier whose rate
126
+ * the order form did not state (`interestRate` and `interestFree` both `null`) gets no suffix.
47
127
  */
48
- legend?: string;
128
+ $content?: ContentValue<typeof InstallmentsContent>;
49
129
  /** `InstallmentsData` slice forwarded by the reactive runtime. */
50
130
  $data?: InstallmentsData;
51
131
  /** Compiler-injected action surface; carries `payment.setInstallments`. */
52
132
  $actions?: ComponentActions;
53
133
  };
54
134
  export declare const InstallmentsDefinition: ComponentDefinition<InstallmentsProps>;
55
- export declare function Installments({ installmentTemplate, interestFreeLabel, interestTemplate, legend, $data, $actions: $actionsProp, className, ...props }: InstallmentsProps): import("react/jsx-runtime").JSX.Element | null;
135
+ export declare function Installments({ $content, $locale, $data, $actions: $actionsProp, className, ...props }: InstallmentsProps): import("react/jsx-runtime").JSX.Element | null;
56
136
  //#endregion
57
137
  export { findInstallmentOption, resolveInstallmentTiers };
58
138
  //# sourceMappingURL=installments.d.ts.map