@vtex/faststore 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (411) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/dist/actions.json +152 -1
  3. package/dist/catalog.json +1264 -142
  4. package/dist/cli/index.d.ts +512 -63
  5. package/dist/cli/index.js +2098 -686
  6. package/dist/cli/index.js.map +1 -1
  7. package/dist/cli/server-runtime.js +44 -24
  8. package/dist/cli/server-runtime.js.map +1 -1
  9. package/dist/client.d.ts +5 -1
  10. package/dist/client.js +5 -1
  11. package/dist/components.d.ts +34 -7
  12. package/dist/components.js +38 -11
  13. package/dist/content-types.json +523 -0
  14. package/dist/core/dist/define-component.d.ts +6 -1
  15. package/dist/docs/account-access-gate.md +4 -4
  16. package/dist/docs/account-address-book.md +519 -0
  17. package/dist/docs/account-entry-point.md +1 -1
  18. package/dist/docs/account-menu.md +5 -5
  19. package/dist/docs/alert-dialog.md +2 -2
  20. package/dist/docs/billing-address.md +17 -9
  21. package/dist/docs/card-entry.md +37 -6
  22. package/dist/docs/cardholder-document.md +16 -14
  23. package/dist/docs/cart-item.md +1 -1
  24. package/dist/docs/cart.md +8 -8
  25. package/dist/docs/client-profile-fieldset.md +7 -5
  26. package/dist/docs/copy-text.md +84 -0
  27. package/dist/docs/document-field.md +8 -8
  28. package/dist/docs/footer-link-group.md +2 -2
  29. package/dist/docs/header-root.md +1 -1
  30. package/dist/docs/incentives.md +2 -2
  31. package/dist/docs/logo.md +5 -5
  32. package/dist/docs/my-account-profile.md +4 -4
  33. package/dist/docs/navigation-link-list.md +2 -2
  34. package/dist/docs/navigation-link.md +3 -3
  35. package/dist/docs/order-cancel.md +52 -0
  36. package/dist/docs/order-delivery-address.md +63 -0
  37. package/dist/docs/order-delivery-group.md +83 -0
  38. package/dist/docs/order-details-back.md +41 -0
  39. package/dist/docs/order-details-header.md +48 -0
  40. package/dist/docs/order-list-row.md +46 -0
  41. package/dist/docs/order-list-search.md +101 -0
  42. package/dist/docs/order-list-views.md +97 -0
  43. package/dist/docs/order-list.md +94 -0
  44. package/dist/docs/order-payment.md +94 -0
  45. package/dist/docs/order-placed-date.md +49 -0
  46. package/dist/docs/order-placed-payment-summary.md +13 -15
  47. package/dist/docs/order-placed.md +225 -0
  48. package/dist/docs/order-progress.md +88 -0
  49. package/dist/docs/order-status-badge.md +91 -0
  50. package/dist/docs/order-summary.md +53 -0
  51. package/dist/docs/payment-method-badges.md +14 -3
  52. package/dist/docs/place-order.md +13 -9
  53. package/dist/docs/saved-cards.md +2 -2
  54. package/dist/docs/select.md +19 -6
  55. package/dist/docs/session.md +1 -1
  56. package/dist/docs/shipping-address.md +1 -1
  57. package/dist/docs/sign-in-redirect.md +6 -6
  58. package/dist/docs/toast.md +7 -3
  59. package/dist/index.d.ts +6 -2
  60. package/dist/index.js +2 -1
  61. package/dist/internal/client.d.ts +6 -1
  62. package/dist/internal/client.js +7 -2
  63. package/dist/internal/server.d.ts +6 -2
  64. package/dist/internal/server.js +6 -2
  65. package/dist/matter/account-access-gate/account-access-gate.d.ts +2 -1
  66. package/dist/matter/account-access-gate/account-access-gate.js +19 -16
  67. package/dist/matter/account-access-gate/account-access-gate.js.map +1 -1
  68. package/dist/matter/account-address-book/account-address-book-delete.d.ts +60 -0
  69. package/dist/matter/account-address-book/account-address-book-delete.js +184 -0
  70. package/dist/matter/account-address-book/account-address-book-delete.js.map +1 -0
  71. package/dist/matter/account-address-book/account-address-book-deliverability.d.ts +19 -0
  72. package/dist/matter/account-address-book/account-address-book-deliverability.js +50 -0
  73. package/dist/matter/account-address-book/account-address-book-deliverability.js.map +1 -0
  74. package/dist/matter/account-address-book/account-address-book-form-parts.d.ts +42 -0
  75. package/dist/matter/account-address-book/account-address-book-form-parts.js +146 -0
  76. package/dist/matter/account-address-book/account-address-book-form-parts.js.map +1 -0
  77. package/dist/matter/account-address-book/account-address-book-profile-notice.d.ts +25 -0
  78. package/dist/matter/account-address-book/account-address-book-profile-notice.js +72 -0
  79. package/dist/matter/account-address-book/account-address-book-profile-notice.js.map +1 -0
  80. package/dist/matter/account-address-book/account-address-book.d.ts +120 -0
  81. package/dist/matter/account-address-book/account-address-book.js +469 -0
  82. package/dist/matter/account-address-book/account-address-book.js.map +1 -0
  83. package/dist/matter/account-address-book/account-address-country-switch.js +59 -0
  84. package/dist/matter/account-address-book/account-address-country-switch.js.map +1 -0
  85. package/dist/matter/account-address-book/account-address-country.d.ts +36 -0
  86. package/dist/matter/account-address-book/account-address-country.js +151 -0
  87. package/dist/matter/account-address-book/account-address-country.js.map +1 -0
  88. package/dist/matter/account-address-book/account-address-first-line.js +11 -0
  89. package/dist/matter/account-address-book/account-address-first-line.js.map +1 -0
  90. package/dist/matter/account-address-book/account-address-form-context.d.ts +55 -0
  91. package/dist/matter/account-address-book/account-address-form-context.js +14 -0
  92. package/dist/matter/account-address-book/account-address-form-context.js.map +1 -0
  93. package/dist/matter/account-address-book/account-address-form.d.ts +85 -0
  94. package/dist/matter/account-address-book/account-address-form.js +946 -0
  95. package/dist/matter/account-address-book/account-address-form.js.map +1 -0
  96. package/dist/matter/account-address-book/account-address-postal-autofill.js +189 -0
  97. package/dist/matter/account-address-book/account-address-postal-autofill.js.map +1 -0
  98. package/dist/matter/account-address-book/account-address-record.d.ts +26 -0
  99. package/dist/matter/account-address-book/account-address-record.js +138 -0
  100. package/dist/matter/account-address-book/account-address-record.js.map +1 -0
  101. package/dist/matter/account-entry-point/account-entry-point.js +11 -11
  102. package/dist/matter/account-entry-point/account-entry-point.js.map +1 -1
  103. package/dist/matter/account-menu/account-menu.d.ts +7 -3
  104. package/dist/matter/account-menu/account-menu.js +69 -28
  105. package/dist/matter/account-menu/account-menu.js.map +1 -1
  106. package/dist/matter/billing-address/billing-address.d.ts +30 -17
  107. package/dist/matter/billing-address/billing-address.js +128 -33
  108. package/dist/matter/billing-address/billing-address.js.map +1 -1
  109. package/dist/matter/breadcrumb/breadcrumb.js +2 -2
  110. package/dist/matter/breadcrumb/breadcrumb.js.map +1 -1
  111. package/dist/matter/card-entry/card-capture.js +4 -3
  112. package/dist/matter/card-entry/card-capture.js.map +1 -1
  113. package/dist/matter/card-entry/card-entry.d.ts +5 -3
  114. package/dist/matter/card-entry/card-entry.js +77 -27
  115. package/dist/matter/card-entry/card-entry.js.map +1 -1
  116. package/dist/matter/cardholder-document/cardholder-document.d.ts +10 -9
  117. package/dist/matter/cardholder-document/cardholder-document.js +36 -16
  118. package/dist/matter/cardholder-document/cardholder-document.js.map +1 -1
  119. package/dist/matter/cart/cart.d.ts +7 -2
  120. package/dist/matter/cart/cart.js +29 -26
  121. package/dist/matter/cart/cart.js.map +1 -1
  122. package/dist/matter/cart-item/cart-item.js +2 -2
  123. package/dist/matter/cart-item/cart-item.js.map +1 -1
  124. package/dist/matter/client-preferences/client-preferences-fieldset.js +1 -1
  125. package/dist/matter/client-profile-form/client-profile-fieldset.js +8 -5
  126. package/dist/matter/client-profile-form/client-profile-fieldset.js.map +1 -1
  127. package/dist/matter/identity-edit/identity-edit.js +3 -3
  128. package/dist/matter/identity-edit/identity-edit.js.map +1 -1
  129. package/dist/matter/identity-summary/identity-summary.js +2 -2
  130. package/dist/matter/identity-summary/identity-summary.js.map +1 -1
  131. package/dist/matter/my-account-profile/my-account-profile.d.ts +3 -3
  132. package/dist/matter/my-account-profile/my-account-profile.js +4 -4
  133. package/dist/matter/my-account-profile/my-account-profile.js.map +1 -1
  134. package/dist/matter/order-cancel/order-cancel.d.ts +110 -0
  135. package/dist/matter/order-cancel/order-cancel.js +344 -0
  136. package/dist/matter/order-cancel/order-cancel.js.map +1 -0
  137. package/dist/matter/order-delivery-address/order-delivery-address.d.ts +73 -0
  138. package/dist/matter/order-delivery-address/order-delivery-address.js +172 -0
  139. package/dist/matter/order-delivery-address/order-delivery-address.js.map +1 -0
  140. package/dist/matter/order-delivery-group/order-delivery-group.d.ts +128 -0
  141. package/dist/matter/order-delivery-group/order-delivery-group.js +408 -0
  142. package/dist/matter/order-delivery-group/order-delivery-group.js.map +1 -0
  143. package/dist/matter/order-details-header/order-details-header.d.ts +104 -0
  144. package/dist/matter/order-details-header/order-details-header.js +190 -0
  145. package/dist/matter/order-details-header/order-details-header.js.map +1 -0
  146. package/dist/matter/order-list/customer-orders-filter.d.ts +12 -0
  147. package/dist/matter/order-list/customer-orders-filter.js +30 -0
  148. package/dist/matter/order-list/customer-orders-filter.js.map +1 -0
  149. package/dist/matter/order-list/order-list.d.ts +121 -0
  150. package/dist/matter/order-list/order-list.js +395 -0
  151. package/dist/matter/order-list/order-list.js.map +1 -0
  152. package/dist/matter/order-list-row/order-list-row.d.ts +44 -0
  153. package/dist/matter/order-list-row/order-list-row.js +127 -0
  154. package/dist/matter/order-list-row/order-list-row.js.map +1 -0
  155. package/dist/matter/order-list-search/order-list-search.d.ts +72 -0
  156. package/dist/matter/order-list-search/order-list-search.js +296 -0
  157. package/dist/matter/order-list-search/order-list-search.js.map +1 -0
  158. package/dist/matter/order-list-views/order-list-views.d.ts +65 -0
  159. package/dist/matter/order-list-views/order-list-views.js +154 -0
  160. package/dist/matter/order-list-views/order-list-views.js.map +1 -0
  161. package/dist/matter/order-payment/order-payment.d.ts +83 -0
  162. package/dist/matter/order-payment/order-payment.js +258 -0
  163. package/dist/matter/order-payment/order-payment.js.map +1 -0
  164. package/dist/matter/order-placed/order-placed-deliveries.d.ts +145 -0
  165. package/dist/matter/order-placed/order-placed-deliveries.js +380 -0
  166. package/dist/matter/order-placed/order-placed-deliveries.js.map +1 -0
  167. package/dist/matter/order-placed/order-placed.d.ts +122 -0
  168. package/dist/matter/order-placed/order-placed.js +452 -0
  169. package/dist/matter/order-placed/order-placed.js.map +1 -0
  170. package/dist/matter/order-placed-date/order-placed-date.d.ts +45 -0
  171. package/dist/matter/order-placed-date/order-placed-date.js +92 -0
  172. package/dist/matter/order-placed-date/order-placed-date.js.map +1 -0
  173. package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.d.ts +5 -8
  174. package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js +29 -81
  175. package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js.map +1 -1
  176. package/dist/matter/order-progress/order-progress.d.ts +85 -0
  177. package/dist/matter/order-progress/order-progress.js +203 -0
  178. package/dist/matter/order-progress/order-progress.js.map +1 -0
  179. package/dist/matter/order-summary/order-summary.d.ts +81 -0
  180. package/dist/matter/order-summary/order-summary.js +192 -0
  181. package/dist/matter/order-summary/order-summary.js.map +1 -0
  182. package/dist/matter/payment/cardholder-document-rule.d.ts +35 -0
  183. package/dist/matter/payment/cardholder-document-rule.js +35 -0
  184. package/dist/matter/payment/cardholder-document-rule.js.map +1 -0
  185. package/dist/matter/payment/payment-card-capture.js +38 -23
  186. package/dist/matter/payment/payment-card-capture.js.map +1 -1
  187. package/dist/matter/payment/payment-controller.js +11 -0
  188. package/dist/matter/payment/payment-controller.js.map +1 -1
  189. package/dist/matter/payment/payment-method-badges.js +4 -2
  190. package/dist/matter/payment/payment-method-badges.js.map +1 -1
  191. package/dist/matter/payment/payment.js +11 -0
  192. package/dist/matter/payment/payment.js.map +1 -1
  193. package/dist/matter/payment/use-payment-method-selection.d.ts +39 -0
  194. package/dist/matter/payment/use-payment-method-selection.js +30 -2
  195. package/dist/matter/payment/use-payment-method-selection.js.map +1 -1
  196. package/dist/matter/payment/use-payment-submit-gate.d.ts +16 -2
  197. package/dist/matter/payment/use-payment-submit-gate.js +42 -14
  198. package/dist/matter/payment/use-payment-submit-gate.js.map +1 -1
  199. package/dist/matter/place-order/place-order.d.ts +12 -7
  200. package/dist/matter/place-order/place-order.js +126 -103
  201. package/dist/matter/place-order/place-order.js.map +1 -1
  202. package/dist/matter/pricing/pricing.js +5 -5
  203. package/dist/matter/pricing/pricing.js.map +1 -1
  204. package/dist/matter/region/region.js +1 -1
  205. package/dist/matter/saved-cards/saved-cards.js +26 -15
  206. package/dist/matter/saved-cards/saved-cards.js.map +1 -1
  207. package/dist/matter/session/session.js +2 -2
  208. package/dist/matter/session/session.js.map +1 -1
  209. package/dist/matter/shipping-address/country-descriptors.d.ts +1 -0
  210. package/dist/matter/shipping-address/country-descriptors.js +23 -1
  211. package/dist/matter/shipping-address/country-descriptors.js.map +1 -1
  212. package/dist/matter/shipping-address/shipping-address.js +62 -14
  213. package/dist/matter/shipping-address/shipping-address.js.map +1 -1
  214. package/dist/matter/shipping-simulator/shipping-simulator.d.ts +1 -1
  215. package/dist/matter/shipping-simulator/shipping-simulator.js.map +1 -1
  216. package/dist/matter/sign-in-redirect/sign-in-redirect.js +48 -10
  217. package/dist/matter/sign-in-redirect/sign-in-redirect.js.map +1 -1
  218. package/dist/matter/variant-selector/variant-selector.js +2 -2
  219. package/dist/matter/variant-selector/variant-selector.js.map +1 -1
  220. package/dist/particles/address-summary/address-summary.js +2 -2
  221. package/dist/particles/address-summary/address-summary.js.map +1 -1
  222. package/dist/particles/alert-dialog/alert-dialog.d.ts +5 -1
  223. package/dist/particles/alert-dialog/alert-dialog.js +5 -2
  224. package/dist/particles/alert-dialog/alert-dialog.js.map +1 -1
  225. package/dist/particles/copy-text/copy-text.d.ts +28 -0
  226. package/dist/particles/copy-text/copy-text.js +140 -0
  227. package/dist/particles/copy-text/copy-text.js.map +1 -0
  228. package/dist/particles/document-field/document-field.d.ts +34 -5
  229. package/dist/particles/document-field/document-field.js +115 -19
  230. package/dist/particles/document-field/document-field.js.map +1 -1
  231. package/dist/particles/field/field.js +1 -1
  232. package/dist/particles/field/field.js.map +1 -1
  233. package/dist/particles/footer-link-group/footer-link-group.d.ts +6 -2
  234. package/dist/particles/footer-link-group/footer-link-group.js +18 -7
  235. package/dist/particles/footer-link-group/footer-link-group.js.map +1 -1
  236. package/dist/particles/incentives/incentives.d.ts +6 -2
  237. package/dist/particles/incentives/incentives.js +7 -2
  238. package/dist/particles/incentives/incentives.js.map +1 -1
  239. package/dist/particles/logo/logo.d.ts +3 -2
  240. package/dist/particles/logo/logo.js +20 -8
  241. package/dist/particles/logo/logo.js.map +1 -1
  242. package/dist/particles/navigation-link/navigation-link.d.ts +2 -3
  243. package/dist/particles/navigation-link/navigation-link.js +4 -4
  244. package/dist/particles/navigation-link/navigation-link.js.map +1 -1
  245. package/dist/particles/navigation-link-list/navigation-link-list.d.ts +6 -2
  246. package/dist/particles/navigation-link-list/navigation-link-list.js +18 -7
  247. package/dist/particles/navigation-link-list/navigation-link-list.js.map +1 -1
  248. package/dist/particles/order-details-back/order-details-back.d.ts +28 -0
  249. package/dist/particles/order-details-back/order-details-back.js +52 -0
  250. package/dist/particles/order-details-back/order-details-back.js.map +1 -0
  251. package/dist/particles/order-status-badge/order-status-badge.d.ts +19 -0
  252. package/dist/particles/order-status-badge/order-status-badge.js +50 -0
  253. package/dist/particles/order-status-badge/order-status-badge.js.map +1 -0
  254. package/dist/particles/phone-field/phone-field.js +2 -2
  255. package/dist/particles/phone-field/phone-field.js.map +1 -1
  256. package/dist/particles/select/select.js +6 -6
  257. package/dist/particles/select/select.js.map +1 -1
  258. package/dist/particles/toast/toast.d.ts +1 -1
  259. package/dist/particles/toast/toast.js +32 -6
  260. package/dist/particles/toast/toast.js.map +1 -1
  261. package/dist/schema.graphql +1014 -28
  262. package/dist/sdk/actions/address-action-provider.d.ts +16 -0
  263. package/dist/sdk/actions/address-action-provider.js +20 -0
  264. package/dist/sdk/actions/address-action-provider.js.map +1 -0
  265. package/dist/sdk/actions/analytics-action-provider.js +1 -1
  266. package/dist/sdk/actions/index.d.ts +3 -1
  267. package/dist/sdk/actions/index.js +3 -1
  268. package/dist/sdk/actions/order-action-provider.d.ts +12 -0
  269. package/dist/sdk/actions/order-action-provider.js +16 -0
  270. package/dist/sdk/actions/order-action-provider.js.map +1 -0
  271. package/dist/sdk/actions/types.d.ts +6 -2
  272. package/dist/sdk/address/address-fields.js +38 -0
  273. package/dist/sdk/address/address-fields.js.map +1 -0
  274. package/dist/sdk/address/checkout-readiness.js +17 -0
  275. package/dist/sdk/address/checkout-readiness.js.map +1 -0
  276. package/dist/sdk/address/constants.js +60 -0
  277. package/dist/sdk/address/constants.js.map +1 -0
  278. package/dist/sdk/address/country-display.js +19 -0
  279. package/dist/sdk/address/country-display.js.map +1 -0
  280. package/dist/sdk/address/country-rules.js +30 -0
  281. package/dist/sdk/address/country-rules.js.map +1 -0
  282. package/dist/sdk/address/format-address.js +18 -0
  283. package/dist/sdk/address/format-address.js.map +1 -0
  284. package/dist/sdk/address/iso-countries.js +262 -0
  285. package/dist/sdk/address/iso-countries.js.map +1 -0
  286. package/dist/sdk/address/layouts.js +56 -0
  287. package/dist/sdk/address/layouts.js.map +1 -0
  288. package/dist/sdk/address/messages.js +97 -0
  289. package/dist/sdk/address/messages.js.map +1 -0
  290. package/dist/sdk/address/operations.d.ts +54 -0
  291. package/dist/sdk/address/operations.js +83 -0
  292. package/dist/sdk/address/operations.js.map +1 -0
  293. package/dist/sdk/address/postal-code-lookup-operations.js +23 -0
  294. package/dist/sdk/address/postal-code-lookup-operations.js.map +1 -0
  295. package/dist/sdk/address/postal-code.js +11 -0
  296. package/dist/sdk/address/postal-code.js.map +1 -0
  297. package/dist/sdk/address/schema.js +14 -0
  298. package/dist/sdk/address/schema.js.map +1 -0
  299. package/dist/sdk/address/server-fields.js +25 -0
  300. package/dist/sdk/address/server-fields.js.map +1 -0
  301. package/dist/sdk/address/switch-country.js +57 -0
  302. package/dist/sdk/address/switch-country.js.map +1 -0
  303. package/dist/sdk/address/types.d.ts +26 -0
  304. package/dist/sdk/address/use-address-actions.d.ts +29 -0
  305. package/dist/sdk/address/use-address-actions.js +247 -0
  306. package/dist/sdk/address/use-address-actions.js.map +1 -0
  307. package/dist/sdk/address/use-address-by-postal-code.js +57 -0
  308. package/dist/sdk/address/use-address-by-postal-code.js.map +1 -0
  309. package/dist/sdk/address/validate-address.js +62 -0
  310. package/dist/sdk/address/validate-address.js.map +1 -0
  311. package/dist/sdk/cache/storefront-cache.js +29 -4
  312. package/dist/sdk/cache/storefront-cache.js.map +1 -1
  313. package/dist/sdk/client/fetch-page-data.d.ts +11 -0
  314. package/dist/sdk/client/fetch-page-data.js +12 -1
  315. package/dist/sdk/client/fetch-page-data.js.map +1 -1
  316. package/dist/sdk/content/create-content-runtime.js +1 -8
  317. package/dist/sdk/content/create-content-runtime.js.map +1 -1
  318. package/dist/sdk/data/failed-fields.js +23 -0
  319. package/dist/sdk/data/failed-fields.js.map +1 -0
  320. package/dist/sdk/data/index.js +2 -2
  321. package/dist/sdk/data/page-reactive-data-root.d.ts +45 -7
  322. package/dist/sdk/data/page-reactive-data-root.js +88 -12
  323. package/dist/sdk/data/page-reactive-data-root.js.map +1 -1
  324. package/dist/sdk/data/reactive-list-item-data-provider.js +2 -2
  325. package/dist/sdk/generated/fragment-types.js +2 -0
  326. package/dist/sdk/generated/fragment-types.js.map +1 -1
  327. package/dist/sdk/generated/gql.js +3 -1
  328. package/dist/sdk/generated/gql.js.map +1 -1
  329. package/dist/sdk/generated/graphql.d.ts +8 -0
  330. package/dist/sdk/generated/graphql.js +212 -1
  331. package/dist/sdk/generated/graphql.js.map +1 -1
  332. package/dist/sdk/i18n/messages/en-US.js +138 -1
  333. package/dist/sdk/i18n/messages/en-US.json +138 -1
  334. package/dist/sdk/i18n/messages/en-US.json.d.ts +137 -0
  335. package/dist/sdk/i18n/messages/es-ES.js +138 -1
  336. package/dist/sdk/i18n/messages/es-ES.json +138 -1
  337. package/dist/sdk/i18n/messages/pt-BR.js +138 -1
  338. package/dist/sdk/i18n/messages/pt-BR.json +138 -1
  339. package/dist/sdk/navigation/current-page.js +30 -0
  340. package/dist/sdk/navigation/current-page.js.map +1 -0
  341. package/dist/sdk/navigation/not-found-log.d.ts +28 -0
  342. package/dist/sdk/navigation/not-found-log.js +133 -0
  343. package/dist/sdk/navigation/not-found-log.js.map +1 -0
  344. package/dist/sdk/navigation/path.js +25 -0
  345. package/dist/sdk/navigation/path.js.map +1 -0
  346. package/dist/sdk/navigation/redirect.d.ts +11 -0
  347. package/dist/sdk/navigation/redirect.js +22 -0
  348. package/dist/sdk/navigation/redirect.js.map +1 -0
  349. package/dist/sdk/navigation/report.js +70 -0
  350. package/dist/sdk/navigation/report.js.map +1 -0
  351. package/dist/sdk/navigation/resolve-storefront-href.d.ts +12 -0
  352. package/dist/sdk/navigation/resolve-storefront-href.js +214 -0
  353. package/dist/sdk/navigation/resolve-storefront-href.js.map +1 -0
  354. package/dist/sdk/navigation/route-identity-provider.d.ts +11 -0
  355. package/dist/sdk/navigation/route-identity-provider.js +20 -0
  356. package/dist/sdk/navigation/route-identity-provider.js.map +1 -0
  357. package/dist/sdk/navigation/route-map-provider.d.ts +19 -0
  358. package/dist/sdk/navigation/route-map-provider.js +29 -0
  359. package/dist/sdk/navigation/route-map-provider.js.map +1 -0
  360. package/dist/sdk/navigation/storefront-link.d.ts +16 -0
  361. package/dist/sdk/navigation/storefront-link.js +66 -0
  362. package/dist/sdk/navigation/storefront-link.js.map +1 -0
  363. package/dist/sdk/navigation/types.d.ts +45 -0
  364. package/dist/sdk/navigation/use-storefront-navigation.d.ts +26 -0
  365. package/dist/sdk/navigation/use-storefront-navigation.js +73 -0
  366. package/dist/sdk/navigation/use-storefront-navigation.js.map +1 -0
  367. package/dist/sdk/navigation/use-storefront-route.d.ts +26 -0
  368. package/dist/sdk/navigation/use-storefront-route.js +87 -0
  369. package/dist/sdk/navigation/use-storefront-route.js.map +1 -0
  370. package/dist/sdk/navigation/use-storefront-search-params.d.ts +11 -0
  371. package/dist/sdk/navigation/use-storefront-search-params.js +16 -0
  372. package/dist/sdk/navigation/use-storefront-search-params.js.map +1 -0
  373. package/dist/sdk/orders/completion-badge.d.ts +8 -0
  374. package/dist/sdk/orders/completion-badge.js +47 -0
  375. package/dist/sdk/orders/completion-badge.js.map +1 -0
  376. package/dist/sdk/orders/order-operations.d.ts +19 -0
  377. package/dist/sdk/orders/order-operations.js +21 -0
  378. package/dist/sdk/orders/order-operations.js.map +1 -0
  379. package/dist/sdk/orders/use-order-actions.d.ts +23 -0
  380. package/dist/sdk/orders/use-order-actions.js +62 -0
  381. package/dist/sdk/orders/use-order-actions.js.map +1 -0
  382. package/dist/sdk/payment/gateway-origin.js +26 -13
  383. package/dist/sdk/payment/gateway-origin.js.map +1 -1
  384. package/dist/sdk/payment/gateway.d.ts +14 -2
  385. package/dist/sdk/payment/gateway.js +32 -14
  386. package/dist/sdk/payment/gateway.js.map +1 -1
  387. package/dist/sdk/payment/operations.js +11 -0
  388. package/dist/sdk/payment/operations.js.map +1 -1
  389. package/dist/sdk/payment/submission-registry.d.ts +2 -1
  390. package/dist/sdk/payment/submission-registry.js +12 -8
  391. package/dist/sdk/payment/submission-registry.js.map +1 -1
  392. package/dist/sdk/payment/use-payment-actions.d.ts +5 -3
  393. package/dist/sdk/payment/use-payment-actions.js +5 -2
  394. package/dist/sdk/payment/use-payment-actions.js.map +1 -1
  395. package/dist/sdk/payment/use-place-order.d.ts +6 -3
  396. package/dist/sdk/payment/use-place-order.js +333 -143
  397. package/dist/sdk/payment/use-place-order.js.map +1 -1
  398. package/dist/sdk/seo/page-alternates.d.ts +55 -0
  399. package/dist/sdk/seo/page-alternates.js +132 -0
  400. package/dist/sdk/seo/page-alternates.js.map +1 -0
  401. package/dist/utils/own-value.js +19 -0
  402. package/dist/utils/own-value.js.map +1 -0
  403. package/dist/utils/safe-href.d.ts +4 -4
  404. package/dist/utils/safe-href.js +31 -22
  405. package/dist/utils/safe-href.js.map +1 -1
  406. package/package.json +5 -1
  407. package/skills/storefront-asset/SKILL.md +111 -0
  408. package/skills/storefront-asset/references/api-side.md +153 -0
  409. package/skills/storefront-asset/references/findings.md +40 -0
  410. package/skills/storefront-asset/references/ui-side.md +94 -0
  411. package/src/styles/tailwind.css +27 -0
@@ -108,6 +108,7 @@ a form the shopper cannot see.
108
108
  | `billingMatchNoticeLabel` | string | `"Your billing address must match the one on your card or bank statement, or your bank may decline the order."` | Always-on billing-match disclaimer. Gated only by this prop and `billingMatchNoticeVisible` — unlike the two notices above, it never changes with the toggle, the form, `billingAddressRequired`, or a saved address. |
109
109
  | `billingMatchNoticeVisible` | boolean | `true` | Switches the billing-match disclaimer above on or off. A blank `billingMatchNoticeLabel` also renders nothing, even while this is `true` — the two rules never combine into an empty element. |
110
110
  | `fieldRequiredMessage` | string | `"This field is required."` | Shown as an inline field error under a required, blank address field once it has been touched (T38) — see Accessibility Contract below. One prop, not one per field: every rendered field but `complement` shares the same rule. An authored empty or whitespace-only string falls back to this default. |
111
+ | `postalCodeInvalidMessage` | string | `"Enter a valid postal code."` | Shown as an inline field error under a touched, non-blank postal code that does not match the selected country's format (the descriptor's `rule.pattern`, the same one the delivery form enforces). Only the postal code reads this prop; the English default matches every other default on this form, so an author localises it with the rest. A blank postal code reads `fieldRequiredMessage` instead, never this. The message never contains the typed value. An authored empty or whitespace-only string falls back to this default. |
111
112
  | `disabled` | boolean | `false` | Disables the toggle, every form field, the country selector, and the submit button. |
112
113
 
113
114
  **Data:** declares no fragment and no `fetchStrategy`, so it fetches no shopper data. It reads only the
@@ -132,9 +133,9 @@ fields does not prevent that either — there is no `<form>` element anywhere in
132
133
  `required` is real for assistive technology but not wired to anything that blocks a click on a
133
134
  different button in a different component. Since T38 each rendered field (all but `complement`) does
134
135
  announce its own validity once touched — see Accessibility Contract below — but that announcement is
135
- driven by a local blur-tracked state, never by `required`'s own native validity, and it still does not
136
- gate the submit control; the submit gate is `isBillingAddressFormValid`, read at the submit button's
137
- own `disabled`.
136
+ driven by a local touched-field state (blur, or a refused submit focusing the field), never by
137
+ `required`'s own native validity, and it still does not gate the submit control; the submit gate is
138
+ `isBillingAddressFormValid`, read at the submit button's own `disabled`.
138
139
 
139
140
  **The hard block itself lives elsewhere.** This component also publishes the exact same fact the notice
140
141
  renders from onto the shared payment draft (`billingAddressUnsaved`), and T24's submit gate
@@ -154,10 +155,13 @@ stays checked and the shopper never opens the form. It never reacts to the toggl
154
155
  `data-fs-billing-address-match-notice`, and renders as a plain paragraph with no ARIA role — it is a
155
156
  static disclaimer, not a live region reacting to an event.
156
157
 
158
+ **Focus on refusal:** while the custom-address form is open, it registers itself so that when `PlaceOrder` refuses an order because the address was never saved, keyboard focus moves into the form: to the first rendered required field that is still blank; if none is blank, to the first rendered field whose value fails its country's format (a postal code `123` for BRA); and only when every field is filled and well-formed, to the submit control. The field the focus lands on, blank or malformed, is marked touched, so its message (`required` for a blank field, `format` for a malformed one) shows with the focus and no blur is needed. The country selector is never the target, and a disabled field or a disabled submit control (for example while saving) takes no focus. The reason stays in `PlaceOrder`'s existing alert and this component's unsaved-address notice. Focus moves only on the refused click.
159
+
157
160
  **Country adaptivity is entirely data-driven**, reusing the same country descriptors the delivery
158
161
  address step uses: Brazil shows a neighborhood/bairro field, the United States does not, and adding a
159
162
  new country anywhere in this codebase is a data-only change that this component picks up automatically
160
- — never a code change here.
163
+ — never a code change here. The postal code's format is the same data: the descriptor's `rule.pattern`
164
+ gates the submit button and the field error, so a country's format is defined once for both forms.
161
165
 
162
166
  ---
163
167
 
@@ -228,7 +232,7 @@ while the box is unchecked, and an optional inline error.
228
232
  | Required-billing-address note (`data-fs-billing-address-required-note`) | De-emphasized helper text | `text-[12px] text-[#666666]` |
229
233
  | Unsaved-address notice (`data-fs-billing-address-unsaved-notice`) | De-emphasized, non-error helper text | `text-[12px] text-[#666666]` |
230
234
  | Billing-match disclaimer (`data-fs-billing-address-match-notice`) | De-emphasized helper text, first child of the root | `text-[12px] text-[#666666]` |
231
- | Field error (`data-fs-field-error`) | Per-field validation message, shown once a required field is touched and left blank (T38) | `text-[12px] font-medium text-[#B00020]` |
235
+ | Field error (`data-fs-field-error`) | Per-field validation message, shown once a field is touched: a blank required field, or a non-blank postal code that fails the country's format (T38); a refused submit that focuses the field touches it without a blur | `text-[12px] font-medium text-[#B00020]` |
232
236
  | Inline error (`data-fs-billing-address-error`) | Warning-toned alert text | `text-[12px] font-medium text-[#B00020]` |
233
237
  | Placing (`data-fs-billing-address-placing`) | Present while an order-placement sequence is in flight (T28) — distinct from `data-fs-billing-address-pending`, which this component already emits for its own local submit dispatch; the root is also `inert` and `aria-disabled` while placing | `opacity-60 cursor-not-allowed` |
234
238
 
@@ -252,10 +256,14 @@ There is no per-field styling hook beyond the particles' own `data-fs-checkbox-*
252
256
  ## Accessibility Contract
253
257
 
254
258
  **What the platform promises:** every rendered custom-address field (all but `complement`) announces
255
- its own validity once the shopper has touched it — focus, type nothing, and blur a required field, and
256
- it carries `aria-invalid="true"` plus an error message (`fieldRequiredMessage`) associated through
257
- `aria-describedby`; nothing is marked invalid before it is touched, and `complement` — the one optional
258
- field — is never marked invalid. This mirrors `CardEntry`'s own field-level validity mechanism exactly.
259
+ its own validity once the shopper has touched it. A field is touched when the shopper blurs it, or when a
260
+ refused submit moves focus to it (no blur ever comes there). Focus, type nothing, and blur a required
261
+ field, and it carries `aria-invalid="true"` plus an error message (`fieldRequiredMessage`) associated
262
+ through `aria-describedby`; nothing is marked invalid before it is touched, and `complement` — the one
263
+ optional field — is never marked invalid. A postal code that is non-blank but not in the selected country's format
264
+ is marked the same way, with `postalCodeInvalidMessage` as its error; switching country re-judges the
265
+ typed value at once. Blank wins over format: a blank postal code reads `fieldRequiredMessage`, never the
266
+ format message. This mirrors `CardEntry`'s own field-level validity mechanism exactly.
259
267
  Each field also carries its own `Field.Label`, authorable per field. A default `:focus-visible` outline
260
268
  is painted from the platform's own stylesheet on every field in this component.
261
269
 
@@ -70,7 +70,9 @@ While collapsed, `CardEntry` still answers a place-order attempt: it keeps its s
70
70
 
71
71
  Collapsing clears the security code field, and only the security code. The card number, holder name, and expiration survive, so a shopper who switches method and switches back finds what they typed — no credit-card component in this package retains a security code across a visibility change.
72
72
 
73
- The authored `disabled` prop is independent of this: a store that freezes the form with `disabled` sees no change, and a collapsed form may also be `disabled` — neither implies the other.
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
+
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.
74
76
 
75
77
  ---
76
78
 
@@ -78,12 +80,12 @@ The authored `disabled` prop is independent of this: a store that freezes the fo
78
80
 
79
81
  `CardEntry` renders the detected card network's icon at runtime, once the typed number matches a configured payment method's `validator.numberRegex` — the icon name is computed in component code, not read from a schema prop, so the compiler's prop-type-driven icon collection never sees it.
80
82
 
81
- **Any store composing `CardEntry` (or `SavedCards` / `SavedCardOption`) must declare the five network icon names in `global.icons.include`:**
83
+ **Any store composing `CardEntry` (or `SavedCards` / `SavedCardOption`) must declare the six network icon names in `global.icons.include`:**
82
84
 
83
85
  ```json
84
86
  {
85
87
  "icons": {
86
- "include": ["amex", "diners", "elo-card", "mastercard", "visa"]
88
+ "include": ["amex", "diners", "discover", "elo-card", "mastercard", "visa"]
87
89
  }
88
90
  }
89
91
  ```
@@ -94,7 +96,7 @@ The authored `disabled` prop is independent of this: a store that freezes the fo
94
96
  {
95
97
  "icons": {
96
98
  "collection": "ph",
97
- "include": ["amex", "diners", "elo-card", "mastercard", "visa"]
99
+ "include": ["amex", "diners", "discover", "elo-card", "mastercard", "visa"]
98
100
  }
99
101
  }
100
102
  ```
@@ -103,6 +105,34 @@ Copying the first snippet verbatim over an existing `icons` object silently drop
103
105
 
104
106
  Omitting `include` entirely is silent too. The network icon renders as an empty 24×24 box instead of the card mark.
105
107
 
108
+ ## Store setup: response headers
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`.
111
+
112
+ ```json
113
+ {
114
+ "responseHeaders": [
115
+ {
116
+ "routes": ["/checkout"],
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'",
119
+ "Referrer-Policy": "strict-origin-when-cross-origin"
120
+ }
121
+ }
122
+ ]
123
+ }
124
+ ```
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.
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
+ - **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.
130
+ - **`frame-ancestors 'none'`** blanks the page inside any iframe, including an editor preview.
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
+ - **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`.
133
+
134
+ To check a served page, run `node scripts/assert-payment-page-headers.mjs --url <page url> --vault-host https://<account>.vtexvault.com`.
135
+
106
136
  ---
107
137
 
108
138
  ## Components
@@ -124,7 +154,8 @@ The only component. No internal sub-parts are separately schema-addressable.
124
154
  | `cvvPlaceholder` | string | — | CVV field placeholder. |
125
155
  | `cvvDescription` | string | `"The 3-4 digit number on your card"` | Helper text under the CVV field. Empty string renders nothing. |
126
156
  | `numberRequiredMessage` | string | `"Card number is required"` | Shown when the card-number field is left blank. |
127
- | `numberInvalidMessage` | string | `"Enter a valid card number"` | Shown for a Luhn-invalid number, or one that matches no configured method — the same string covers both. |
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. |
128
159
  | `holderNameRequiredMessage` | string | `"Cardholder name is required"` | Shown when the holder-name field is left blank and the detected method requires it. |
129
160
  | `expirationRequiredMessage` | string | `"Expiration date is required"` | Shown when the expiration field is left blank and the detected method requires it. |
130
161
  | `expirationInvalidMessage` | string | `"Enter a valid expiration date"` | Shown for a structurally malformed `MM/YY`. |
@@ -208,7 +239,7 @@ Style `CardEntry`'s root as a vertical stack of fields, matching a typical card
208
239
  | Field inputs (`data-fs-field-control`) | The bordered text input | `border border-[#CCCCCC] rounded-[6px] px-[12px] py-[10px] text-[15px] w-full` |
209
240
  | Field errors (`data-fs-field-error`) | Inline validation message, small and red | `text-[12px] text-[#C8102E] mt-[4px] block` |
210
241
  | CVV helper text (`data-fs-card-entry-cvv-description`) | Small muted line under the CVV field | `text-[12px] text-[#666666] mt-[4px] block` |
211
- | Placing (`data-fs-card-entry-placing`) | Present while an order-placement sequence is in flight (T28); 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` |
242
+ | 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` |
212
243
  | 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` |
213
244
 
214
245
  Styled minimal example:
@@ -1,7 +1,7 @@
1
1
  # CardholderDocument
2
2
 
3
3
  **Category:** commerce
4
- **Purpose:** A single tax-document input (CPF) for the checkout payment step, shown or hidden and marked required by the currently selected payment method's server-driven configuration.
4
+ **Purpose:** A single tax-document input for the checkout payment step. The store's country picks the document (SSN for the United States, CPF for Brazil, SIN for Canada, RFC for Mexico); the currently selected payment method's server-driven configuration shows or hides it and marks it required.
5
5
 
6
6
  ---
7
7
 
@@ -11,12 +11,12 @@ Use these signals to detect that a CardholderDocument block is present. Position
11
11
 
12
12
  A CardholderDocument block is:
13
13
 
14
- - A **single labeled text input**, formatted with dots and a dash like `123.456.789-01` (the CPF mask).
15
- - Labeled **"CPF"** or a similar tax-document label — never "Card number", "Expiration", or "CVV".
14
+ - A **single labeled text input**, formatted like `123.456.789-01` (CPF), `123-45-6789` (SSN), `046-454-286` (SIN) or `ABCD010101AB1` (RFC).
15
+ - Labeled **"CPF"**, **"SSN"**, **"SIN"**, **"RFC"** or a similar tax-document label — never "Card number", "Expiration", or "CVV".
16
16
  - Not accompanied by a network icon, a "•••• 1234" masked number, or any card-brand logo — those belong to `CardEntry` or `SavedCards`, not this block.
17
17
  - Sometimes marked with a required indicator (an asterisk or similar) next to its label; sometimes not — both are valid, since requiredness is server-driven per payment method.
18
18
 
19
- If the image shows a **card-entry form with one extra plain text field formatted like a Brazilian tax ID**, use `CardholderDocument`. Do not use it for the shopper's account/profile document field — that is a different, identity-step component this block never composes with or reads from.
19
+ If the image shows a **card-entry form with one extra plain text field formatted like a tax ID (CPF, SSN, SIN or RFC)**, use `CardholderDocument`. Do not use it for the shopper's account/profile document field — that is a different, identity-step component this block never composes with or reads from.
20
20
 
21
21
  ---
22
22
 
@@ -28,7 +28,7 @@ If the image shows a **card-entry form with one extra plain text field formatted
28
28
 
29
29
  - The shopper's saved profile/identity document (a client-identity or user-profile field) → use the identity-step document component instead. `CardholderDocument` is a payment-time value, deliberately separate — it never reads or writes the stored profile document, because the epic's RFC records that the two may differ.
30
30
  - A generic, data-agnostic tax-document input with no server-driven presence/requiredness → use the `DocumentField` particle directly instead; `CardholderDocument` exists specifically to wire that particle to the selected payment method's validator.
31
- - More than one document type or country → out of scope today. Only CPF renders; see this component's own spec for the recorded deferral.
31
+ - A business document (CNPJ, EIN, BN, the corporate RFC) → not offered; only the four person documents render.
32
32
 
33
33
  ---
34
34
 
@@ -50,7 +50,7 @@ Child order reflects visual order. There is no parent/child relationship for thi
50
50
  **Composition rules:**
51
51
 
52
52
  - Must be inside `PaymentSectionRoot` or `PaymentSectionController`. Outside either, it throws.
53
- - Renders `null` (no DOM at all) when the selected payment method's validator does not mark a document displayable, or when no method is selected yet. This is normal, not an error — most methods most of the time render nothing here.
53
+ - Renders `null` (no DOM at all) when the selected payment method's validator does not mark a document displayable, when no method is selected yet, or when the store's country has no document type (an unlisted country, or no country data). This is normal, not an error — most methods most of the time render nothing here.
54
54
  - Also renders `null` while the card payment is collapsed — the persisted selection is a method that is not a card, or one the section does not serve, and a composed `PaymentMethodList` can bring the card form back (see [[payment]]) — whatever that method's own validator says. When the card comes back, the field re-seeds from the value already typed.
55
55
  - Takes no children; passing any is a no-op.
56
56
 
@@ -60,18 +60,20 @@ Child order reflects visual order. There is no parent/child relationship for thi
60
60
 
61
61
  ### CardholderDocument
62
62
 
63
- The field itself. Renders the `DocumentField` particle for CPF, with presence and requiredness resolved from `usePayment().selectedMethod.validator` (`documentDisplayable` / `documentRequired`) rather than from any prop.
63
+ The field itself. Renders the `DocumentField` particle for the type `usePayment().countryDocumentType` resolves (`USA` SSN, `BRA` CPF, `CAN` SIN, `MEX` RFC), with presence and requiredness resolved from `usePayment().selectedMethod.validator` (`documentDisplayable` / `documentRequired`) rather than from any prop.
64
64
 
65
65
  | Prop | Type | Default | Notes |
66
66
  |------|------|---------|-------|
67
- | `label` | `string` | `'CPF'` | The field's visible label. |
68
- | `placeholder` | `string` | `'000.000.000-00'` | Shown in the empty input as a format hint. |
69
- | `errorMessage` | `string` | `'Invalid CPF'` | Shown inline when the typed value fails CPF check-digit validation on blur. |
67
+ | `label` | `string` | the type's name (`SSN`, `CPF`, `SIN`, `RFC`) | The field's visible label. |
68
+ | `placeholder` | `string` | the type's own (`000-00-0000`, `000.000.000-00`, `000-000-000`, `AAAA000000AAA`) | Shown in the empty input as a format hint. |
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
- No `documentType` prop — this build supports CPF only. No `required` prop — requiredness is always read from the selected method's validator, never authored.
72
+ 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
73
 
74
- **Data:** declares no `fragment` of its own. It reads `selectedMethod`, `draft`, and `setDraftDocument` off the ambient `payment` context that `PaymentSectionRoot` / `PaymentSectionController` already fetches for.
74
+ **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.
75
+
76
+ **Focus on refusal:** while the field is on screen and not `disabled`, it registers itself so that when `PlaceOrder` refuses an order because the document is missing or malformed, keyboard focus moves to the `<input>`. The reason stays in `PlaceOrder`'s existing alert. Focus moves only on the refused click, and never for a refusal the gateway returned. With the field absent or `disabled`, nothing moves.
75
77
 
76
78
  ---
77
79
 
@@ -98,7 +100,7 @@ No `documentType` prop — this build supports CPF only. No `required` prop —
98
100
  ## Common mistakes
99
101
 
100
102
  - **Nesting `CardholderDocument` inside `CardEntry`.** It is a sibling under the same `PaymentSectionRoot`, never a child — `CardEntry` does not accept children.
101
- - **Passing a `documentType`, `required`, `countryCode`, or `document` prop.** None exist. Document type is fixed to CPF; requiredness and presence are always read from the selected method's validator, never authored; the typed value is not a prop at all — it flows into the shared payment draft internally.
103
+ - **Passing a `documentType`, `required`, `countryCode`, or `document` prop.** None exist. The document type follows the store's country; requiredness and presence are always read from the selected method's validator, never authored; the typed value is not a prop at all — it flows into the shared payment draft internally.
102
104
  - **Using this component for the shopper's saved profile document.** That is a different, identity-step field this component never reads from or writes to — the two are intentionally separate, even for the same shopper.
103
105
  - **Expecting it to render outside a `PaymentSectionRoot` / `PaymentSectionController`.** It throws — the same requirement every other payment leaf (`CardEntry`, `Installments`, `SavedCards`, …) has.
104
106
  - **Treating a blank render as broken.** Most of the time, for most payment methods, this component correctly renders nothing — that is the "not displayable" state, not a bug.
@@ -107,7 +109,7 @@ No `documentType` prop — this build supports CPF only. No `required` prop —
107
109
 
108
110
  ## Known limitations
109
111
 
110
- - **CPF only.** The underlying read model carries no document-type or country signal (see this component's own spec for the full, measured deferral) — a store outside Brazil cannot get a different document type from this component today.
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.
111
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.
112
114
 
113
115
  ---
@@ -53,7 +53,7 @@ CartItemRoot
53
53
 
54
54
  **It names itself from what it wraps.** The link adds no `aria-label`, so its accessible name is the image's alt text (`image.altText ?? variant.name`). On a line whose `variant.image` is `null` the leaf renders its children unwrapped instead of wrapping nothing, because an anchor with no content is a keyboard focus stop with no accessible name.
55
55
 
56
- **No usable product URL, no link.** The leaf runs `detailUrl` through `resolveSafeHref`, the same allowlist the navigation particle applies to CMS-authored destinations, and renders its children unwrapped when the destination is blank or refused: `javascript:`, `data:`, protocol-relative, or malformed. The particle gates only `$content.href`, so a platform URL arriving on the `href` prop is this leaf's to validate. Either way the image still shows: the leaf never self-hides, unlike the data-bearing leaves below, because hiding a wrapper would take its content with it. A refusal logs its reason and never the value; a blank URL is ordinary and stays quiet.
56
+ **No usable product URL, no link.** The leaf runs `detailUrl` through `resolveSafeHref`, the same allowlist the navigation particle applies to CMS-authored destinations, and renders its children unwrapped when the destination is blank or refused: `javascript:`, `data:`, protocol-relative, or malformed. A safe `detailUrl` is a logical path: `NavigationLink` prefixes it for the current binding. The particle gates only `$content.href`, so a platform URL arriving on the `href` prop is this leaf's to validate. Either way the image still shows: the leaf never self-hides, unlike the data-bearing leaves below, because hiding a wrapper would take its content with it. A refusal logs its reason and never the value and still renders the children unwrapped; a blank URL is ordinary and stays quiet.
57
57
 
58
58
  Navigation is client-side through the `NavigationLink` particle, which also owns `rel` hardening. The link is same-tab, and `target` is omitted from the props type rather than merely left out of the schema, because an image-only link cannot carry the "(opens in new tab)" cue a `_blank` destination needs.
59
59
 
package/dist/docs/cart.md CHANGED
@@ -65,7 +65,7 @@ What happens after a successful add to cart is a **per-store choice made by comp
65
65
 
66
66
  - **Mini-cart store → `CartOpenOnAdd`.** When the store has a mini-cart drawer, compose `CartOpenOnAdd` as the **parent of the mini-cart `DrawerRoot`** (its single child). It opens the drawer automatically on each successful add, with the new item visible and the count updated. It controls the drawer internally, so **do not set raw `open` / `onOpenChange` on `DrawerRoot`** — those are not authorable props, and the header `DrawerTrigger` plus manual close (Escape / backdrop / close button) keep working through the encapsulated wiring.
67
67
 
68
- - **No-mini-cart store → `CartRedirectOnAdd`.** When the store has **no** mini-cart and adding a product should send the shopper straight to checkout, compose `CartRedirectOnAdd` (and omit the drawer entirely). It navigates to `href` (default `/checkout`) after each successful add. It renders no UI of its own; place it once in the layout.
68
+ - **No-mini-cart store → `CartRedirectOnAdd`.** When the store has **no** mini-cart and adding a product should send the shopper straight to checkout, compose `CartRedirectOnAdd` (and omit the drawer entirely). It navigates to `href` (default the checkout page, `{ "standard": "checkout" }`) after each successful add. It renders no UI of its own; place it once in the layout.
69
69
 
70
70
  The two are **mutually exclusive — compose exactly one**. A store with a mini-cart uses `CartOpenOnAdd` and never `CartRedirectOnAdd`; a store without one uses `CartRedirectOnAdd` and omits the drawer. Both react only to a **successful** add (a failed add or one returning user errors triggers neither).
71
71
 
@@ -87,7 +87,7 @@ CartRoot (layout)
87
87
  ```
88
88
  CartRoot (layout)
89
89
  ├── Header (add-to-cart CTAs elsewhere; no drawer)
90
- └── CartRedirectOnAdd ← navigates to /checkout on a successful add
90
+ └── CartRedirectOnAdd ← navigates to the checkout page on a successful add
91
91
  ```
92
92
 
93
93
  ---
@@ -230,7 +230,7 @@ Neither leaf renders a wrapper or carries spacing, so **order, grouping, and any
230
230
  Continue-shopping is a **non-mutating** control, not a cart action. Which control depends on the surface:
231
231
 
232
232
  - **Inside the mini-cart drawer**, use `CartContinueShopping` — it closes the drawer through the drawer's own contract and dispatches no cart write.
233
- - **On a cart or checkout page** (no drawer to close), use a storefront `NavigationLink` (e.g. `href="/"`) back to browsing. Do **not** place `CartContinueShopping` there: it is a drawer close, and without a `DrawerRoot` ancestor the render fails.
233
+ - **On a cart or checkout page** (no drawer to close), use a storefront `NavigationLink` (e.g. `href={{ page: 'home' }}`) back to browsing. Do **not** place `CartContinueShopping` there: it is a drawer close, and without a `DrawerRoot` ancestor the render fails.
234
234
 
235
235
  ```text
236
236
  CartRoot (layout)
@@ -259,7 +259,7 @@ CartRoot (layout)
259
259
  "popup-body": { "type": "CartList", "children": ["cart-item-template"] },
260
260
  "subtotal-row": { "type": "CartTotal", "props": { "label": "subtotal" } },
261
261
  "total-row": { "type": "CartTotal", "props": { "label": "total" } },
262
- "checkout-btn": { "type": "CartGoCheckout", "props": { "href": "/checkout", "children": "continuar" } },
262
+ "checkout-btn": { "type": "CartGoCheckout", "props": { "href": { "standard": "checkout" }, "children": "continuar" } },
263
263
 
264
264
  "cart-empty": { "type": "CartEmpty", "children": ["empty-illustration", "empty-msg", "empty-footer"] },
265
265
  "empty-illustration": { "type": "Icon", "props": { "name": "shopping-bag" } },
@@ -275,7 +275,7 @@ On a cart/checkout page there is no drawer to close, so the empty branch keeps `
275
275
  {
276
276
  "cart-empty": { "type": "CartEmpty", "children": ["empty-msg", "keep-shopping-link"] },
277
277
  "empty-msg": { "type": "CartEmptyMessage", "props": { "text": "sua cesta está vazia" } },
278
- "keep-shopping-link": { "type": "NavigationLink", "props": { "href": "/", "children": "continuar comprando" } }
278
+ "keep-shopping-link": { "type": "NavigationLink", "props": { "href": { "page": "home" }, "children": "continuar comprando" } }
279
279
  }
280
280
  ```
281
281
 
@@ -307,7 +307,7 @@ The mini-cart drawer (the layout composition described on `CartRoot`) ends in a
307
307
 
308
308
  - **`CartCheckoutGuard`** is the outer wrapper. It reads cart availability and, while any line item is not `AVAILABLE`, makes its whole subtree non-interactive (`inert` + `aria-disabled`) and exposes `data-fs-cart-checkout-blocked` for styling the disabled state. The shopper cannot proceed with an undeliverable item. It updates reactively from cache — no refetch, no reload — so the block clears the moment the offending line is removed or becomes available.
309
309
  - **`CartTotal`** sits inside the guard, on or next to the button, so the grand total the shopper is about to pay is visible at the CTA. It reads the nearest `CartRoot`/`CartTotalizerRoot` and reformats reactively on every cart change.
310
- - **`CartGoCheckout`** is the link to checkout (default `href` `/checkout`). During a **client-side** route transition it surfaces a loading state on its content wrapper — `aria-busy` plus `data-fs-cart-go-checkout-pending` — so the shopper sees the click registered. There is **no built-in spinner**: opt into one by styling that attribute (or composing a `Spinner` on it). For an **external or hard** checkout navigation (a non-Next route, a different origin, or a full page load — common for the real VTEX checkout) there is no client-side transition window, so the loading state simply does not show. That is the documented, graceful no-op, not a bug.
310
+ - **`CartGoCheckout`** is the link to checkout (default `href` the checkout page, `{ "standard": "checkout" }`). During a **client-side** route transition it surfaces a loading state on its content wrapper — `aria-busy` plus `data-fs-cart-go-checkout-pending` — so the shopper sees the click registered. There is **no built-in spinner**: opt into one by styling that attribute (or composing a `Spinner` on it). For an **external or hard** checkout navigation (a non-Next route, a different origin, or a full page load — common for the real VTEX checkout) there is no client-side transition window, so the loading state simply does not show. That is the documented, graceful no-op, not a bug.
311
311
 
312
312
  **The button wording is CMS content.** It resolves in a fixed order: the `cart-checkout-label` entry, then the `label` prop, then `children`, then the package default `"Checkout"`. So a merchant rewords the CTA — `"Finalizar compra"`, `"Ir para o pagamento"` — with a CMS save and no deployment, while a store with no CMS binding renders its authored value. `children` stays supported because that is where stores labelled the button before `label` existed; a CMS entry overrides it with no schema edit. A blank or whitespace-only entry value counts as unconfigured and falls through. Non-compiler hosts (Storybook, tests) pass a typed `$content` fixture directly.
313
313
 
@@ -315,7 +315,7 @@ The mini-cart drawer (the layout composition described on `CartRoot`) ends in a
315
315
 
316
316
  | Prop | Type | Required | Notes |
317
317
  |-------|------|----------|-------|
318
- | `href` | string | no | Checkout destination, default `/checkout`. Never content-editable |
318
+ | `href` | page reference or string | no | Checkout destination, default `{ "standard": "checkout" }`. A string is a logical path or an off-site URL. Never content-editable |
319
319
  | `label` | string | no | Authored fallback for the wording. Ignored when an entry supplies a label |
320
320
  | `children` | node | no | Legacy label channel, still honoured. Element children are replaced when an entry supplies a label |
321
321
 
@@ -332,7 +332,7 @@ Schema shape (inside the `DrawerPopup` footer `Container`):
332
332
  "popup-footer": { "type": "Container", "children": ["checkout-cta"] },
333
333
  "checkout-cta": { "type": "CartCheckoutGuard", "children": ["checkout-total", "checkout-btn"] },
334
334
  "checkout-total": { "type": "CartTotal", "props": { "label": "Total" } },
335
- "checkout-btn": { "type": "CartGoCheckout", "props": { "href": "/checkout", "label": "Finalizar compra" } }
335
+ "checkout-btn": { "type": "CartGoCheckout", "props": { "href": { "standard": "checkout" }, "label": "Finalizar compra" } }
336
336
  }
337
337
  ```
338
338
 
@@ -1,7 +1,7 @@
1
1
  # ClientProfileFieldset
2
2
 
3
3
  **Category:** identity
4
- **Purpose:** The composable, one-Save write of the `ClientProfile` entity. Registers itself with the enclosing `FormRoot` under the `clientProfile` namespace and dispatches at most one `identity.clientProfileUpdate` when the shopper presses that form's submit. Four bound controls — first name, last name, phone, document — compose freely inside it, in any order or subset.
4
+ **Purpose:** The composable, one-Save write of the `ClientProfile` entity. Registers itself with the enclosing `FormRoot` under the `clientProfile` namespace and dispatches at most one `identity.clientProfileUpdate` when the shopper presses that form's submit. Four bound controls — first name, last name, phone, document (CPF, SSN, SIN or RFC) — compose freely inside it, in any order or subset.
5
5
 
6
6
  ---
7
7
 
@@ -65,7 +65,7 @@ SessionRoot (required ancestor; session tri-state +
65
65
  | Prop | Type | Default | Notes |
66
66
  |------|------|---------|-------|
67
67
  | `country` | `'US' \| 'BR'` | `'US'` | Phone mask/validation country, provided to the phone control via context. |
68
- | `documentType` | string | — | e.g. `'CPF'`. The document control renders only when supported. |
68
+ | `documentType` | string | — | One of `'CPF'`, `'SSN'`, `'SIN'` or `'RFC'` (upper case). The document control renders only when supported, and the payload carries `document` only for a supported type. |
69
69
  | `skeletonCount` | number | `4` | Placeholder rows drawn while the profile resolves. Set it to the number of controls composed. |
70
70
  | `loadingLabel` | string | `'Loading your details'` | Announced politely while the profile resolves. Blank means no announcement. |
71
71
  | `loadedLabel` | string | `'Your details are ready'` | Announced politely once the controls mount. Blank means no announcement. |
@@ -105,12 +105,14 @@ governs visibility (see *Switching the phone field off* below).
105
105
 
106
106
  | Prop | Type | Default | Notes |
107
107
  |------|------|---------|-------|
108
- | `label` | string | `'CPF'` | |
108
+ | `label` | string | the document type's name (`'CPF'`, `'SSN'`, `'SIN'` or `'RFC'`) | |
109
109
  | `placeholder` | string | — | |
110
110
  | `errorMessage` | string | — | |
111
111
 
112
- Renders nothing, and registers no field name, when the fieldset's `documentType` is unsupported. Composes
113
- the `DocumentField` particle. Recomposable (RFC:503): given children, they replace `DocumentField`'s
112
+ Renders nothing, and registers no field name, when the fieldset's `documentType` is unsupported. The mask,
113
+ the validation and the `autocomplete` hint (`off` for SSN and SIN) come from the document type; the saved
114
+ `document` string is the type's sanitised value (digits for CPF, SSN and SIN, letters kept for RFC), the
115
+ same string the card form sends. Composes the `DocumentField` particle. Recomposable (RFC:503): given children, they replace `DocumentField`'s
114
116
  default `Field.Label` + `DocumentFieldInput` + `Field.Error` anatomy, in any order; childless keeps
115
117
  today's order and text.
116
118
 
@@ -0,0 +1,84 @@
1
+ # CopyText
2
+
3
+ **Category:** action
4
+ **Purpose:** Copies one string the caller supplies and confirms the result inline.
5
+
6
+ ---
7
+
8
+ ## Visual cues (how to identify in an image)
9
+
10
+ A small action beside an identifier, with a short confirmation that appears after the action and can be dismissed. The image is the source of truth for layout.
11
+
12
+ ## When to use
13
+
14
+ Any screen that needs one action to copy a single string, such as an order number.
15
+
16
+ ## When NOT to use
17
+
18
+ - Rendering the identifier itself. Pass the string in; do not ask `CopyText` to display the heading.
19
+ - A toast or a page-level notification. The confirmation stays with the action.
20
+
21
+ ---
22
+
23
+ ## Composition
24
+
25
+ ```
26
+ CopyText
27
+ ```
28
+
29
+ `CopyText` is one element. The caller passes the visible label or icon as `children`.
30
+
31
+ ## Components
32
+
33
+ ### CopyText
34
+
35
+ | Prop | Type | Default | Purpose |
36
+ |---|---|---|---|
37
+ | `accessibleName` | string | `Copy` | Accessible name of the action |
38
+ | `successMessage` | string | `Copied` | Announced after a successful copy |
39
+ | `failureMessage` | string | `Could not copy` | Announced when the clipboard rejects the write |
40
+ | `dismissLabel` | string | `Dismiss` | Accessible name of the dismiss control |
41
+
42
+ `text` is required and is not a schema prop. The caller supplies the exact string to copy. `children` is the visible label or icon, and it is not a schema prop either.
43
+
44
+ ---
45
+
46
+ ## Canonical schema example
47
+
48
+ ```json
49
+ {
50
+ "copy-identifier": {
51
+ "type": "CopyText",
52
+ "props": {
53
+ "accessibleName": "Copy order number",
54
+ "successMessage": "Copied",
55
+ "failureMessage": "Could not copy",
56
+ "dismissLabel": "Dismiss"
57
+ },
58
+ "children": []
59
+ }
60
+ }
61
+ ```
62
+
63
+ The screen that owns the identifier passes `text` and `children` at runtime. Do not author the identifier in the page.
64
+
65
+ ## Common mistakes
66
+
67
+ - **OrderDetailsHeader** renders the number. `CopyText` only copies the string it is given.
68
+ - Passing the heading, including a prefix such as "Order #", copies that whole string. Pass the identifier alone.
69
+
70
+ ---
71
+
72
+ ## Styling
73
+
74
+ | Component | What to style | Plausible classes |
75
+ |---|---|---|
76
+ | `CopyText` | The action and the inline confirmation | `inline-flex items-center gap-[8px] text-[14px]` |
77
+
78
+ Style the hooks `data-fs-copy-text`, `data-fs-copy-text-action`, `data-fs-copy-text-message`, and `data-fs-copy-text-outcome`. The component ships no CSS.
79
+
80
+ ---
81
+
82
+ ## Related
83
+
84
+ - [[button]] — the action primitive this control composes.
@@ -1,14 +1,14 @@
1
1
  # DocumentField
2
2
 
3
3
  **Category:** content
4
- **Purpose:** A presentational tax-document input that composes the `Field` particle (label + native `<input>` + inline error). It applies a locale-specific mask on every change (e.g. CPF `###.###.###-##`) and runs check-digit validation on blur/submit. It is data-agnostic — value flows through props; it consumes no GraphQL and no domain context.
4
+ **Purpose:** A presentational tax-document input that composes the `Field` particle (label + native `<input>` + inline error). It applies the mask of its document type on every change (CPF `###.###.###-##`, SSN `###-##-####`, SIN `###-###-###`, or RFC, thirteen upper-case letters and digits) and runs that type's validation on blur/submit. It is data-agnostic — value flows through props; it consumes no GraphQL and no domain context.
5
5
 
6
6
  ---
7
7
 
8
8
  ## Visual cues (how to identify in an image)
9
9
 
10
- - A single-line text input labelled **"CPF"** (or another tax-document name), usually on a checkout identification step, near the email/phone fields.
11
- - Shows a masked placeholder like `000.000.000-00` and formats digits as they are typed.
10
+ - A single-line text input labelled **"CPF"**, **"SSN"**, **"SIN"** or **"RFC"** (or another tax-document name), usually on a checkout identification step, near the email/phone fields.
11
+ - Shows a masked placeholder like `000.000.000-00` (CPF), `000-00-0000` (SSN), `000-000-000` (SIN) or `AAAA000000AAA` (RFC) and formats characters as they are typed.
12
12
  - When invalid, an inline error below the input (e.g. *"Enter a valid CPF."*).
13
13
 
14
14
  If the image shows a checkout identification step with a tax-document field, use `DocumentField`.
@@ -61,15 +61,15 @@ react-hook-form and loses the mask — unsupported, the RFC's named double-binde
61
61
  | `label` | string | — | Accessible label. |
62
62
  | `placeholder` | string | — | Input placeholder. |
63
63
  | `disabled` | boolean | `false` | Disables the input (e.g. while a write is in flight). |
64
- | `requirement` | `'mandatory' \| 'optional'` | — | Raises the field to required, announced as `aria-required` (never the native attribute). Unset is no opinion, which is what keeps CPF Optional by Recommendation, unlike email. Bound to a fieldset whose rule already says required, `'optional'` does not lower it. |
64
+ | `requirement` | `'mandatory' \| 'optional'` | — | Raises the field to required, announced as `aria-required` (never the native attribute). Unset is no opinion, which is what keeps the document Optional by Recommendation, unlike email. Bound to a fieldset whose rule already says required, `'optional'` does not lower it. |
65
65
  | `name` | string | `'document'` | Field/input name. |
66
- | `documentType` | `'CPF'` | `'CPF'` | Selects the mask + validator + digit-only input mode. |
66
+ | `documentType` | `'CPF' \| 'SSN' \| 'SIN' \| 'RFC'` | `'CPF'` | Selects the mask, sanitiser, validator, digit-only input mode and `autocomplete`. `DOCUMENTS` holds one entry per type; the API's lower-case ids (`cpf`, `ssn`, `sin`, `rfc`) go through `documentTypeFromId`. |
67
67
  | `ref` | `Ref<HTMLInputElement>` | — | Lands on the `<input>` `Field.Control` renders — **not on the wrapper `<div>`, as it did before** (a deliberate, source-breaking change). Composed with react-hook-form's own ref on the bound path — a caller ref and react-hook-form's ref are both honoured. |
68
68
  | `children` | `ReactNode` | — | Given, replaces the default `Field.Label` + `DocumentFieldInput` + `Field.Error` anatomy, in any order (RFC:503). |
69
69
 
70
- **Masking:** applied progressively on every change; input is never blocked. Digit-only masks (CPF) strip non-digits and hint `inputMode="numeric"`.
70
+ **Masking:** applied progressively on every change; input is never blocked. The type's sanitiser runs first: digit-only types (CPF, SSN, SIN) strip non-digits and hint `inputMode="numeric"`; RFC upper-cases and keeps only `A-Z` and `0-9`, and carries no `inputMode`. SSN and SIN inputs carry `autocomplete="off"` so the browser does not offer the number back; CPF and RFC carry no `autocomplete` attribute. The attribute is a request, not a guarantee.
71
71
 
72
- **Validation:** the check digit is checked on blur/submit only — never per keystroke. An **empty** value is valid (the field is optional). A prior error clears while the shopper edits and is re-evaluated on the next blur.
72
+ **Validation:** the type's rule (CPF check digits; SSN area, group and serial ranges; SIN Luhn check; RFC structure with a plausible month and day) is checked on blur/submit only — never per keystroke. An **empty** value is valid (the field is optional). A prior error clears while the shopper edits and is re-evaluated on the next blur.
73
73
 
74
74
  ---
75
75
 
@@ -82,7 +82,7 @@ runs the plain, unbound behaviour documented above, unaltered.
82
82
  - **What the contract supplies**: `label` and `placeholder`, when the particle's own prop is omitted (an
83
83
  explicit prop always wins); `defaultValue`, seeded into `useController`; and `rule`, merged with the
84
84
  particle's own check-digit validator (below).
85
- - **What stays the particle's**: the CPF mask, `documentType`, and the `errorMessage` copy.
85
+ - **What stays the particle's**: the mask of the `documentType`, the `documentType` itself, and the `errorMessage` copy.
86
86
  - **Single binder, real contract for the read-only parts (RFC:503)**: the composite remains the sole
87
87
  binder for its field — `useController` is called once, here. Its default (and a recomposed) anatomy's
88
88
  input is `DocumentFieldInput`, which renders the raw Base UI `Field.Control` directly rather than this
@@ -58,7 +58,7 @@ It renders **both responsive forms at once**, each under its own hook: an accord
58
58
  | Prop | Type | Required | Notes |
59
59
  |-------|------|----------|-------|
60
60
  | `heading` | string | no | Authored fallback. Ignored when a CMS entry supplies a heading |
61
- | `links` | array | no | Authored fallback list of `{ label, href, target? }`. Ignored when a CMS entry supplies `links` |
61
+ | `links` | array | no | Authored fallback list of `{ label, href, target? }`. An item `href` may be a page reference or a logical path. Ignored when a CMS entry supplies `links` |
62
62
 
63
63
  Content model (`footer-link-group`) fields, edited in the CMS:
64
64
 
@@ -67,7 +67,7 @@ Content model (`footer-link-group`) fields, edited in the CMS:
67
67
  | `heading` | string | no | The group heading and the accordion trigger's accessible name. Optional so a links-only entry falls back to the authored heading instead of omitting the group. A group with no heading resolved from either channel renders nothing |
68
68
  | `links` | array | no | Ordered links. Reordering here reorders the rendered list with no deployment. Optional so a heading-only entry falls back to the authored list instead of omitting the group |
69
69
  | `links[].label` | string | yes | Link text. A blank label drops that link — an anchor with no name is unusable |
70
- | `links[].href` | string | yes | Destination. `http:`, `https:`, `mailto:`, `tel:`, or a path starting with a single `/` |
70
+ | `links[].href` | string | yes | A `uri-reference` string: `http:`, `https:`, `mailto:`, `tel:`, or a path starting with a single `/`. The binding prefix is applied at render |
71
71
  | `links[].target` | `_self` \| `_blank` | no | `_blank` opens a new tab and adds `rel="noopener noreferrer"` automatically |
72
72
 
73
73
  ---
@@ -80,7 +80,7 @@ A layout whose root holds a `HeaderRoot` and the page `Slot` beside it, with a l
80
80
  },
81
81
  "header-logo": {
82
82
  "type": "Logo",
83
- "props": { "src": "/logo.svg", "alt": "Loja XYZ", "href": "/" }
83
+ "props": { "src": "/logo.svg", "alt": "Loja XYZ", "href": { "page": "home" } }
84
84
  },
85
85
  "header-nav": {
86
86
  "type": "NavigationMenuRoot",
@@ -64,7 +64,7 @@ FooterRoot
64
64
 
65
65
  | Prop | Type | Required | Notes |
66
66
  |-------|------|----------|-------|
67
- | `items` | array | no | Authored fallback list of `{ title, firstLineText?, secondLineText?, href?, icon?, iconUrl?, alt? }`. Ignored when a CMS entry supplies `items` |
67
+ | `items` | array | no | Authored fallback list of `{ title, firstLineText?, secondLineText?, href?, icon?, iconUrl?, alt? }`. An item `href` may be a page reference or a logical path. Ignored when a CMS entry supplies `items` |
68
68
 
69
69
  Content model (`incentives`) fields, edited in the CMS:
70
70
 
@@ -74,7 +74,7 @@ Content model (`incentives`) fields, edited in the CMS:
74
74
  | `items[].title` | string | yes | The benefit's short bold label. The only required field per item; a blank one drops that item |
75
75
  | `items[].firstLineText` | string | no | The first line of supporting copy. Optional, so a title-only item is legal; a blank one renders no line |
76
76
  | `items[].secondLineText` | string | no | The second line. Absent or blank renders no element, so an item shows zero, one, or two lines |
77
- | `items[].href` | string | no | The block's destination. Optional, because a benefit strip links nowhere and a shortcut row links everywhere. Wraps the whole block — glyph included — in a same-tab link. Absent or blank renders the item unlinked; a value the render-time allowlist refuses also renders it unlinked, keeping the glyph and copy |
77
+ | `items[].href` | string | no | A `uri-reference` string. Optional, because a benefit strip links nowhere and a shortcut row links everywhere. Wraps the whole block — glyph included — in a same-tab link. Absent or blank renders the item unlinked; a value the render-time allowlist refuses also renders it unlinked, keeping the glyph and copy. A safe string receives the binding prefix at render |
78
78
  | `items[].icon` | enum | no | One of `truck`, `calendar`, `gift`, `store`, `shield-check`. Renders the collection glyph, decorative |
79
79
  | `items[].iconUrl` | string | no | An uploaded image, for a benefit the predefined set has no glyph for. Wins over `icon` when both are set |
80
80
  | `items[].alt` | string | no | Alt text for an uploaded image. Defaults to empty, keeping the image decorative — the visible title beside it is already the item's accessible content, so repeating it would announce the same words twice |