@vtex/faststore 0.0.8 → 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 (568) hide show
  1. package/CHANGELOG.md +101 -0
  2. package/README.md +0 -1
  3. package/dist/actions.json +48 -1
  4. package/dist/catalog.json +1397 -1594
  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 +67 -56
  13. package/dist/components.js +64 -53
  14. package/dist/content-types.json +5886 -555
  15. package/dist/core/dist/define-component.d.ts +7 -2
  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-entry-point.md +4 -4
  24. package/dist/docs/account-menu.md +16 -17
  25. package/dist/docs/account-saved-cards.md +306 -0
  26. package/dist/docs/alert-dialog.md +3 -1
  27. package/dist/docs/avatar.md +4 -2
  28. package/dist/docs/billing-address.md +99 -30
  29. package/dist/docs/binding-switcher.md +157 -0
  30. package/dist/docs/buy-button.md +7 -8
  31. package/dist/docs/card-entry.md +42 -29
  32. package/dist/docs/card-summary.md +185 -0
  33. package/dist/docs/cardholder-document.md +5 -3
  34. package/dist/docs/carousel.md +5 -4
  35. package/dist/docs/cart-destination.md +251 -0
  36. package/dist/docs/cart-item.md +48 -15
  37. package/dist/docs/cart-totalizer.md +8 -6
  38. package/dist/docs/cart.md +240 -39
  39. package/dist/docs/challenge-return.md +135 -0
  40. package/dist/docs/client-preferences-fieldset.md +10 -5
  41. package/dist/docs/client-preferences.md +31 -8
  42. package/dist/docs/client-profile-fieldset.md +20 -6
  43. package/dist/docs/client-profile.md +12 -3
  44. package/dist/docs/copy-text.md +9 -7
  45. package/dist/docs/document-field.md +1 -1
  46. package/dist/docs/email-field.md +2 -1
  47. package/dist/docs/email-identification.md +12 -2
  48. package/dist/docs/footer-copyright.md +4 -2
  49. package/dist/docs/footer-social.md +1 -1
  50. package/dist/docs/form.md +54 -18
  51. package/dist/docs/free-shipping-progress.md +18 -13
  52. package/dist/docs/identity-edit.md +8 -2
  53. package/dist/docs/identity-summary.md +18 -5
  54. package/dist/docs/incentives.md +2 -2
  55. package/dist/docs/installments.md +46 -32
  56. package/dist/docs/logo.md +1 -1
  57. package/dist/docs/my-account-profile.md +16 -11
  58. package/dist/docs/navigation-link.md +5 -3
  59. package/dist/docs/order-cancel.md +3 -1
  60. package/dist/docs/order-delivery-address.md +7 -5
  61. package/dist/docs/order-delivery-group.md +1 -3
  62. package/dist/docs/order-details-back.md +1 -1
  63. package/dist/docs/order-details-header.md +1 -4
  64. package/dist/docs/order-invoice-download.md +60 -0
  65. package/dist/docs/order-list-row.md +1 -1
  66. package/dist/docs/order-list-search.md +13 -20
  67. package/dist/docs/order-list-views.md +11 -17
  68. package/dist/docs/order-list.md +12 -5
  69. package/dist/docs/order-payment.md +9 -7
  70. package/dist/docs/order-placed-date.md +1 -1
  71. package/dist/docs/order-placed-payment-summary.md +28 -15
  72. package/dist/docs/order-placed.md +49 -14
  73. package/dist/docs/order-progress.md +1 -1
  74. package/dist/docs/order-status-badge.md +20 -9
  75. package/dist/docs/order-summary.md +2 -2
  76. package/dist/docs/order-tracking-link.md +58 -0
  77. package/dist/docs/payment-method-badges.md +32 -6
  78. package/dist/docs/payment-methods.md +2 -2
  79. package/dist/docs/payment.md +36 -17
  80. package/dist/docs/phone-field.md +4 -4
  81. package/dist/docs/place-order.md +84 -36
  82. package/dist/docs/postal-code-field.md +3 -1
  83. package/dist/docs/pricing.md +21 -23
  84. package/dist/docs/product-gallery.md +19 -20
  85. package/dist/docs/product-information.md +14 -10
  86. package/dist/docs/product-list.md +7 -6
  87. package/dist/docs/product-shelf.md +7 -1
  88. package/dist/docs/promotion.md +4 -2
  89. package/dist/docs/region.md +23 -15
  90. package/dist/docs/save-card.md +7 -6
  91. package/dist/docs/saved-cards.md +65 -36
  92. package/dist/docs/select.md +3 -4
  93. package/dist/docs/shipping-address.md +57 -21
  94. package/dist/docs/shipping-simulator.md +53 -15
  95. package/dist/docs/sign-in-disclosure.md +176 -0
  96. package/dist/docs/sign-in-form.md +78 -47
  97. package/dist/docs/sign-in-redirect.md +5 -3
  98. package/dist/docs/sign-in.md +173 -0
  99. package/dist/docs/toast.md +45 -16
  100. package/dist/docs/variant-selector.md +15 -11
  101. package/dist/graphql/types.d.ts +4 -14
  102. package/dist/index.d.ts +3 -2
  103. package/dist/internal/client.d.ts +4 -3
  104. package/dist/internal/client.js +5 -2
  105. package/dist/internal/server.d.ts +10 -5
  106. package/dist/internal/server.js +9 -4
  107. package/dist/matter/access-code-sign-in/access-code-sign-in.d.ts +250 -66
  108. package/dist/matter/access-code-sign-in/access-code-sign-in.js +459 -188
  109. package/dist/matter/access-code-sign-in/access-code-sign-in.js.map +1 -1
  110. package/dist/matter/account-address-book/account-address-book-delete.d.ts +78 -40
  111. package/dist/matter/account-address-book/account-address-book-delete.js +86 -50
  112. package/dist/matter/account-address-book/account-address-book-delete.js.map +1 -1
  113. package/dist/matter/account-address-book/account-address-book-deliverability.d.ts +21 -4
  114. package/dist/matter/account-address-book/account-address-book-deliverability.js +45 -17
  115. package/dist/matter/account-address-book/account-address-book-deliverability.js.map +1 -1
  116. package/dist/matter/account-address-book/account-address-book-form-parts.d.ts +74 -19
  117. package/dist/matter/account-address-book/account-address-book-form-parts.js +77 -26
  118. package/dist/matter/account-address-book/account-address-book-form-parts.js.map +1 -1
  119. package/dist/matter/account-address-book/account-address-book-profile-notice.d.ts +27 -6
  120. package/dist/matter/account-address-book/account-address-book-profile-notice.js +55 -28
  121. package/dist/matter/account-address-book/account-address-book-profile-notice.js.map +1 -1
  122. package/dist/matter/account-address-book/account-address-book.d.ts +67 -14
  123. package/dist/matter/account-address-book/account-address-book.js +74 -33
  124. package/dist/matter/account-address-book/account-address-book.js.map +1 -1
  125. package/dist/matter/account-address-book/account-address-country-switch.js +3 -3
  126. package/dist/matter/account-address-book/account-address-country-switch.js.map +1 -1
  127. package/dist/matter/account-address-book/account-address-country.d.ts +66 -20
  128. package/dist/matter/account-address-book/account-address-country.js +83 -49
  129. package/dist/matter/account-address-book/account-address-country.js.map +1 -1
  130. package/dist/matter/account-address-book/account-address-form-context.d.ts +8 -4
  131. package/dist/matter/account-address-book/account-address-form-context.js.map +1 -1
  132. package/dist/matter/account-address-book/account-address-form.d.ts +468 -45
  133. package/dist/matter/account-address-book/account-address-form.js +518 -155
  134. package/dist/matter/account-address-book/account-address-form.js.map +1 -1
  135. package/dist/matter/account-address-book/account-address-record.d.ts +27 -6
  136. package/dist/matter/account-address-book/account-address-record.js +32 -17
  137. package/dist/matter/account-address-book/account-address-record.js.map +1 -1
  138. package/dist/matter/account-menu/account-menu.d.ts +34 -17
  139. package/dist/matter/account-menu/account-menu.js +46 -54
  140. package/dist/matter/account-menu/account-menu.js.map +1 -1
  141. package/dist/matter/account-menu-identity/account-menu-identity.js +1 -1
  142. package/dist/matter/account-saved-cards/account-saved-cards.d.ts +463 -0
  143. package/dist/matter/account-saved-cards/account-saved-cards.js +1011 -0
  144. package/dist/matter/account-saved-cards/account-saved-cards.js.map +1 -0
  145. package/dist/matter/billing-address/billing-address.d.ts +156 -74
  146. package/dist/matter/billing-address/billing-address.js +227 -156
  147. package/dist/matter/billing-address/billing-address.js.map +1 -1
  148. package/dist/matter/breadcrumb/breadcrumb.d.ts +21 -3
  149. package/dist/matter/breadcrumb/breadcrumb.js +24 -9
  150. package/dist/matter/breadcrumb/breadcrumb.js.map +1 -1
  151. package/dist/matter/buy-button/buy-button.d.ts +8 -11
  152. package/dist/matter/buy-button/buy-button.js +10 -19
  153. package/dist/matter/buy-button/buy-button.js.map +1 -1
  154. package/dist/matter/card-entry/card-capture.js +12 -4
  155. package/dist/matter/card-entry/card-capture.js.map +1 -1
  156. package/dist/matter/card-entry/card-entry.d.ts +123 -32
  157. package/dist/matter/card-entry/card-entry.js +348 -221
  158. package/dist/matter/card-entry/card-entry.js.map +1 -1
  159. package/dist/matter/cart/cart-namespace.d.ts +11 -1
  160. package/dist/matter/cart/cart-namespace.js +11 -1
  161. package/dist/matter/cart/cart-namespace.js.map +1 -1
  162. package/dist/matter/cart/cart.d.ts +416 -45
  163. package/dist/matter/cart/cart.js +782 -101
  164. package/dist/matter/cart/cart.js.map +1 -1
  165. package/dist/matter/cart-destination/cart-destination.d.ts +233 -0
  166. package/dist/matter/cart-destination/cart-destination.js +703 -0
  167. package/dist/matter/cart-destination/cart-destination.js.map +1 -0
  168. package/dist/matter/cart-item/cart-item.d.ts +145 -16
  169. package/dist/matter/cart-item/cart-item.js +230 -54
  170. package/dist/matter/cart-item/cart-item.js.map +1 -1
  171. package/dist/matter/cart-item-compositions/cart-item-compositions.js +1 -1
  172. package/dist/matter/cart-item-compositions/cart-item-compositions.js.map +1 -1
  173. package/dist/matter/cart-item-customizations/cart-item-customizations.js +1 -1
  174. package/dist/matter/cart-item-customizations/cart-item-customizations.js.map +1 -1
  175. package/dist/matter/cart-item-discounts/cart-item-discounts.js +1 -1
  176. package/dist/matter/cart-item-discounts/cart-item-discounts.js.map +1 -1
  177. package/dist/matter/cart-item-seller-info/cart-item-seller-info.js +1 -1
  178. package/dist/matter/cart-item-seller-info/cart-item-seller-info.js.map +1 -1
  179. package/dist/matter/cart-item-variations/cart-item-variations.js +1 -1
  180. package/dist/matter/cart-item-variations/cart-item-variations.js.map +1 -1
  181. package/dist/matter/cart-totalizer/cart-totalizer.d.ts +43 -9
  182. package/dist/matter/cart-totalizer/cart-totalizer.js +49 -19
  183. package/dist/matter/cart-totalizer/cart-totalizer.js.map +1 -1
  184. package/dist/matter/challenge-return/challenge-return.d.ts +62 -0
  185. package/dist/matter/challenge-return/challenge-return.js +241 -0
  186. package/dist/matter/challenge-return/challenge-return.js.map +1 -0
  187. package/dist/matter/client-preferences/client-preferences-fieldset.d.ts +86 -17
  188. package/dist/matter/client-preferences/client-preferences-fieldset.js +126 -54
  189. package/dist/matter/client-preferences/client-preferences-fieldset.js.map +1 -1
  190. package/dist/matter/client-preferences/client-preferences.d.ts +50 -7
  191. package/dist/matter/client-preferences/client-preferences.js +84 -15
  192. package/dist/matter/client-preferences/client-preferences.js.map +1 -1
  193. package/dist/matter/client-profile/client-profile.d.ts +44 -9
  194. package/dist/matter/client-profile/client-profile.js +64 -24
  195. package/dist/matter/client-profile/client-profile.js.map +1 -1
  196. package/dist/matter/client-profile-form/client-profile-fieldset.d.ts +119 -22
  197. package/dist/matter/client-profile-form/client-profile-fieldset.js +161 -73
  198. package/dist/matter/client-profile-form/client-profile-fieldset.js.map +1 -1
  199. package/dist/matter/delivery-options/delivery-options-accordion.d.ts +49 -4
  200. package/dist/matter/delivery-options/delivery-options-accordion.js +67 -14
  201. package/dist/matter/delivery-options/delivery-options-accordion.js.map +1 -1
  202. package/dist/matter/delivery-options/delivery-options-controller.d.ts +69 -9
  203. package/dist/matter/delivery-options/delivery-options-controller.js +80 -14
  204. package/dist/matter/delivery-options/delivery-options-controller.js.map +1 -1
  205. package/dist/matter/delivery-options/delivery-options.d.ts +37 -2
  206. package/dist/matter/delivery-options/delivery-options.js +75 -12
  207. package/dist/matter/delivery-options/delivery-options.js.map +1 -1
  208. package/dist/matter/delivery-options/use-delivery-option-selection.d.ts +1 -0
  209. package/dist/matter/delivery-options/use-delivery-option-selection.js +1 -1
  210. package/dist/matter/delivery-options/use-delivery-option-selection.js.map +1 -1
  211. package/dist/matter/email-identification/email-identification.d.ts +25 -3
  212. package/dist/matter/email-identification/email-identification.js +49 -12
  213. package/dist/matter/email-identification/email-identification.js.map +1 -1
  214. package/dist/matter/free-shipping-progress/free-shipping-progress.d.ts +85 -10
  215. package/dist/matter/free-shipping-progress/free-shipping-progress.js +153 -53
  216. package/dist/matter/free-shipping-progress/free-shipping-progress.js.map +1 -1
  217. package/dist/matter/identity-edit/identity-edit.d.ts +52 -10
  218. package/dist/matter/identity-edit/identity-edit.js +47 -19
  219. package/dist/matter/identity-edit/identity-edit.js.map +1 -1
  220. package/dist/matter/identity-summary/identity-summary.d.ts +76 -22
  221. package/dist/matter/identity-summary/identity-summary.js +95 -45
  222. package/dist/matter/identity-summary/identity-summary.js.map +1 -1
  223. package/dist/matter/installments/installments-select.d.ts +98 -16
  224. package/dist/matter/installments/installments-select.js +156 -48
  225. package/dist/matter/installments/installments-select.js.map +1 -1
  226. package/dist/matter/installments/installments.d.ts +96 -16
  227. package/dist/matter/installments/installments.js +115 -40
  228. package/dist/matter/installments/installments.js.map +1 -1
  229. package/dist/matter/installments/use-installments-selection.d.ts +1 -0
  230. package/dist/matter/installments/use-installments-selection.js +8 -3
  231. package/dist/matter/installments/use-installments-selection.js.map +1 -1
  232. package/dist/matter/my-account-profile/my-account-profile.d.ts +358 -103
  233. package/dist/matter/my-account-profile/my-account-profile.js +370 -174
  234. package/dist/matter/my-account-profile/my-account-profile.js.map +1 -1
  235. package/dist/matter/order-cancel/order-cancel.d.ts +65 -19
  236. package/dist/matter/order-cancel/order-cancel.js +118 -51
  237. package/dist/matter/order-cancel/order-cancel.js.map +1 -1
  238. package/dist/matter/order-delivery-address/order-delivery-address.d.ts +8 -18
  239. package/dist/matter/order-delivery-address/order-delivery-address.js +14 -23
  240. package/dist/matter/order-delivery-address/order-delivery-address.js.map +1 -1
  241. package/dist/matter/order-delivery-group/order-delivery-group.d.ts +40 -24
  242. package/dist/matter/order-delivery-group/order-delivery-group.js +64 -74
  243. package/dist/matter/order-delivery-group/order-delivery-group.js.map +1 -1
  244. package/dist/matter/order-details-header/order-details-header.d.ts +32 -15
  245. package/dist/matter/order-details-header/order-details-header.js +66 -58
  246. package/dist/matter/order-details-header/order-details-header.js.map +1 -1
  247. package/dist/matter/order-invoice-download/order-invoice-download.d.ts +78 -0
  248. package/dist/matter/order-invoice-download/order-invoice-download.js +173 -0
  249. package/dist/matter/order-invoice-download/order-invoice-download.js.map +1 -0
  250. package/dist/matter/order-list/order-list.d.ts +164 -19
  251. package/dist/matter/order-list/order-list.js +229 -87
  252. package/dist/matter/order-list/order-list.js.map +1 -1
  253. package/dist/matter/order-list-row/order-list-row.d.ts +6 -1
  254. package/dist/matter/order-list-row/order-list-row.js +3 -2
  255. package/dist/matter/order-list-row/order-list-row.js.map +1 -1
  256. package/dist/matter/order-list-search/order-list-search.d.ts +18 -26
  257. package/dist/matter/order-list-search/order-list-search.js +30 -69
  258. package/dist/matter/order-list-search/order-list-search.js.map +1 -1
  259. package/dist/matter/order-list-views/order-list-views.d.ts +15 -22
  260. package/dist/matter/order-list-views/order-list-views.js +22 -68
  261. package/dist/matter/order-list-views/order-list-views.js.map +1 -1
  262. package/dist/matter/order-payment/order-payment.d.ts +33 -10
  263. package/dist/matter/order-payment/order-payment.js +44 -39
  264. package/dist/matter/order-payment/order-payment.js.map +1 -1
  265. package/dist/matter/order-placed/order-placed-deliveries.d.ts +144 -12
  266. package/dist/matter/order-placed/order-placed-deliveries.js +115 -40
  267. package/dist/matter/order-placed/order-placed-deliveries.js.map +1 -1
  268. package/dist/matter/order-placed/order-placed.d.ts +198 -31
  269. package/dist/matter/order-placed/order-placed.js +230 -139
  270. package/dist/matter/order-placed/order-placed.js.map +1 -1
  271. package/dist/matter/order-placed-date/order-placed-date.d.ts +5 -8
  272. package/dist/matter/order-placed-date/order-placed-date.js +7 -8
  273. package/dist/matter/order-placed-date/order-placed-date.js.map +1 -1
  274. package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.d.ts +90 -17
  275. package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js +93 -117
  276. package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js.map +1 -1
  277. package/dist/matter/order-progress/order-progress.d.ts +19 -8
  278. package/dist/matter/order-progress/order-progress.js +37 -45
  279. package/dist/matter/order-progress/order-progress.js.map +1 -1
  280. package/dist/matter/order-summary/order-summary.d.ts +19 -9
  281. package/dist/matter/order-summary/order-summary.js +38 -44
  282. package/dist/matter/order-summary/order-summary.js.map +1 -1
  283. package/dist/matter/order-tracking-link/order-tracking-link.d.ts +43 -0
  284. package/dist/matter/order-tracking-link/order-tracking-link.js +107 -0
  285. package/dist/matter/order-tracking-link/order-tracking-link.js.map +1 -0
  286. package/dist/matter/payment/payment-card-capture.js +17 -10
  287. package/dist/matter/payment/payment-card-capture.js.map +1 -1
  288. package/dist/matter/payment/payment-controller.d.ts +4 -2
  289. package/dist/matter/payment/payment-controller.js +30 -9
  290. package/dist/matter/payment/payment-controller.js.map +1 -1
  291. package/dist/matter/payment/payment-method-badges.js +1 -1
  292. package/dist/matter/payment/payment.d.ts +69 -19
  293. package/dist/matter/payment/payment.js +101 -35
  294. package/dist/matter/payment/payment.js.map +1 -1
  295. package/dist/matter/payment/use-payment-method-selection.d.ts +25 -4
  296. package/dist/matter/payment/use-payment-method-selection.js +94 -32
  297. package/dist/matter/payment/use-payment-method-selection.js.map +1 -1
  298. package/dist/matter/payment/use-payment-submit-gate.d.ts +14 -3
  299. package/dist/matter/payment/use-payment-submit-gate.js +47 -8
  300. package/dist/matter/payment/use-payment-submit-gate.js.map +1 -1
  301. package/dist/matter/place-order/place-order.d.ts +171 -57
  302. package/dist/matter/place-order/place-order.js +376 -185
  303. package/dist/matter/place-order/place-order.js.map +1 -1
  304. package/dist/matter/pricing/pricing.d.ts +152 -13
  305. package/dist/matter/pricing/pricing.js +153 -52
  306. package/dist/matter/pricing/pricing.js.map +1 -1
  307. package/dist/matter/product-information/product-information.d.ts +27 -4
  308. package/dist/matter/product-information/product-information.js +32 -15
  309. package/dist/matter/product-information/product-information.js.map +1 -1
  310. package/dist/matter/product-list/product-list.d.ts +24 -6
  311. package/dist/matter/product-list/product-list.js +32 -26
  312. package/dist/matter/product-list/product-list.js.map +1 -1
  313. package/dist/matter/product-shelf/product-shelf.d.ts +8 -3
  314. package/dist/matter/product-shelf/product-shelf.js +111 -10
  315. package/dist/matter/product-shelf/product-shelf.js.map +1 -1
  316. package/dist/matter/region/region.d.ts +33 -16
  317. package/dist/matter/region/region.js +59 -52
  318. package/dist/matter/region/region.js.map +1 -1
  319. package/dist/matter/save-card/save-card.d.ts +43 -8
  320. package/dist/matter/save-card/save-card.js +61 -23
  321. package/dist/matter/save-card/save-card.js.map +1 -1
  322. package/dist/matter/saved-cards/saved-cards.d.ts +113 -21
  323. package/dist/matter/saved-cards/saved-cards.js +349 -77
  324. package/dist/matter/saved-cards/saved-cards.js.map +1 -1
  325. package/dist/matter/shipping-address/address-payload.js +25 -0
  326. package/dist/matter/shipping-address/address-payload.js.map +1 -0
  327. package/dist/matter/shipping-address/country-descriptors.js +71 -71
  328. package/dist/matter/shipping-address/country-descriptors.js.map +1 -1
  329. package/dist/matter/shipping-address/library-country-descriptors.js +136 -0
  330. package/dist/matter/shipping-address/library-country-descriptors.js.map +1 -0
  331. package/dist/matter/shipping-address/shipping-address.d.ts +312 -45
  332. package/dist/matter/shipping-address/shipping-address.js +443 -188
  333. package/dist/matter/shipping-address/shipping-address.js.map +1 -1
  334. package/dist/matter/shipping-simulator/shipping-simulator.d.ts +251 -25
  335. package/dist/matter/shipping-simulator/shipping-simulator.js +261 -51
  336. package/dist/matter/shipping-simulator/shipping-simulator.js.map +1 -1
  337. package/dist/matter/sign-in/sign-in.d.ts +108 -0
  338. package/dist/matter/sign-in/sign-in.js +285 -0
  339. package/dist/matter/sign-in/sign-in.js.map +1 -0
  340. package/dist/matter/sign-in-disclosure/sign-in-disclosure.d.ts +81 -0
  341. package/dist/matter/sign-in-disclosure/sign-in-disclosure.js +232 -0
  342. package/dist/matter/sign-in-disclosure/sign-in-disclosure.js.map +1 -0
  343. package/dist/matter/sign-in-form/sign-in-form.d.ts +93 -62
  344. package/dist/matter/sign-in-form/sign-in-form.js +134 -144
  345. package/dist/matter/sign-in-form/sign-in-form.js.map +1 -1
  346. package/dist/particles/binding-switcher/binding-switcher.d.ts +59 -0
  347. package/dist/particles/binding-switcher/binding-switcher.js +194 -0
  348. package/dist/particles/binding-switcher/binding-switcher.js.map +1 -0
  349. package/dist/particles/card-summary/card-network.d.ts +17 -0
  350. package/dist/particles/card-summary/card-network.js +25 -0
  351. package/dist/particles/card-summary/card-network.js.map +1 -0
  352. package/dist/particles/card-summary/card-summary.d.ts +113 -0
  353. package/dist/particles/card-summary/card-summary.js +221 -0
  354. package/dist/particles/card-summary/card-summary.js.map +1 -0
  355. package/dist/particles/carousel/carousel.d.ts +99 -11
  356. package/dist/particles/carousel/carousel.js +103 -35
  357. package/dist/particles/carousel/carousel.js.map +1 -1
  358. package/dist/particles/copy-text/copy-text.js +5 -15
  359. package/dist/particles/copy-text/copy-text.js.map +1 -1
  360. package/dist/particles/dialog/dialog.d.ts +14 -6
  361. package/dist/particles/dialog/dialog.js +6 -3
  362. package/dist/particles/dialog/dialog.js.map +1 -1
  363. package/dist/particles/drawer/drawer.js +1 -1
  364. package/dist/particles/drawer/drawer.js.map +1 -1
  365. package/dist/particles/email-field/email-field.d.ts +2 -1
  366. package/dist/particles/email-field/email-field.js +2 -1
  367. package/dist/particles/email-field/email-field.js.map +1 -1
  368. package/dist/particles/footer-link-group/footer-link-group.js +1 -0
  369. package/dist/particles/footer-link-group/footer-link-group.js.map +1 -1
  370. package/dist/particles/footer-social/footer-social.d.ts +1 -1
  371. package/dist/particles/footer-social/footer-social.js +1 -1
  372. package/dist/particles/footer-social/footer-social.js.map +1 -1
  373. package/dist/particles/form/form.d.ts +85 -13
  374. package/dist/particles/form/form.js +91 -42
  375. package/dist/particles/form/form.js.map +1 -1
  376. package/dist/particles/gallery/gallery.d.ts +129 -12
  377. package/dist/particles/gallery/gallery.js +121 -34
  378. package/dist/particles/gallery/gallery.js.map +1 -1
  379. package/dist/particles/incentives/incentives.d.ts +1 -1
  380. package/dist/particles/incentives/incentives.js +1 -1
  381. package/dist/particles/incentives/incentives.js.map +1 -1
  382. package/dist/particles/order-details-back/order-details-back.d.ts +5 -3
  383. package/dist/particles/order-details-back/order-details-back.js +8 -10
  384. package/dist/particles/order-details-back/order-details-back.js.map +1 -1
  385. package/dist/particles/order-status-badge/order-status-badge.d.ts +3 -3
  386. package/dist/particles/order-status-badge/order-status-badge.js +4 -20
  387. package/dist/particles/order-status-badge/order-status-badge.js.map +1 -1
  388. package/dist/particles/password-field/password-field.d.ts +1 -1
  389. package/dist/particles/password-field/password-field.js +2 -4
  390. package/dist/particles/password-field/password-field.js.map +1 -1
  391. package/dist/particles/payment-methods/payment-methods.d.ts +1 -1
  392. package/dist/particles/payment-methods/payment-methods.js +1 -1
  393. package/dist/particles/payment-methods/payment-methods.js.map +1 -1
  394. package/dist/particles/phone-field/phone-field.d.ts +4 -4
  395. package/dist/particles/phone-field/phone-field.js +8 -11
  396. package/dist/particles/phone-field/phone-field.js.map +1 -1
  397. package/dist/particles/spinner/spinner.d.ts +24 -4
  398. package/dist/particles/spinner/spinner.js +25 -9
  399. package/dist/particles/spinner/spinner.js.map +1 -1
  400. package/dist/particles/switch/switch.d.ts +4 -1
  401. package/dist/particles/switch/switch.js +3 -1
  402. package/dist/particles/switch/switch.js.map +1 -1
  403. package/dist/particles/toast/toast.d.ts +49 -9
  404. package/dist/particles/toast/toast.js +81 -15
  405. package/dist/particles/toast/toast.js.map +1 -1
  406. package/dist/schema.graphql +461 -89
  407. package/dist/sdk/actions/index.d.ts +3 -1
  408. package/dist/sdk/actions/index.js +3 -1
  409. package/dist/sdk/actions/locale-action-provider.d.ts +16 -0
  410. package/dist/sdk/actions/locale-action-provider.js +20 -0
  411. package/dist/sdk/actions/locale-action-provider.js.map +1 -0
  412. package/dist/sdk/actions/saved-card-action-provider.d.ts +12 -0
  413. package/dist/sdk/actions/saved-card-action-provider.js +16 -0
  414. package/dist/sdk/actions/saved-card-action-provider.js.map +1 -0
  415. package/dist/sdk/actions/types.d.ts +6 -2
  416. package/dist/sdk/address/address-fields.js +4 -4
  417. package/dist/sdk/address/address-fields.js.map +1 -1
  418. package/dist/sdk/address/constants.js +1 -6
  419. package/dist/sdk/address/constants.js.map +1 -1
  420. package/dist/sdk/address/messages.js +44 -44
  421. package/dist/sdk/address/messages.js.map +1 -1
  422. package/dist/sdk/address/postal-code.js +15 -2
  423. package/dist/sdk/address/postal-code.js.map +1 -1
  424. package/dist/sdk/address/types.d.ts +5 -3
  425. package/dist/sdk/address/validate-address.js +3 -3
  426. package/dist/sdk/address/validate-address.js.map +1 -1
  427. package/dist/sdk/analytics/use-analytics-actions.d.ts +1 -1
  428. package/dist/sdk/analytics/use-analytics-actions.js.map +1 -1
  429. package/dist/sdk/cache/storefront-cache.js +2 -1
  430. package/dist/sdk/cache/storefront-cache.js.map +1 -1
  431. package/dist/sdk/cart/operations.d.ts +2 -1
  432. package/dist/sdk/cart/operations.js +55 -1
  433. package/dist/sdk/cart/operations.js.map +1 -1
  434. package/dist/sdk/cart/optimistic.d.ts +30 -7
  435. package/dist/sdk/cart/optimistic.js +78 -41
  436. package/dist/sdk/cart/optimistic.js.map +1 -1
  437. package/dist/sdk/cart/use-cart-actions.d.ts +7 -0
  438. package/dist/sdk/cart/use-cart-actions.js +61 -15
  439. package/dist/sdk/cart/use-cart-actions.js.map +1 -1
  440. package/dist/sdk/cart/use-cart-sync-sales-channel.js +70 -0
  441. package/dist/sdk/cart/use-cart-sync-sales-channel.js.map +1 -0
  442. package/dist/sdk/data/index.js +2 -2
  443. package/dist/sdk/data/reactive-list-item-data-provider.js +2 -2
  444. package/dist/sdk/generated/gql.js +16 -12
  445. package/dist/sdk/generated/gql.js.map +1 -1
  446. package/dist/sdk/generated/graphql.d.ts +197 -51
  447. package/dist/sdk/generated/graphql.js +2318 -91
  448. package/dist/sdk/generated/graphql.js.map +1 -1
  449. package/dist/sdk/i18n/format-error-code.js +23 -0
  450. package/dist/sdk/i18n/format-error-code.js.map +1 -0
  451. package/dist/sdk/i18n/message-formatter.d.ts +22 -0
  452. package/dist/sdk/i18n/message-formatter.js +140 -0
  453. package/dist/sdk/i18n/message-formatter.js.map +1 -0
  454. package/dist/sdk/i18n/use-message-formatter.d.ts +8 -0
  455. package/dist/sdk/i18n/use-message-formatter.js +18 -0
  456. package/dist/sdk/i18n/use-message-formatter.js.map +1 -0
  457. package/dist/sdk/identity/use-identity-actions.js.map +1 -1
  458. package/dist/sdk/locale/binding-switch-provider.d.ts +13 -0
  459. package/dist/sdk/locale/binding-switch-provider.js +20 -0
  460. package/dist/sdk/locale/binding-switch-provider.js.map +1 -0
  461. package/dist/sdk/locale/use-locale-actions.d.ts +16 -0
  462. package/dist/sdk/locale/use-locale-actions.js +70 -0
  463. package/dist/sdk/locale/use-locale-actions.js.map +1 -0
  464. package/dist/sdk/navigation/binding-switch.d.ts +39 -0
  465. package/dist/sdk/navigation/binding-switch.js +129 -0
  466. package/dist/sdk/navigation/binding-switch.js.map +1 -0
  467. package/dist/sdk/navigation/decode-route-params.d.ts +11 -0
  468. package/dist/sdk/navigation/decode-route-params.js +32 -0
  469. package/dist/sdk/navigation/decode-route-params.js.map +1 -0
  470. package/dist/sdk/navigation/redirect.d.ts +2 -0
  471. package/dist/sdk/navigation/redirect.js +19 -1
  472. package/dist/sdk/navigation/redirect.js.map +1 -1
  473. package/dist/sdk/navigation/types.d.ts +13 -0
  474. package/dist/sdk/payment/bin-format.js +20 -0
  475. package/dist/sdk/payment/bin-format.js.map +1 -0
  476. package/dist/sdk/payment/challenge-return.js +37 -0
  477. package/dist/sdk/payment/challenge-return.js.map +1 -0
  478. package/dist/sdk/payment/confirmation-last-four.js +39 -0
  479. package/dist/sdk/payment/confirmation-last-four.js.map +1 -0
  480. package/dist/sdk/payment/gateway.d.ts +1 -1
  481. package/dist/sdk/payment/gateway.js +8 -2
  482. package/dist/sdk/payment/gateway.js.map +1 -1
  483. package/dist/sdk/payment/operations.d.ts +1 -0
  484. package/dist/sdk/payment/operations.js +28 -6
  485. package/dist/sdk/payment/operations.js.map +1 -1
  486. package/dist/sdk/payment/resumed-purchase.d.ts +1 -0
  487. package/dist/sdk/payment/resumed-purchase.js +119 -0
  488. package/dist/sdk/payment/resumed-purchase.js.map +1 -0
  489. package/dist/sdk/payment/security-code-mask.js +16 -23
  490. package/dist/sdk/payment/security-code-mask.js.map +1 -1
  491. package/dist/sdk/payment/submission-registry.js +6 -2
  492. package/dist/sdk/payment/submission-registry.js.map +1 -1
  493. package/dist/sdk/payment/use-payment-actions.d.ts +18 -3
  494. package/dist/sdk/payment/use-payment-actions.js +23 -3
  495. package/dist/sdk/payment/use-payment-actions.js.map +1 -1
  496. package/dist/sdk/payment/use-place-order.d.ts +10 -2
  497. package/dist/sdk/payment/use-place-order.js +138 -76
  498. package/dist/sdk/payment/use-place-order.js.map +1 -1
  499. package/dist/sdk/provider/storefront-provider.d.ts +1 -7
  500. package/dist/sdk/provider/storefront-provider.js +4 -11
  501. package/dist/sdk/provider/storefront-provider.js.map +1 -1
  502. package/dist/sdk/saved-cards/operations.d.ts +16 -0
  503. package/dist/sdk/saved-cards/operations.js +41 -0
  504. package/dist/sdk/saved-cards/operations.js.map +1 -0
  505. package/dist/sdk/saved-cards/use-saved-card-actions.d.ts +26 -0
  506. package/dist/sdk/saved-cards/use-saved-card-actions.js +86 -0
  507. package/dist/sdk/saved-cards/use-saved-card-actions.js.map +1 -0
  508. package/dist/sdk/seo/entity-landing.d.ts +24 -0
  509. package/dist/sdk/seo/entity-landing.js +30 -0
  510. package/dist/sdk/seo/entity-landing.js.map +1 -0
  511. package/dist/sdk/seo/page-alternates.d.ts +8 -5
  512. package/dist/sdk/seo/page-alternates.js +11 -14
  513. package/dist/sdk/seo/page-alternates.js.map +1 -1
  514. package/dist/sdk/seo/search-landing.d.ts +42 -0
  515. package/dist/sdk/seo/search-landing.js +85 -0
  516. package/dist/sdk/seo/search-landing.js.map +1 -0
  517. package/dist/sdk/session/mock-session.d.ts +9 -0
  518. package/dist/sdk/session/mock-session.js +31 -0
  519. package/dist/sdk/session/mock-session.js.map +1 -0
  520. package/dist/sdk/session/read-server-session.d.ts +3 -0
  521. package/dist/sdk/session/read-server-session.js +5 -0
  522. package/dist/sdk/session/read-server-session.js.map +1 -1
  523. package/dist/sdk/session/return-path-segment.d.ts +10 -0
  524. package/dist/sdk/session/return-path-segment.js +15 -0
  525. package/dist/sdk/session/return-path-segment.js.map +1 -0
  526. package/dist/sdk/session/use-session-actions.js.map +1 -1
  527. package/dist/sdk/shipping/shipping-operations.d.ts +1 -1
  528. package/dist/sdk/shipping/shipping-operations.js +13 -0
  529. package/dist/sdk/shipping/shipping-operations.js.map +1 -1
  530. package/dist/sdk/shipping/use-cart-shipping-simulation.js.map +1 -1
  531. package/dist/sdk/shipping/use-shipping-actions.js.map +1 -1
  532. package/dist/sdk/shipping/use-shipping-simulation.js.map +1 -1
  533. package/dist/sdk/state/cart.d.ts +9 -2
  534. package/dist/sdk/state/cart.js +9 -2
  535. package/dist/sdk/state/cart.js.map +1 -1
  536. package/dist/utils/safe-href.d.ts +2 -0
  537. package/package.json +4 -3
  538. package/skills/storefront-asset/SKILL.md +2 -2
  539. package/skills/storefront-asset/references/api-side.md +27 -14
  540. package/skills/storefront-asset/references/findings.md +5 -2
  541. package/src/styles/tailwind.css +9 -2
  542. package/dist/matter/shipping-address/country-descriptors.d.ts +0 -1
  543. package/dist/message-locales.json +0 -7
  544. package/dist/sdk/i18n/client.d.ts +0 -4
  545. package/dist/sdk/i18n/client.js +0 -4
  546. package/dist/sdk/i18n/locales.d.ts +0 -8
  547. package/dist/sdk/i18n/locales.js +0 -57
  548. package/dist/sdk/i18n/locales.js.map +0 -1
  549. package/dist/sdk/i18n/messages/en-US.js +0 -164
  550. package/dist/sdk/i18n/messages/en-US.js.map +0 -1
  551. package/dist/sdk/i18n/messages/en-US.json +0 -159
  552. package/dist/sdk/i18n/messages/en-US.json.d.ts +0 -163
  553. package/dist/sdk/i18n/messages/es-ES.js +0 -164
  554. package/dist/sdk/i18n/messages/es-ES.js.map +0 -1
  555. package/dist/sdk/i18n/messages/es-ES.json +0 -159
  556. package/dist/sdk/i18n/messages/pt-BR.js +0 -164
  557. package/dist/sdk/i18n/messages/pt-BR.js.map +0 -1
  558. package/dist/sdk/i18n/messages/pt-BR.json +0 -159
  559. package/dist/sdk/i18n/provider.d.ts +0 -1
  560. package/dist/sdk/i18n/provider.js +0 -30
  561. package/dist/sdk/i18n/provider.js.map +0 -1
  562. package/dist/sdk/i18n/server.d.ts +0 -28
  563. package/dist/sdk/i18n/server.js +0 -59
  564. package/dist/sdk/i18n/server.js.map +0 -1
  565. package/dist/utils/resolve-authored-copy.js +0 -18
  566. package/dist/utils/resolve-authored-copy.js.map +0 -1
  567. package/dist/utils/substitute-template.js +0 -33
  568. package/dist/utils/substitute-template.js.map +0 -1
@@ -0,0 +1,157 @@
1
+ # BindingSwitcher
2
+
3
+ **Category:** action
4
+ **Purpose:** Lists the store's bindings and starts a binding switch (locale, currency, and sales channel) through `locale.set`.
5
+
6
+ ---
7
+
8
+ ## Visual cues (how to identify in an image)
9
+
10
+ A closed dropdown whose visible value is a language name, a chevron, and sometimes one short sentence in a status line. The image is the source of truth for layout.
11
+
12
+ ---
13
+
14
+ ## When to use
15
+
16
+ A store that declares two or more bindings and wants the shopper to switch the whole binding. Pass `bindings` as `$data.Global.localization.bindings`. With fewer than two counted bindings the component renders nothing.
17
+
18
+ ## When NOT to use
19
+
20
+ - A country list, a currency picker, or a CMS language field.
21
+ - A store with one binding. It renders nothing and should not reserve an empty control.
22
+
23
+ ---
24
+
25
+ ## Composition
26
+
27
+ The schema tree is one node. `BindingSwitcher` has no children. The `Select` parts are internal and are not schema children.
28
+
29
+ ```
30
+ BindingSwitcher
31
+ ```
32
+
33
+ ---
34
+
35
+ ## Components
36
+
37
+ ### BindingSwitcher
38
+
39
+ Renders a host `div` (`data-fs-binding-switcher`). No fragment. Declares `actions: { locale: ['set'] }`. Choosing another binding calls `$actions.locale.set({ bindingId })`.
40
+
41
+ | Prop | Type | Default | Notes |
42
+ |------|------|---------|-------|
43
+ | `bindings` | object | — | `foundation.json` `localization.bindings`, keyed by binding id. No library default. The store passes `$data.Global.localization.bindings`. |
44
+
45
+ Copy comes from `$content` (content type `binding-switcher`):
46
+
47
+ - **`label`:** the accessible name, rendered as the select label.
48
+ - **`notice`:** shown when the page loaded with `fs_notice=no-equivalent`. Inline `<output>` (implicit `status` role).
49
+
50
+ ---
51
+
52
+ ## Canonical schema example
53
+
54
+ ```json
55
+ {
56
+ "binding-switcher": {
57
+ "type": "BindingSwitcher",
58
+ "props": {
59
+ "bindings": "$data.Global.localization.bindings"
60
+ },
61
+ "style": [
62
+ "flex",
63
+ "flex-col",
64
+ "gap-2",
65
+ "text-[14px]",
66
+ "[&_[data-fs-binding-switcher-notice]]:text-[13px]",
67
+ "[&_[data-fs-select-trigger]]:inline-flex",
68
+ "[&_[data-fs-select-trigger]]:items-center",
69
+ "[&_[data-fs-select-trigger]]:gap-2",
70
+ "[&_[data-fs-select-trigger]]:rounded-md",
71
+ "[&_[data-fs-select-trigger]]:border",
72
+ "[&_[data-fs-select-trigger]]:border-neutral-300",
73
+ "[&_[data-fs-select-trigger]]:bg-white",
74
+ "[&_[data-fs-select-trigger]]:px-3",
75
+ "[&_[data-fs-select-trigger]]:py-1.5",
76
+ "[&_[data-fs-select-positioner]]:z-50",
77
+ "[&_[data-fs-select-popup]]:min-w-[var(--anchor-width)]",
78
+ "[&_[data-fs-select-popup]]:overflow-hidden",
79
+ "[&_[data-fs-select-popup]]:rounded-md",
80
+ "[&_[data-fs-select-popup]]:border",
81
+ "[&_[data-fs-select-popup]]:border-neutral-200",
82
+ "[&_[data-fs-select-popup]]:bg-white",
83
+ "[&_[data-fs-select-popup]]:shadow-lg",
84
+ "[&_[data-fs-select-list]]:py-1",
85
+ "[&_[data-fs-select-item]]:cursor-pointer",
86
+ "[&_[data-fs-select-item]]:px-3",
87
+ "[&_[data-fs-select-item]]:py-2",
88
+ "[&_[data-fs-select-item][data-highlighted]]:bg-neutral-100"
89
+ ]
90
+ }
91
+ }
92
+ ```
93
+
94
+ ---
95
+
96
+ ## Common mistakes
97
+
98
+ - **LocaleSelector** or **LanguagePicker.** The name is `BindingSwitcher`.
99
+ - **A toast for the notice.** The notice is an inline `<output>`.
100
+ - **A default bindings list.** The store passes `$data.Global.localization.bindings`.
101
+ - **Children that rebuild Select.** The schema element has no children.
102
+
103
+ ---
104
+
105
+ ## Styling
106
+
107
+ The host stacks the notice above the control. The popup stays in the host and opens below the trigger, 4px clear of it, so the element `style` reaches `[data-fs-select-popup]`. Give that popup an opaque surface. A parent locked to a fixed height lets the notice paint outside the bar; `min-h-16` on that parent keeps the notice inside it.
108
+
109
+ | Component | What you style | Plausible classes |
110
+ |---|---|---|
111
+ | `BindingSwitcher` | Stacks the notice and the control. The notice line is `text-[13px]`. The popup is `[data-fs-select-popup]`. | `flex flex-col gap-2 text-[14px] [&_[data-fs-binding-switcher-notice]]:text-[13px] [&_[data-fs-select-popup]]:bg-white [&_[data-fs-select-popup]]:border [&_[data-fs-select-popup]]:border-neutral-200 [&_[data-fs-select-popup]]:rounded-md [&_[data-fs-select-popup]]:shadow-lg` |
112
+
113
+ ```json
114
+ {
115
+ "binding-switcher": {
116
+ "type": "BindingSwitcher",
117
+ "props": {
118
+ "bindings": "$data.Global.localization.bindings"
119
+ },
120
+ "style": [
121
+ "flex",
122
+ "flex-col",
123
+ "gap-2",
124
+ "text-[14px]",
125
+ "[&_[data-fs-binding-switcher-notice]]:text-[13px]",
126
+ "[&_[data-fs-select-trigger]]:inline-flex",
127
+ "[&_[data-fs-select-trigger]]:items-center",
128
+ "[&_[data-fs-select-trigger]]:gap-2",
129
+ "[&_[data-fs-select-trigger]]:rounded-md",
130
+ "[&_[data-fs-select-trigger]]:border",
131
+ "[&_[data-fs-select-trigger]]:border-neutral-300",
132
+ "[&_[data-fs-select-trigger]]:bg-white",
133
+ "[&_[data-fs-select-trigger]]:px-3",
134
+ "[&_[data-fs-select-trigger]]:py-1.5",
135
+ "[&_[data-fs-select-positioner]]:z-50",
136
+ "[&_[data-fs-select-popup]]:min-w-[var(--anchor-width)]",
137
+ "[&_[data-fs-select-popup]]:overflow-hidden",
138
+ "[&_[data-fs-select-popup]]:rounded-md",
139
+ "[&_[data-fs-select-popup]]:border",
140
+ "[&_[data-fs-select-popup]]:border-neutral-200",
141
+ "[&_[data-fs-select-popup]]:bg-white",
142
+ "[&_[data-fs-select-popup]]:shadow-lg",
143
+ "[&_[data-fs-select-list]]:py-1",
144
+ "[&_[data-fs-select-item]]:cursor-pointer",
145
+ "[&_[data-fs-select-item]]:px-3",
146
+ "[&_[data-fs-select-item]]:py-2",
147
+ "[&_[data-fs-select-item][data-highlighted]]:bg-neutral-100"
148
+ ]
149
+ }
150
+ }
151
+ ```
152
+
153
+ ---
154
+
155
+ ## Related
156
+
157
+ - [[select]] — the empty dropdown this component composes. `Select` does not know about bindings.
@@ -75,12 +75,9 @@ Root data provider. Declares the GraphQL fragment and exposes product/variant co
75
75
 
76
76
  ### BuyButtonButton
77
77
 
78
- The rendered button. Dispatches `$actions.cart.addItem(...)` on click.
78
+ The rendered button. Dispatches `$actions.cart.addItem(...)` on click. No props.
79
79
 
80
- | Prop | Type | Default | Notes |
81
- |------|------|---------|-------|
82
- | `availableLabel` | string | `"Comprar"` | Label shown when the variant is available for sale |
83
- | `unavailableLabel` | string | `"Indisponivel"` | Label shown when the variant is not available |
80
+ **Content model** (`buy-button-labels`): `availableLabel` (shown when the variant is available for sale) and `unavailableLabel` (shown when it is not), both ICU messages read only from `$content`. A missing message renders empty and logs `message.missing`. `children` replaces the label, and then no message is formatted.
84
81
 
85
82
  **Actions:** declares `actions: { cart: ['addItem'] }`; the compiler threads the `addItem` handler in via `$actions.cart`. Renders `null` when `BuyButtonRoot` has no valid variant data. Disabled (and `aria-busy`) while the add is in-flight (the button tracks its own pending state). Must be a descendant of `BuyButtonRoot`.
86
83
 
@@ -132,9 +129,9 @@ Fill each element's `style` array with Tailwind classes read off the image. Typi
132
129
  | Component | What you style | Plausible classes |
133
130
  |---|---|---|
134
131
  | `BuyButtonRoot` | Layout wrapper only — it renders no box of its own | `block w-full mt-[8px]` |
135
- | `BuyButtonButton` | The CTA: full-width pill in the brand color, with hover and disabled states | `inline-flex items-center justify-center w-full h-[44px] px-[20px] bg-[#C8102E] text-white rounded-[4px] text-[14px] font-bold uppercase cursor-pointer transition-colors hover:bg-[#A50D26] disabled:opacity-50 disabled:cursor-not-allowed` |
132
+ | `BuyButtonButton` | The CTA: full-width pill in the brand color, with hover and disabled states | `inline-flex items-center justify-center w-full h-[44px] px-[20px] bg-[var(--color-primary)] text-white rounded-[4px] text-[14px] font-bold uppercase cursor-pointer transition-colors hover:bg-[var(--color-primary-hover)] disabled:opacity-50 disabled:cursor-not-allowed` |
136
133
 
137
- Read the button's fill color straight off the image as an arbitrary hex (`bg-[#C8102E]`); derive the hover shade as a slightly darker value. Always include `disabled:` styling — the button auto-disables when the variant is unavailable. Do not invent a swatch or token for the brand color; inline hex only.
134
+ The button's fill is the brand color, so write it as the role's variable (`bg-[var(--color-primary)]`), never as the hex read off the image. Its hover and active shades are slightly darker values that several elements of the page share, so declare them in the page or layout `theme` (`--color-primary-hover`, `--color-primary-active`). Always include `disabled:` styling — the button auto-disables when the variant is unavailable.
138
135
 
139
136
  Styled example:
140
137
 
@@ -148,11 +145,13 @@ Styled example:
148
145
  "buy-button-action": {
149
146
  "type": "BuyButtonButton",
150
147
  "props": { "availableLabel": "Comprar", "unavailableLabel": "Indisponível" },
151
- "style": ["inline-flex", "items-center", "justify-center", "w-full", "h-[44px]", "px-[20px]", "bg-[#C8102E]", "text-white", "rounded-[4px]", "text-[14px]", "font-bold", "tracking-[0.06em]", "uppercase", "cursor-pointer", "transition-colors", "duration-150", "hover:bg-[#A50D26]", "active:bg-[#8A0B20]", "disabled:opacity-50", "disabled:cursor-not-allowed"]
148
+ "style": ["inline-flex", "items-center", "justify-center", "w-full", "h-[44px]", "px-[20px]", "bg-[var(--color-primary)]", "text-white", "rounded-[4px]", "text-[14px]", "font-bold", "tracking-[0.06em]", "uppercase", "cursor-pointer", "transition-colors", "duration-150", "hover:bg-[var(--color-primary-hover)]", "active:bg-[var(--color-primary-active)]", "disabled:opacity-50", "disabled:cursor-not-allowed"]
152
149
  }
153
150
  }
154
151
  ```
155
152
 
153
+ The page or layout `theme` that declares the shades: `{"--color-primary-hover": "#A50D26", "--color-primary-active": "#8A0B20"}`.
154
+
156
155
  ---
157
156
 
158
157
  ## Related
@@ -50,7 +50,7 @@ PaymentSectionRoot (or PaymentSectionController)
50
50
  ├── … other payment leaves (installments, save-card, billing, place-order)
51
51
  ```
52
52
 
53
- `CardEntry` renders its own four fields internally (number, holder name, expiration, CVV) — none of them are separately placeable schema elements. Holder name, expiration, and CVV each render conditionally, based on the detected payment method's validator config; the number field always renders. The CVV field is `type="text"`, same as the others, but carries an inline `-webkit-text-security: disc` style that renders its digits as dots — from the keystroke that completes the code, not from the first one. "Complete" is the detected method's own `cvvMask` length: three digits for most networks, four for Amex. Where that mask is pipe-delimited — one method id covering a 3-and-4-digit family — it is the *shortest* alternative, not the longest the field accepts: a shopper holding the 3-digit card of such a family never reaches a fourth digit, so the longer length would leave their complete, valid code legible for the rest of the flow. Below it the digits render in the clear, so a shopper can read back what they just typed and catch a typo; at it, the mask engages on that same render, never on blur and never after a delay, so a paste that delivers every digit in one event opens no legible window. The mask is derived from the value on every render rather than latched once, so backspacing below the length reveals what is left, and a network switch that widens the expectation (a 3-digit code against a newly detected Amex) reveals the code again until its fourth digit. `type="password"` was tried first and reverted: a real Chrome browser offered to save the security code to its password manager (synced to the signed-in account) the instant the field carried that type — pairing the expiration field as a fake "username" — which PCI-DSS forbids for a value that must not be retained past authorization. The CSS property obscures the digits without tripping that heuristic, since it never touches `type`. It is supported in Chromium and WebKit (and, per T70's spec, Firefox 114+ — unverified on this branch); an engine without it renders the digits in the clear, exactly what shipped before this mechanism existed — not a regression. The declaration is an inline style, which outranks a class-based rule from a compound swatch at normal importance — but not one that reaches for Tailwind's `!` important modifier: swatch tokens reach `className` verbatim with no validation, so a store that authors an arbitrary-property utility ending in `!` can still unmask the field. Nothing in this package closes that hole; it is accepted rather than fixed (masking spec, OQ-1). A helper line (`cvvDescription`) renders under the field by default, telling the shopper where to find the code; an empty string suppresses it (see Components below).
53
+ `CardEntry` renders its own four fields internally (number, holder name, expiration, CVV) — none of them are separately placeable schema elements. Holder name, expiration, and CVV each render conditionally, based on the detected payment method's validator config; the number field always renders. The CVV field is `type="text"`, same as the others, but carries an inline `-webkit-text-security: disc` style that renders its digits as dots while the field does not have focus: readable while the shopper is in the field, so they can read back what they just typed and catch a typo, and obscured the moment focus leaves it, with no length involved — a partial code is hidden on blur like a full one. Re-focusing a hidden code reveals it again, so a typo can be read and corrected. A disabled field counts as unfocused, because a browser fires no `blur` when a focused input becomes disabled; the focus flag is also reset when the card form collapses and when the input unmounts. The style is derived from the value and the focus flag on every render, never from an effect or a timer, so a paste or a browser autofill that delivers every digit while the field is unfocused, and the blur itself, open no legible window. The trade-off is deliberate: while the field has focus, a code the shopper just typed is on screen in the clear. `type="password"` was tried first and reverted: a real Chrome browser offered to save the security code to its password manager (synced to the signed-in account) the instant the field carried that type — pairing the expiration field as a fake "username" — which PCI-DSS forbids for a value that must not be retained past authorization. The CSS property obscures the digits without tripping that heuristic, since it never touches `type`. It is supported in Chromium and WebKit (and Firefox 114+, unverified on this branch); an engine without it renders the digits in the clear, exactly what shipped before this mechanism existed — not a regression. The declaration is an inline style, which outranks a class-based rule from a compound swatch at normal importance — but not one that reaches for Tailwind's `!` important modifier: swatch tokens reach `className` verbatim with no validation, so a store that authors an arbitrary-property utility ending in `!` can still unmask the field. Nothing in this package closes that hole; it is accepted rather than fixed. A helper line (`cvvDescription`) renders under the field by default, telling the shopper where to find the code; an empty string suppresses it (see Components below).
54
54
 
55
55
  **Composition rules:**
56
56
 
@@ -72,7 +72,7 @@ Collapsing clears the security code field, and only the security code. The card
72
72
 
73
73
  The authored `disabled` prop is independent of the collapse: a store that freezes the form with `disabled` sees no change, and a collapsed form may also be `disabled` — neither implies the other.
74
74
 
75
- In the checkout, the card number, holder name, expiration, and security code are cleared after every outcome in which the card target ran: the card POST resolved clean, resolved with errors or threw, or the target refused before any request. They are kept when the submission was refused before the target ran (the form's own check, a refused or untrusted transaction, the submit gate, no method selected) so the shopper can fix them.
75
+ In the checkout, the card number, holder name, expiration, and security code are cleared after every outcome in which the card target ran: the card POST resolved clean, resolved with errors or threw, or the target refused before any request. They are kept when the submission was refused before the target ran (the form's own check, a refused or untrusted transaction, the submit gate, no method selected) so the shopper can fix them. The values stay while the card request is open and clear as soon as it settles, ahead of the confirmation callback, so a callback error or timeout finds the form already empty. While the order attempt is resume-only the form accepts no input, so a card cannot be typed into a form that the next click would ignore.
76
76
 
77
77
  ---
78
78
 
@@ -90,7 +90,7 @@ In the checkout, the card number, holder name, expiration, and security code are
90
90
  }
91
91
  ```
92
92
 
93
- **If the store's `global.json` already has an `icons` object, extend it — do not replace it.** A store that already sets `"collection"` (or `"aliases"` / `"collections"`) must keep that key alongside the new `include`:
93
+ **If the store's `foundation.json` already has an `icons` object, extend it — do not replace it.** A store that already sets `"collection"` (or `"aliases"` / `"collections"`) must keep that key alongside the new `include`:
94
94
 
95
95
  ```json
96
96
  {
@@ -107,7 +107,7 @@ Omitting `include` entirely is silent too. The network icon renders as an empty
107
107
 
108
108
  ## Store setup: response headers
109
109
 
110
- The card number and security code are typed into `CardEntry`'s raw fields and POSTed from the browser straight to the VTEX payment gateway, so the page that composes it needs a policy that names the vault host the card is POSTed to, forbids framing the page, and narrows what the page may load and call. The generator ships no default: the store declares it in `global.json` under `responseHeaders`, scoped by `routes` to the page that composes `CardEntry`.
110
+ The card number and security code are typed into `CardEntry`'s raw fields and POSTed from the browser straight to the VTEX payment gateway, so the page that composes it needs a policy that names the vault host the card is POSTed to, forbids framing the page, and narrows what the page may load and call. The generator ships no default: the store declares it in `foundation.json` under `responseHeaders`, scoped by `routes` to the page that composes `CardEntry`.
111
111
 
112
112
  ```json
113
113
  {
@@ -115,7 +115,7 @@ The card number and security code are typed into `CardEntry`'s raw fields and PO
115
115
  {
116
116
  "routes": ["/checkout"],
117
117
  "headers": {
118
- "Content-Security-Policy": "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https://acme.vtexvault.com; frame-ancestors 'none'; base-uri 'self'; object-src 'none'",
118
+ "Content-Security-Policy": "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://acme.vtexassets.com; font-src 'self' data:; connect-src 'self' https://acme.vtexvault.com; form-action 'self'; frame-ancestors 'none'; base-uri 'self'; object-src 'none'",
119
119
  "Referrer-Policy": "strict-origin-when-cross-origin"
120
120
  }
121
121
  }
@@ -123,10 +123,10 @@ The card number and security code are typed into `CardEntry`'s raw fields and PO
123
123
  }
124
124
  ```
125
125
 
126
- - **The vault host in `connect-src` is `https://{account}.vtexvault.com`, for the account the store serves.** That is the `NEXT_PUBLIC_ACCOUNT` the store is built with, which is not always `account.name` in `global.json`. Write the served account, with no wildcard: `https://*.vtexvault.com` would let a compromised script send the card to any tenant's vault.
126
+ - **The vault host in `connect-src` is `https://{account}.vtexvault.com`, for the account the store serves.** That is the `NEXT_PUBLIC_ACCOUNT` the store is built with, which is not always `store.account` in `foundation.json`. Write the served account, with no wildcard: `https://*.vtexvault.com` would let a compromised script send the card to any tenant's vault.
127
127
  - **A policy that names the legacy payments host (`vtexpayments.com.br`) makes the browser block the card POST.** The order cannot be placed and nothing else on the page reports why. The generated app calls its own GraphQL at the relative `/api/graphql`, so `'self'` covers it; a store built with an absolute `NEXT_PUBLIC_STOREFRONT_API_URL` must add that origin.
128
128
  - **A rule's `routes` must name the page that composes `CardEntry`**, as the page's `route` spells it (`/checkout`, `/reserva/checkout/payment`). Renaming that page fails the compile instead of dropping the policy. A page added later that composes `CardEntry` carries nothing until its route is added to the rule.
129
- - **`script-src 'unsafe-inline'` is a known limit, and the policy does not stop injected script from sending the card off the page.** A static header cannot carry a nonce, so the inline scripts Next.js emits need it, and script injected into the page runs with the same rights. `connect-src` closes only `fetch`, XHR, beacons and WebSocket. The policy still leaves three channels open to any https host: an image request (`img-src https:`, which the page needs for catalog images), a form submission (no `form-action`) and a navigation (CSP cannot restrict one). What today's ruled policy does give is the vault origin pinned, no `'unsafe-eval'`, a page no other site can frame (`frame-ancestors 'none'`) and no `http:` or wildcard source. It does not replace keeping untrusted script off the payment page.
129
+ - **`script-src 'unsafe-inline'` is a known limit, and the policy does not stop injected script from sending the card off the page.** A static header cannot carry a nonce, so the inline scripts Next.js emits need it, and script injected into the page runs with the same rights. `connect-src` closes only `fetch`, XHR, beacons and WebSocket. The policy still leaves one channel open to any https host: a navigation (CSP cannot restrict one). The image and form-post channels are closed: `img-src` names exactly one image origin, `https://{account}.vtexassets.com`, so a store whose page loads images from another origin must list that origin exactly (a bare `https:` fails the header check), and `form-action 'self'` stops a form from posting to another origin (the check accepts `'self'` or `'none'` and nothing else). What today's ruled policy does give is the vault origin pinned, no `'unsafe-eval'`, a page no other site can frame (`frame-ancestors 'none'`) and no `http:` or wildcard source. It does not replace keeping untrusted script off the payment page.
130
130
  - **`frame-ancestors 'none'`** blanks the page inside any iframe, including an editor preview.
131
131
  - **reCAPTCHA needs the anti-bot origins, and the ruled policy above does not declare them yet.** The challenge frame and script come from `https://www.google.com` and `https://www.gstatic.com`, the origins `sdk/anti-bot` declares. The frame is blocked by `default-src 'self'` (no `frame-src`) and the script by `script-src 'self' 'unsafe-inline'`, so both need the anti-bot origins. The stores add them together with whoever wires `getAntiBotToken`; the header check accepts a `frame-src` that names only those two origins and rejects any other.
132
132
  - **Under `next dev` the served `script-src` also carries `'unsafe-eval'`; production does not.** React Refresh evaluates code in the browser, so the generated `next.config.ts` adds `'unsafe-eval'` to the `script-src` of every Content-Security-Policy it serves only when `NODE_ENV` is `development` (what `next dev` sets), which is what `pnpm dev:example` runs. Any build whose `NODE_ENV` is not `development` (the default for `next build` and `next start`) serves the declared policy byte for byte, so the live header check still runs against them: a dev response shows a `script-src` the store never declared, which `scripts/assert-payment-page-headers.mjs` rejects by design, so run that script against `next start`.
@@ -143,33 +143,44 @@ The only component. No internal sub-parts are separately schema-addressable.
143
143
 
144
144
  | Prop | Type | Default | Notes |
145
145
  |------|------|---------|-------|
146
- | `legend` | string | `"Card details"` | Fieldset legend/title. |
147
- | `numberLabel` | string | `"Card number"` | Card-number field label. |
148
146
  | `numberPlaceholder` | string | — | Card-number field placeholder. |
149
- | `holderNameLabel` | string | `"Cardholder name"` | Holder-name field label. Same noun as `holderNameRequiredMessage`, deliberately. |
150
147
  | `holderNamePlaceholder` | string | — | Holder-name field placeholder. |
151
- | `expirationLabel` | string | `"Expiration date"` | Expiration field label. |
152
- | `expirationPlaceholder` | string | `"MM/YY"` | Expiration field placeholder. |
153
- | `cvvLabel` | string | `"Security code"` | CVV field label. |
154
148
  | `cvvPlaceholder` | string | — | CVV field placeholder. |
155
- | `cvvDescription` | string | `"The 3-4 digit number on your card"` | Helper text under the CVV field. Empty string renders nothing. |
156
- | `numberRequiredMessage` | string | `"Card number is required"` | Shown when the card-number field is left blank. |
157
- | `numberInvalidMessage` | string | `"Enter a valid card number"` | Shown for a Luhn-invalid number, or one a configured network claims only as a prefix (the wrong length, or two networks at once). |
158
- | `networkNotAcceptedMessage` | string | `"This card is not from a network the store accepts"` | Shown for a Luhn-valid number that no configured network claims at all. |
159
- | `holderNameRequiredMessage` | string | `"Cardholder name is required"` | Shown when the holder-name field is left blank and the detected method requires it. |
160
- | `expirationRequiredMessage` | string | `"Expiration date is required"` | Shown when the expiration field is left blank and the detected method requires it. |
161
- | `expirationInvalidMessage` | string | `"Enter a valid expiration date"` | Shown for a structurally malformed `MM/YY`. |
162
- | `expirationExpiredMessage` | string | `"This card has expired"` | Shown for a structurally valid `MM/YY` that has already passed. |
163
- | `cvvRequiredMessage` | string | `"Security code is required"` | Shown when the CVV field is left blank and the detected method requires it. |
164
- | `cvvInvalidMessage` | string | `"Enter a valid security code"` | Shown for a CVV that fails the detected method's format. |
165
149
  | `disabled` | boolean | `false` | Disables every field. |
166
150
 
151
+ **Content model** (`card-entry`), every field read only from `$content` (a missing message renders empty and logs `message.missing`):
152
+
153
+ | Field | Source copy | Notes |
154
+ |-------|-------------|-------|
155
+ | `legend` | "Card details" | Fieldset legend/title. |
156
+ | `numberLabel` | "Card number" | Card-number field label. |
157
+ | `holderNameLabel` | "Cardholder name" | Holder-name field label. Same noun as `holderNameRequiredMessage`, deliberately. |
158
+ | `expirationLabel` | "Expiration date" | Expiration field label. |
159
+ | `expirationPlaceholder` | "MM/YY" | Expiration field placeholder. |
160
+ | `cvvLabel` | "Security code" | CVV field label. |
161
+ | `cvvDescription` | "The 3-4 digit number on your card" | Helper text under the CVV field. A blank message renders nothing. |
162
+ | `numberRequiredMessage` | "Card number is required" | Shown when the card-number field is left blank. |
163
+ | `numberInvalidMessage` | "Enter a valid card number" | Shown for a Luhn-invalid number, or one a configured network claims only as a prefix (the wrong length, or two networks at once). |
164
+ | `networkNotAcceptedMessage` | "This card is not from a network the store accepts" | Shown for a Luhn-valid number that no configured network claims at all. |
165
+ | `holderNameRequiredMessage` | "Cardholder name is required" | Shown when the holder-name field is left blank and the detected method requires it. |
166
+ | `expirationRequiredMessage` | "Expiration date is required" | Shown when the expiration field is left blank and the detected method requires it. |
167
+ | `expirationInvalidMessage` | "Enter a valid expiration date" | Shown for a structurally malformed `MM/YY`. |
168
+ | `expirationExpiredMessage` | "This card has expired" | Shown for a structurally valid `MM/YY` that has already passed. |
169
+ | `cvvRequiredMessage` | "Security code is required" | Shown when the CVV field is left blank and the detected method requires it. |
170
+ | `cvvInvalidMessage` | "Enter a valid security code" | Shown for a CVV that fails the detected method's format. |
171
+
167
172
  **Data:** declares no fragment and no actions. Card masks, required-ness, and network regexes come from the `card-capture` context — at checkout, the payment section's own methods. It reads no cart, so it works where no purchase is underway; the `add_payment_info` event and the cart total it needs belong to the payment section root.
168
173
 
169
174
  **Never a schema prop:** the card number and CVV. They exist only in this component's local state, for the lifetime of the mounted instance, and are never exposed as a bindable prop, a fragment field, or a value another component can read.
170
175
 
171
176
  **Validation timing:** the draft is validated before the place-order sequence opens a transaction, not only when the order is submitted — an invalid number, holder name, expiration, or CVV refuses with an inline field message before anything is charged or opened. The submission itself re-validates the same way, so the two can never disagree.
172
177
 
178
+ **Field timing:** each field validates when the shopper leaves it. A blur writes or clears only that field's error, and editing a field clears its own error. A blur never moves focus: pulling focus back to a half-typed expiration would trap a shopper who tabs away. The first invalid field takes focus only when Place order refuses the draft.
179
+
180
+ **Keyboard hint:** the number, expiration, and security code inputs carry `inputmode="numeric"`; the holder name input carries none. The attribute is advisory, so a keyboard that ignores it still shows letters.
181
+
182
+ **A card from a network the store does not accept:** a Luhn-valid number that no configured network claims, exactly or as a prefix, is told apart from a malformed one. The number field shows `networkNotAcceptedMessage` when the shopper leaves it, and Place order refuses with the code `UNSUPPORTED_CARD_NETWORK`, rendered through `PlaceOrder`'s `unsupportedNetworkMessage`, whether or not a payment method is selected. The refusal comes before any transaction opens. With no method selected, the form gives the place-order sequence a side-effect-free explanation, asked only at the missing-method step, so the order of the checks (path, method, submit gate, card check) does not change; that click sets no field error and moves no focus, because the blur message is already on the field. With a method selected, the card check itself refuses with the same code, shows the field error, and focuses the number. A prefix claimed at the wrong length, a prefix two networks both claim, a Luhn-invalid number, and a blank number keep their existing refusals, and so does a store whose methods carry no number pattern, where detection never ran. The code and both messages are fixed copy: nothing derived from the typed number appears in them or in a log line.
183
+
173
184
  **Selection timing:** network detection, the network mark, and the number's grouping follow every keystroke, but the detected method and the card's BIN (its first eight digits) reach the server only once the number field holds eight digits — never as a shorter prefix. Below eight digits nothing is sent, so the installments control and the persisted selection keep whatever was last recorded. The first digit typed off the new-card path does record that path, locally and with nothing sent, so a saved card that was checked stops being the selection as soon as the shopper starts a new number.
174
185
 
175
186
  ---
@@ -234,14 +245,16 @@ Style `CardEntry`'s root as a vertical stack of fields, matching a typical card
234
245
  | Network mark slot (`data-fs-card-entry-networks`) | Positions the single mark inside the input's box; absent entirely until a network is recognized | `absolute right-[12px] top-1/2 -translate-y-1/2 flex items-center` |
235
246
  | Network mark (`data-fs-card-entry-network`) | The recognized network itself — **at most one**, never a row. Carries `data-fs-card-entry-network-id` with the detected method's id | `flex items-center justify-center` |
236
247
  | Network icon (`data-fs-card-entry-network-icon`) | The icon, when the recognized network's name maps to one | `w-[20px] h-[20px]` |
237
- | Network fallback text (`data-fs-card-entry-network-fallback`) | The recognized network's name as text, when it maps to no icon; mutually exclusive with the icon | `text-[13px] font-medium text-[#333333]` |
238
- | Field labels (`data-fs-field-label`) | Small, muted label above each input | `text-[13px] font-medium text-[#333333] mb-[4px] block` |
239
- | Field inputs (`data-fs-field-control`) | The bordered text input | `border border-[#CCCCCC] rounded-[6px] px-[12px] py-[10px] text-[15px] w-full` |
240
- | Field errors (`data-fs-field-error`) | Inline validation message, small and red | `text-[12px] text-[#C8102E] mt-[4px] block` |
241
- | CVV helper text (`data-fs-card-entry-cvv-description`) | Small muted line under the CVV field | `text-[12px] text-[#666666] mt-[4px] block` |
248
+ | Network fallback text (`data-fs-card-entry-network-fallback`) | The recognized network's name as text, when it maps to no icon; mutually exclusive with the icon | `text-[13px] font-medium text-[var(--color-ink)]` |
249
+ | Field labels (`data-fs-field-label`) | Small, muted label above each input | `text-[13px] font-medium text-[var(--color-ink)] mb-[4px] block` |
250
+ | Field inputs (`data-fs-field-control`) | The bordered text input | `border border-[color-mix(in_srgb,var(--color-ink)_20%,transparent)] rounded-[var(--radius-base)] px-[12px] py-[10px] text-[15px] w-full` |
251
+ | Field errors (`data-fs-field-error`) | Inline validation message, small | `text-[12px] mt-[4px] block` |
252
+ | CVV helper text (`data-fs-card-entry-cvv-description`) | Small muted line under the CVV field | `text-[12px] text-[color-mix(in_srgb,var(--color-ink)_60%,transparent)] mt-[4px] block` |
242
253
  | Placing (`data-fs-card-entry-placing`) | Present while an order-placement sequence is in flight (T28), and while the order attempt is resume-only (its card may already have been sent, so the fields do not accept input) until the attempt is freed; the whole root is also `inert` and `aria-disabled` at that point, so style this hook rather than relying on pointer events alone | `opacity-60 cursor-not-allowed` |
243
254
  | Collapsed (`data-fs-card-entry-collapsed`) | Present on the styled root while the card payment is collapsed — the persisted selection is a method this section does not serve or one that is not a card, and a picker is composed to un-hide it (see Reveal and collapse); the root is also `inert`. **No transition or animation can run on it**: the actual hide is a `hidden` attribute one level up, on an unstyled wrapper this node cannot reach with any class, and an ancestor's `display:none` removes the whole subtree from rendering the instant it applies, before any transition on a descendant could ever paint. Use this hook only for one-shot conditional styling of the (already-unrendered) subtree, never for an entrance/exit animation | `opacity-60` |
244
255
 
256
+ A status color is a `visualIdentity` feedback role of the foundation: when the store declares them, color the error row `text-[var(--color-feedback-danger)]`, the success row `text-[var(--color-feedback-success)]` and the notice row `text-[var(--color-feedback-warning)]`, never with a hex.
257
+
245
258
  Styled minimal example:
246
259
 
247
260
  ```json
@@ -260,7 +273,7 @@ Styled minimal example:
260
273
  ## Accessibility Contract
261
274
 
262
275
  **What the platform promises:** the four fields sit inside a native `<fieldset>`/`<legend>` pair
263
- (`legend`, default `"Card details"`) — the pattern every other grouped payment control now follows
276
+ (the `legend` message) — the pattern every other grouped payment control now follows
264
277
  (T38, Decision 1). Each field carries its own `Field.Label`, `aria-invalid`, and an error message
265
278
  associated through `aria-describedby` once it fails validation; the CVV field's helper text
266
279
  (`cvvDescription`) is linked the same way. There is no composite keyboard widget here — every rendered
@@ -0,0 +1,185 @@
1
+ # Card Summary
2
+
3
+ **Category:** content
4
+ **Purpose:** A saved card's identity: its network's mark, its label or else its network name, a mask, and its last four digits, as parts the schema arranges.
5
+
6
+ ---
7
+
8
+ ## Visual cues (how to identify in an image)
9
+
10
+ - A card-network logo (Visa, Mastercard, American Express, Diners, Elo) beside a short text.
11
+ - A name such as `Visa` or a shopper's own label such as `Company card`.
12
+ - A masking symbol (`••••`, `****`) followed by four digits: `•••• 1234`.
13
+ - Usually one line per card, repeated in a list or inside a selectable row.
14
+
15
+ The image is the source of truth for layout.
16
+
17
+ ## When to use
18
+
19
+ - Describing one saved card wherever it appears: the account's saved-cards list, a removal confirmation, the checkout's saved-card row.
20
+
21
+ ## When NOT to use
22
+
23
+ - The store's accepted payment methods as a strip of logos → [[payment-methods]].
24
+ - Typing a new card → the checkout's card entry; this particle never takes a full number or a security code.
25
+ - A card's expiry or usability state → the row that owns the card renders it beside this particle.
26
+
27
+ ---
28
+
29
+ ## Composition
30
+
31
+ ```
32
+ <row that provides 'card-summary'> ← e.g. AccountSavedCardItem
33
+ └── CardSummary
34
+ ├── CardSummaryMark (default)
35
+ ├── CardSummaryName (default)
36
+ ├── CardSummaryMask (default)
37
+ └── CardSummaryDigits (default)
38
+ ```
39
+
40
+ `CardSummary` with no children renders the four parts in that order. Composing children replaces the default: any order, any subset. Child order is the visual order and the screen-reader order. The parts can also sit directly in the providing row, without the `CardSummary` wrapper.
41
+
42
+ Every part requires the `card-summary` context, and only a matter row that owns card data provides it in a schema. The row wraps its children in `CardSummaryRoot` in code and declares `'card-summary'` in its own `providesContext`, so the schema composes the parts directly in the row. Context matching is by contract, not by component name. Stories, tests, and hand-written JSX render `CardSummaryRoot` themselves.
43
+
44
+ A part outside any provider fails the build with a `ContextConstraintError`, and throws at runtime outside the compiler.
45
+
46
+ ---
47
+
48
+ ## Components
49
+
50
+ ### CardSummaryRoot
51
+
52
+ Code only: it has no catalog entry and is never placed in a schema, because a schema cannot supply the card. Renders no element. Publishes the card to the parts. Keeps only the trailing four digit characters of `lastDigits`; the raw value never reaches a part.
53
+
54
+ | Prop | Type | Default | Notes |
55
+ |------|------|---------|-------|
56
+ | `network` | string | — | The network's display name from the platform, e.g. `Visa`. Data, not a schema prop. |
57
+ | `lastDigits` | string | — | The card's last digits. Only four ever render. Data, not a schema prop. |
58
+ | `label` | string \| null | — | The shopper's own name for the card. Shown in place of the network name when non-blank. Data, not a schema prop. |
59
+
60
+ ### CardSummary
61
+
62
+ The wrapper, `<span data-fs-card-summary>`. Carries `data-fs-card-summary-network="<icon>"` when the network has a mark and `data-fs-card-summary-labeled` when a label is present. No props besides `$content`.
63
+
64
+ It formats its `endingIn` message and hands it to the `CardSummaryDigits` inside it. A missing message logs an error, and the digits are then read bare. A `CardSummary` has `$content` only when the store places it or a parent forwards a message to it, as `AccountSavedCardRemoveDescription` forwards its `cardEndingIn`.
65
+
66
+ Content type `card-summary`:
67
+
68
+ | Content field | Description |
69
+ |---|---|
70
+ | endingIn | The last digits as read to assistive technology, with the `lastDigits` argument |
71
+
72
+ ### CardSummaryMark
73
+
74
+ The network's mark. No props. Decided by the data, never by which other parts are composed:
75
+
76
+ | Card | Renders |
77
+ |---|---|
78
+ | Mapped network, no label | The glyph, decorative (the name says the network). |
79
+ | Mapped network, labelled | The glyph plus the network name as screen-reader text. |
80
+ | Unmapped network, no label | Nothing. |
81
+ | Unmapped network, labelled | The network name as visible text (`data-fs-card-summary-network-name`), never another network's glyph. |
82
+
83
+ So a labelled card still tells a sighted shopper and a screen reader its network, even when the schema drops `CardSummaryName`. An unlabelled card does not: its glyph is decorative and `CardSummaryName` is what announces the network, so the network is announced exactly once in the default composition.
84
+
85
+ ### CardSummaryName
86
+
87
+ The label, or else the network name. Nothing when both are blank. Read-only. No props.
88
+
89
+ ### CardSummaryMask
90
+
91
+ Decoration for the hidden digits, always `aria-hidden`. Nothing when empty or when the card has no digits.
92
+
93
+ | Prop | Type | Default | Notes |
94
+ |------|------|---------|-------|
95
+ | `mask` | string | `••••` | The masking symbol. An empty string renders nothing. |
96
+
97
+ `children` replace `mask`, e.g. an `Icon`. Keep them inline: the particle sits inside labels and paragraphs.
98
+
99
+ ### CardSummaryDigits
100
+
101
+ The last four digits. Screen readers hear the `endingIn` message of the `CardSummary` around them, such as "ending in 1234"; the visible digits are hidden from them. Outside a `CardSummary`, or with its message missing, screen readers hear the bare digits. Nothing when the card has no digits. No props.
102
+
103
+ ---
104
+
105
+ ## Networks and the `icons.include` obligation
106
+
107
+ The mark comes from `CARD_NETWORK_ICON_BY_KEY` in `card-network.ts`, the one map every card surface shares. A network name matches after lowercasing and removing every character outside `a-z`: `Visa`, `Mastercard`, `Amex`, `American Express`, `Diners`, `Diners Club`, and `Elo` have marks. Matching is exact, so `Visa Electron` or `Elo Debit` render by name, without a mark. `cardNetworkIcon(name)` returns the icon name or `null`.
108
+
109
+ **Every mapped name must be registered.** The network comes from data, so the compiler cannot see which glyphs a route needs. A store that renders `CardSummaryMark` lists the names under `icons.include` in its `foundation.json`; it is JSON, so it cannot import `CARD_NETWORK_ICON_NAMES`, and the names are written out:
110
+
111
+ ```json
112
+ { "icons": { "include": ["visa", "mastercard", "amex", "diners", "elo-card"] } }
113
+ ```
114
+
115
+ A name the store never registered renders an empty `<svg>`: no build error and no runtime error, just a missing mark. All five are base-dialect names, so they resolve in any store whatever its icon collection.
116
+
117
+ ---
118
+
119
+ ## Canonical schema example
120
+
121
+ The account's row provides the context; the schema arranges the parts:
122
+
123
+ ```json
124
+ {
125
+ "saved-card-item": { "type": "AccountSavedCardItem", "children": ["card-summary"] },
126
+ "card-summary": { "type": "CardSummary", "style": ["inline-flex", "items-center", "gap-[8px]"] }
127
+ }
128
+ ```
129
+
130
+ Digits first, with another mask:
131
+
132
+ ```json
133
+ {
134
+ "saved-card-item": { "type": "AccountSavedCardItem", "children": ["card-digits", "card-mask", "card-mark", "card-name"] },
135
+ "card-digits": { "type": "CardSummaryDigits" },
136
+ "card-mask": { "type": "CardSummaryMask", "props": { "mask": "****" } },
137
+ "card-mark": { "type": "CardSummaryMark" },
138
+ "card-name": { "type": "CardSummaryName" }
139
+ }
140
+ ```
141
+
142
+ ## Common mistakes
143
+
144
+ - **`CardSummaryNumber`, `CardSummaryLastFour`.** The correct name is `CardSummaryDigits`.
145
+ - **`CardSummaryBrand`, `CardSummaryFlag`, `CardSummaryIcon`.** The correct name is `CardSummaryMark`.
146
+ - **`CardSummaryLabel`.** The correct name is `CardSummaryName`; it shows the label or else the network name.
147
+ - **Writing the bullets inside `CardSummaryDigits`.** The mask is its own part, `CardSummaryMask`.
148
+ - **Placing `CardSummaryRoot` in a schema, or passing `network`, `lastDigits`, or `label` as schema props.** The card is data from the row that provides `card-summary`; the Root is not in the catalog.
149
+ - **Composing a part outside a row that provides `card-summary`.** It fails the build.
150
+ - **Dropping `CardSummaryMark` or `CardSummaryDigits` from a custom composition.** The PRD requires both beside a card; only the default composition guarantees them.
151
+ - **Composing `CardSummaryMark` without `CardSummaryName`.** On an unlabelled card the glyph is decorative and the name is what announces the network, so a screen reader hears only "ending in 1234". Keep `CardSummaryName` whenever `CardSummaryMark` is composed.
152
+
153
+ ---
154
+
155
+ ## Styling
156
+
157
+ | Component | What you style | Plausible classes |
158
+ |---|---|---|
159
+ | `CardSummary` | Lines the parts up | `inline-flex items-center gap-[8px]` |
160
+ | `CardSummaryMark` | Mark box; size the glyph through it | `inline-flex items-center [&_svg]:h-[24px] [&_svg]:w-[32px]` |
161
+ | `CardSummaryName` | Name typography | `text-[14px] font-medium text-[var(--color-text)]` |
162
+ | `CardSummaryMask` | Mask color and spacing | `text-[14px] tracking-[2px] text-[var(--color-text-muted)]` |
163
+ | `CardSummaryDigits` | Digit typography | `text-[14px] tabular-nums text-[var(--color-text)]` |
164
+
165
+ `CardSummaryRoot` renders no element and is not styled.
166
+
167
+ ```json
168
+ {
169
+ "card-summary": { "type": "CardSummary", "style": ["inline-flex", "items-center", "gap-[8px]"], "children": ["card-mark", "card-name", "card-mask", "card-digits"] },
170
+ "card-mark": { "type": "CardSummaryMark", "style": ["inline-flex", "items-center", "[&_svg]:h-[24px]", "[&_svg]:w-[32px]"] },
171
+ "card-name": { "type": "CardSummaryName", "style": ["text-[14px]", "font-medium", "text-[var(--color-text)]"] },
172
+ "card-mask": { "type": "CardSummaryMask", "style": ["text-[14px]", "tracking-[2px]", "text-[var(--color-text-muted)]"] },
173
+ "card-digits": { "type": "CardSummaryDigits", "style": ["text-[14px]", "tabular-nums", "text-[var(--color-text)]"] }
174
+ }
175
+ ```
176
+
177
+ The colors that several elements share are variables of the page or layout `theme`, which declares them: `{"--color-text": "#1F1F1F", "--color-text-muted": "#6B6B6B"}`. A color used once stays a hex.
178
+
179
+ ---
180
+
181
+ ## Related
182
+
183
+ - [[payment-methods]]: the store's accepted payment methods as a strip of logos; not a saved card.
184
+ - [[address-summary]]: the same Root-plus-parts shape, for a postal address.
185
+ - [[icon]]: renders the mark from the base icon dialect.
@@ -69,6 +69,8 @@ The field itself. Renders the `DocumentField` particle for the type `usePayment(
69
69
  | `errorMessage` | `string` | `'Invalid '` + the type's name | Shown inline when the typed value fails the type's validation on blur. |
70
70
  | `disabled` | `boolean` | `false` | Disables the input without hiding it — independent of the data-driven presence gate. |
71
71
 
72
+ The method decides whether the field shows and whether it is mandatory; the store's country decides which document it is. The type is the first displayable document the store's country row lists that this build knows, and a country row's own `required` flag is read by nobody. The SSN and SIN inputs carry `autocomplete="off"` so a browser does not offer them for autofill; the CPF and RFC inputs carry no `autocomplete` attribute, and every type stays `type="text"`.
73
+
72
74
  No `documentType` prop — the store's country decides it. No `required` prop — requiredness is always read from the selected method's validator, never authored.
73
75
 
74
76
  **Data:** declares no `fragment` of its own. It reads `selectedMethod`, `countryDocumentType`, `draft`, and `setDraftDocument` off the ambient `payment` context that `PaymentSectionRoot` / `PaymentSectionController` already fetches for.
@@ -109,8 +111,8 @@ No `documentType` prop — the store's country decides it. No `required` prop
109
111
 
110
112
  ## Known limitations
111
113
 
112
- - **Four person documents, by store country.** The country comes from `Payment.storeCountryCode` and `Payment.countries`. A store whose country resolves to no document type shows no field, refuses nothing and sends no document. A document typed while the field was shown is posted only while the selected method still asks for one and the country still resolves a type; the draft itself is not cleared. `label`, `placeholder` and `errorMessage` have no catalog default (the right copy depends on the country), so leave them unset unless the store serves one country.
113
- - **Server-driven requiredness renders the field correctly and is also enforced at submit time — but not by this component or by `CardEntry`.** This component marks the field required when the validator says so; a required-but-blank or malformed value (whether or not required) blocks Place Order client-side, before any transaction opens, **while the selected method's validator also says the document is displayable**. That gate lives in `matter/payment/use-payment-submit-gate.ts` (T24) and is consumed by `PlaceOrder`, not by this component or by `CardEntry`'s own `validateDraft` — this component's only job stays publishing `draft.document` via `setDraftDocument`. When the *currently* selected method's validator says `documentDisplayable: false`, the gate treats `draft.document` as inert either way (fix pass, findings R1/S4/S5): there is no field on screen for the shopper to read a leftover value from or correct it in, whether that value is left over from a previously selected, displayable method or simply blank. See `specs/cardholder-document-submit-gate.md` for the gate's full contract.
114
+ - **Four person documents, by store country.** The country comes from `Payment.storeCountryCode` and `Payment.countries`. A store whose country resolves to no document type shows no field, refuses nothing and sends no document, even when the selected method says a document is required, so the order is not refused client-side for it. A document typed while the field was shown is posted only while the selected method still asks for one and the country still resolves a type; the draft itself is not cleared. `label`, `placeholder` and `errorMessage` have no catalog default (the right copy depends on the country), so leave them unset unless the store serves one country.
115
+ - **Server-driven requiredness renders the field correctly and is also enforced at submit time — but not by this component or by `CardEntry`.** This component marks the field required when the validator says so; a required-but-blank or malformed value (whether or not required) blocks Place Order client-side, before any transaction opens, **while the selected method's validator also says the document is displayable**. That gate lives in `matter/payment/use-payment-submit-gate.ts` (T24) and is consumed by `PlaceOrder`, not by this component or by `CardEntry`'s own `validateDraft` — this component's only job stays publishing `draft.document` via `setDraftDocument`. The gate checks the value against the same country-resolved type the field shows. When the *currently* selected method's validator says `documentDisplayable: false`, the gate treats `draft.document` as inert either way (fix pass, findings R1/S4/S5): there is no field on screen for the shopper to read a leftover value from or correct it in, whether that value is left over from a previously selected, displayable method or simply blank.
114
116
 
115
117
  ---
116
118
 
@@ -120,7 +122,7 @@ No `documentType` prop — the store's country decides it. No `required` prop
120
122
 
121
123
  | Component | What you style | Plausible classes |
122
124
  |---|---|---|
123
- | `CardholderDocument` | The field's own label, input box, and inline error — same shape as a `Field.Root` | `flex flex-col gap-[4px] w-full` on the root; `text-[14px] font-medium text-[#1A1A1A]` for the label; `border border-[#CCCCCC] rounded-[6px] px-[12px] py-[8px] text-[14px]` for the input |
125
+ | `CardholderDocument` | The field's own label, input box, and inline error — same shape as a `Field.Root` | `flex flex-col gap-[4px] w-full` on the root; `text-[14px] font-medium text-[var(--color-ink)]` for the label; `border border-[color-mix(in_srgb,var(--color-ink)_20%,transparent)] rounded-[var(--radius-base)] px-[12px] py-[8px] text-[14px]` for the input |
124
126
  | Placing (`data-fs-cardholder-document-placing`) | Present while an order-placement sequence is in flight (T28); the field is also `inert` and `aria-disabled` at that point | `opacity-60 cursor-not-allowed` |
125
127
 
126
128
  Styled example: