@vtex/faststore 0.0.10 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (506) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/README.md +0 -1
  3. package/dist/actions.json +6 -1
  4. package/dist/catalog.json +789 -1701
  5. package/dist/cli/index.d.ts +66 -28
  6. package/dist/cli/index.js +7371 -512
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/cli/server-runtime.js +41 -60
  9. package/dist/cli/server-runtime.js.map +1 -1
  10. package/dist/client.d.ts +3 -3
  11. package/dist/client.js +2 -2
  12. package/dist/components.d.ts +63 -57
  13. package/dist/components.js +60 -54
  14. package/dist/content-types.json +5785 -754
  15. package/dist/core/dist/define-component.d.ts +1 -1
  16. package/dist/core/dist/define-content-type.d.ts +50 -2
  17. package/dist/core/dist/define-content-type.js +107 -3
  18. package/dist/core/dist/define-content-type.js.map +1 -1
  19. package/dist/core/dist/index.d.ts +2 -2
  20. package/dist/docs/access-code-field.md +1 -1
  21. package/dist/docs/access-code-sign-in.md +126 -77
  22. package/dist/docs/account-address-book.md +210 -95
  23. package/dist/docs/account-menu.md +14 -15
  24. package/dist/docs/account-saved-cards.md +44 -39
  25. package/dist/docs/alert-dialog.md +3 -1
  26. package/dist/docs/avatar.md +4 -2
  27. package/dist/docs/billing-address.md +99 -30
  28. package/dist/docs/binding-switcher.md +5 -2
  29. package/dist/docs/buy-button.md +7 -8
  30. package/dist/docs/card-entry.md +39 -26
  31. package/dist/docs/card-summary.md +18 -8
  32. package/dist/docs/cardholder-document.md +5 -3
  33. package/dist/docs/carousel.md +5 -4
  34. package/dist/docs/cart-destination.md +39 -26
  35. package/dist/docs/cart-item.md +29 -14
  36. package/dist/docs/cart-totalizer.md +7 -5
  37. package/dist/docs/cart.md +135 -41
  38. package/dist/docs/challenge-return.md +135 -0
  39. package/dist/docs/client-preferences-fieldset.md +10 -5
  40. package/dist/docs/client-preferences.md +31 -8
  41. package/dist/docs/client-profile-fieldset.md +20 -6
  42. package/dist/docs/client-profile.md +12 -3
  43. package/dist/docs/copy-text.md +9 -7
  44. package/dist/docs/document-field.md +1 -1
  45. package/dist/docs/email-field.md +2 -1
  46. package/dist/docs/email-identification.md +12 -2
  47. package/dist/docs/footer-copyright.md +4 -2
  48. package/dist/docs/form.md +54 -18
  49. package/dist/docs/free-shipping-progress.md +6 -5
  50. package/dist/docs/identity-edit.md +8 -2
  51. package/dist/docs/identity-summary.md +18 -5
  52. package/dist/docs/installments.md +46 -32
  53. package/dist/docs/my-account-profile.md +16 -11
  54. package/dist/docs/navigation-link.md +5 -3
  55. package/dist/docs/order-cancel.md +3 -1
  56. package/dist/docs/order-delivery-address.md +7 -5
  57. package/dist/docs/order-delivery-group.md +1 -3
  58. package/dist/docs/order-details-back.md +1 -1
  59. package/dist/docs/order-details-header.md +1 -4
  60. package/dist/docs/order-invoice-download.md +60 -0
  61. package/dist/docs/order-list-row.md +1 -1
  62. package/dist/docs/order-list-search.md +13 -20
  63. package/dist/docs/order-list-views.md +11 -17
  64. package/dist/docs/order-list.md +12 -5
  65. package/dist/docs/order-payment.md +9 -7
  66. package/dist/docs/order-placed-date.md +1 -1
  67. package/dist/docs/order-placed-payment-summary.md +28 -15
  68. package/dist/docs/order-placed.md +49 -14
  69. package/dist/docs/order-progress.md +1 -1
  70. package/dist/docs/order-status-badge.md +20 -9
  71. package/dist/docs/order-summary.md +2 -2
  72. package/dist/docs/order-tracking-link.md +58 -0
  73. package/dist/docs/payment-method-badges.md +30 -4
  74. package/dist/docs/payment-methods.md +1 -1
  75. package/dist/docs/payment.md +36 -17
  76. package/dist/docs/phone-field.md +4 -4
  77. package/dist/docs/place-order.md +84 -36
  78. package/dist/docs/postal-code-field.md +3 -1
  79. package/dist/docs/pricing.md +21 -23
  80. package/dist/docs/product-gallery.md +19 -20
  81. package/dist/docs/product-information.md +13 -9
  82. package/dist/docs/product-list.md +7 -6
  83. package/dist/docs/product-shelf.md +0 -1
  84. package/dist/docs/promotion.md +4 -2
  85. package/dist/docs/region.md +23 -15
  86. package/dist/docs/save-card.md +7 -6
  87. package/dist/docs/saved-cards.md +65 -36
  88. package/dist/docs/shipping-address.md +57 -21
  89. package/dist/docs/shipping-simulator.md +53 -15
  90. package/dist/docs/sign-in-disclosure.md +176 -0
  91. package/dist/docs/sign-in-form.md +78 -47
  92. package/dist/docs/sign-in-redirect.md +4 -2
  93. package/dist/docs/sign-in.md +173 -0
  94. package/dist/docs/toast.md +15 -4
  95. package/dist/docs/variant-selector.md +15 -11
  96. package/dist/graphql/types.d.ts +4 -14
  97. package/dist/index.d.ts +2 -2
  98. package/dist/internal/client.d.ts +1 -3
  99. package/dist/internal/client.js +1 -1
  100. package/dist/internal/server.d.ts +7 -4
  101. package/dist/internal/server.js +7 -4
  102. package/dist/matter/access-code-sign-in/access-code-sign-in.d.ts +250 -66
  103. package/dist/matter/access-code-sign-in/access-code-sign-in.js +459 -188
  104. package/dist/matter/access-code-sign-in/access-code-sign-in.js.map +1 -1
  105. package/dist/matter/account-address-book/account-address-book-delete.d.ts +78 -40
  106. package/dist/matter/account-address-book/account-address-book-delete.js +86 -50
  107. package/dist/matter/account-address-book/account-address-book-delete.js.map +1 -1
  108. package/dist/matter/account-address-book/account-address-book-deliverability.d.ts +21 -4
  109. package/dist/matter/account-address-book/account-address-book-deliverability.js +45 -17
  110. package/dist/matter/account-address-book/account-address-book-deliverability.js.map +1 -1
  111. package/dist/matter/account-address-book/account-address-book-form-parts.d.ts +74 -19
  112. package/dist/matter/account-address-book/account-address-book-form-parts.js +77 -26
  113. package/dist/matter/account-address-book/account-address-book-form-parts.js.map +1 -1
  114. package/dist/matter/account-address-book/account-address-book-profile-notice.d.ts +27 -6
  115. package/dist/matter/account-address-book/account-address-book-profile-notice.js +55 -28
  116. package/dist/matter/account-address-book/account-address-book-profile-notice.js.map +1 -1
  117. package/dist/matter/account-address-book/account-address-book.d.ts +67 -14
  118. package/dist/matter/account-address-book/account-address-book.js +74 -33
  119. package/dist/matter/account-address-book/account-address-book.js.map +1 -1
  120. package/dist/matter/account-address-book/account-address-country-switch.js +3 -3
  121. package/dist/matter/account-address-book/account-address-country-switch.js.map +1 -1
  122. package/dist/matter/account-address-book/account-address-country.d.ts +66 -20
  123. package/dist/matter/account-address-book/account-address-country.js +83 -49
  124. package/dist/matter/account-address-book/account-address-country.js.map +1 -1
  125. package/dist/matter/account-address-book/account-address-form-context.d.ts +8 -4
  126. package/dist/matter/account-address-book/account-address-form-context.js.map +1 -1
  127. package/dist/matter/account-address-book/account-address-form.d.ts +468 -45
  128. package/dist/matter/account-address-book/account-address-form.js +518 -155
  129. package/dist/matter/account-address-book/account-address-form.js.map +1 -1
  130. package/dist/matter/account-address-book/account-address-record.d.ts +27 -6
  131. package/dist/matter/account-address-book/account-address-record.js +32 -17
  132. package/dist/matter/account-address-book/account-address-record.js.map +1 -1
  133. package/dist/matter/account-menu/account-menu.d.ts +34 -17
  134. package/dist/matter/account-menu/account-menu.js +46 -54
  135. package/dist/matter/account-menu/account-menu.js.map +1 -1
  136. package/dist/matter/account-menu-identity/account-menu-identity.js +1 -1
  137. package/dist/matter/account-saved-cards/account-saved-cards.d.ts +108 -28
  138. package/dist/matter/account-saved-cards/account-saved-cards.js +177 -122
  139. package/dist/matter/account-saved-cards/account-saved-cards.js.map +1 -1
  140. package/dist/matter/billing-address/billing-address.d.ts +156 -74
  141. package/dist/matter/billing-address/billing-address.js +227 -156
  142. package/dist/matter/billing-address/billing-address.js.map +1 -1
  143. package/dist/matter/breadcrumb/breadcrumb.d.ts +21 -3
  144. package/dist/matter/breadcrumb/breadcrumb.js +24 -9
  145. package/dist/matter/breadcrumb/breadcrumb.js.map +1 -1
  146. package/dist/matter/buy-button/buy-button.d.ts +8 -11
  147. package/dist/matter/buy-button/buy-button.js +10 -19
  148. package/dist/matter/buy-button/buy-button.js.map +1 -1
  149. package/dist/matter/card-entry/card-capture.js +12 -4
  150. package/dist/matter/card-entry/card-capture.js.map +1 -1
  151. package/dist/matter/card-entry/card-entry.d.ts +123 -32
  152. package/dist/matter/card-entry/card-entry.js +348 -221
  153. package/dist/matter/card-entry/card-entry.js.map +1 -1
  154. package/dist/matter/cart/cart-namespace.d.ts +7 -1
  155. package/dist/matter/cart/cart-namespace.js +7 -1
  156. package/dist/matter/cart/cart-namespace.js.map +1 -1
  157. package/dist/matter/cart/cart.d.ts +402 -61
  158. package/dist/matter/cart/cart.js +624 -153
  159. package/dist/matter/cart/cart.js.map +1 -1
  160. package/dist/matter/cart-destination/cart-destination.d.ts +30 -19
  161. package/dist/matter/cart-destination/cart-destination.js +160 -70
  162. package/dist/matter/cart-destination/cart-destination.js.map +1 -1
  163. package/dist/matter/cart-item/cart-item.d.ts +144 -17
  164. package/dist/matter/cart-item/cart-item.js +166 -49
  165. package/dist/matter/cart-item/cart-item.js.map +1 -1
  166. package/dist/matter/cart-item-compositions/cart-item-compositions.js +1 -1
  167. package/dist/matter/cart-item-compositions/cart-item-compositions.js.map +1 -1
  168. package/dist/matter/cart-item-customizations/cart-item-customizations.js +1 -1
  169. package/dist/matter/cart-item-customizations/cart-item-customizations.js.map +1 -1
  170. package/dist/matter/cart-item-discounts/cart-item-discounts.js +1 -1
  171. package/dist/matter/cart-item-discounts/cart-item-discounts.js.map +1 -1
  172. package/dist/matter/cart-item-seller-info/cart-item-seller-info.js +1 -1
  173. package/dist/matter/cart-item-seller-info/cart-item-seller-info.js.map +1 -1
  174. package/dist/matter/cart-item-variations/cart-item-variations.js +1 -1
  175. package/dist/matter/cart-item-variations/cart-item-variations.js.map +1 -1
  176. package/dist/matter/cart-totalizer/cart-totalizer.d.ts +43 -9
  177. package/dist/matter/cart-totalizer/cart-totalizer.js +46 -17
  178. package/dist/matter/cart-totalizer/cart-totalizer.js.map +1 -1
  179. package/dist/matter/challenge-return/challenge-return.d.ts +62 -0
  180. package/dist/matter/challenge-return/challenge-return.js +241 -0
  181. package/dist/matter/challenge-return/challenge-return.js.map +1 -0
  182. package/dist/matter/client-preferences/client-preferences-fieldset.d.ts +86 -17
  183. package/dist/matter/client-preferences/client-preferences-fieldset.js +126 -54
  184. package/dist/matter/client-preferences/client-preferences-fieldset.js.map +1 -1
  185. package/dist/matter/client-preferences/client-preferences.d.ts +50 -7
  186. package/dist/matter/client-preferences/client-preferences.js +84 -15
  187. package/dist/matter/client-preferences/client-preferences.js.map +1 -1
  188. package/dist/matter/client-profile/client-profile.d.ts +44 -9
  189. package/dist/matter/client-profile/client-profile.js +64 -24
  190. package/dist/matter/client-profile/client-profile.js.map +1 -1
  191. package/dist/matter/client-profile-form/client-profile-fieldset.d.ts +119 -22
  192. package/dist/matter/client-profile-form/client-profile-fieldset.js +161 -73
  193. package/dist/matter/client-profile-form/client-profile-fieldset.js.map +1 -1
  194. package/dist/matter/delivery-options/delivery-options-accordion.d.ts +49 -4
  195. package/dist/matter/delivery-options/delivery-options-accordion.js +67 -14
  196. package/dist/matter/delivery-options/delivery-options-accordion.js.map +1 -1
  197. package/dist/matter/delivery-options/delivery-options-controller.d.ts +69 -9
  198. package/dist/matter/delivery-options/delivery-options-controller.js +80 -14
  199. package/dist/matter/delivery-options/delivery-options-controller.js.map +1 -1
  200. package/dist/matter/delivery-options/delivery-options.d.ts +37 -2
  201. package/dist/matter/delivery-options/delivery-options.js +75 -12
  202. package/dist/matter/delivery-options/delivery-options.js.map +1 -1
  203. package/dist/matter/delivery-options/use-delivery-option-selection.d.ts +1 -0
  204. package/dist/matter/delivery-options/use-delivery-option-selection.js +1 -1
  205. package/dist/matter/delivery-options/use-delivery-option-selection.js.map +1 -1
  206. package/dist/matter/email-identification/email-identification.d.ts +25 -3
  207. package/dist/matter/email-identification/email-identification.js +49 -12
  208. package/dist/matter/email-identification/email-identification.js.map +1 -1
  209. package/dist/matter/free-shipping-progress/free-shipping-progress.d.ts +79 -7
  210. package/dist/matter/free-shipping-progress/free-shipping-progress.js +77 -20
  211. package/dist/matter/free-shipping-progress/free-shipping-progress.js.map +1 -1
  212. package/dist/matter/identity-edit/identity-edit.d.ts +52 -10
  213. package/dist/matter/identity-edit/identity-edit.js +47 -19
  214. package/dist/matter/identity-edit/identity-edit.js.map +1 -1
  215. package/dist/matter/identity-summary/identity-summary.d.ts +76 -22
  216. package/dist/matter/identity-summary/identity-summary.js +95 -45
  217. package/dist/matter/identity-summary/identity-summary.js.map +1 -1
  218. package/dist/matter/installments/installments-select.d.ts +98 -16
  219. package/dist/matter/installments/installments-select.js +156 -48
  220. package/dist/matter/installments/installments-select.js.map +1 -1
  221. package/dist/matter/installments/installments.d.ts +96 -16
  222. package/dist/matter/installments/installments.js +115 -40
  223. package/dist/matter/installments/installments.js.map +1 -1
  224. package/dist/matter/installments/use-installments-selection.d.ts +1 -0
  225. package/dist/matter/installments/use-installments-selection.js +8 -3
  226. package/dist/matter/installments/use-installments-selection.js.map +1 -1
  227. package/dist/matter/my-account-profile/my-account-profile.d.ts +358 -103
  228. package/dist/matter/my-account-profile/my-account-profile.js +370 -174
  229. package/dist/matter/my-account-profile/my-account-profile.js.map +1 -1
  230. package/dist/matter/order-cancel/order-cancel.d.ts +65 -19
  231. package/dist/matter/order-cancel/order-cancel.js +118 -51
  232. package/dist/matter/order-cancel/order-cancel.js.map +1 -1
  233. package/dist/matter/order-delivery-address/order-delivery-address.d.ts +8 -18
  234. package/dist/matter/order-delivery-address/order-delivery-address.js +14 -23
  235. package/dist/matter/order-delivery-address/order-delivery-address.js.map +1 -1
  236. package/dist/matter/order-delivery-group/order-delivery-group.d.ts +40 -24
  237. package/dist/matter/order-delivery-group/order-delivery-group.js +64 -74
  238. package/dist/matter/order-delivery-group/order-delivery-group.js.map +1 -1
  239. package/dist/matter/order-details-header/order-details-header.d.ts +32 -15
  240. package/dist/matter/order-details-header/order-details-header.js +66 -58
  241. package/dist/matter/order-details-header/order-details-header.js.map +1 -1
  242. package/dist/matter/order-invoice-download/order-invoice-download.d.ts +78 -0
  243. package/dist/matter/order-invoice-download/order-invoice-download.js +173 -0
  244. package/dist/matter/order-invoice-download/order-invoice-download.js.map +1 -0
  245. package/dist/matter/order-list/order-list.d.ts +164 -19
  246. package/dist/matter/order-list/order-list.js +229 -87
  247. package/dist/matter/order-list/order-list.js.map +1 -1
  248. package/dist/matter/order-list-row/order-list-row.d.ts +6 -1
  249. package/dist/matter/order-list-row/order-list-row.js +3 -2
  250. package/dist/matter/order-list-row/order-list-row.js.map +1 -1
  251. package/dist/matter/order-list-search/order-list-search.d.ts +18 -26
  252. package/dist/matter/order-list-search/order-list-search.js +30 -69
  253. package/dist/matter/order-list-search/order-list-search.js.map +1 -1
  254. package/dist/matter/order-list-views/order-list-views.d.ts +15 -22
  255. package/dist/matter/order-list-views/order-list-views.js +22 -68
  256. package/dist/matter/order-list-views/order-list-views.js.map +1 -1
  257. package/dist/matter/order-payment/order-payment.d.ts +33 -10
  258. package/dist/matter/order-payment/order-payment.js +44 -39
  259. package/dist/matter/order-payment/order-payment.js.map +1 -1
  260. package/dist/matter/order-placed/order-placed-deliveries.d.ts +144 -12
  261. package/dist/matter/order-placed/order-placed-deliveries.js +115 -40
  262. package/dist/matter/order-placed/order-placed-deliveries.js.map +1 -1
  263. package/dist/matter/order-placed/order-placed.d.ts +198 -31
  264. package/dist/matter/order-placed/order-placed.js +230 -139
  265. package/dist/matter/order-placed/order-placed.js.map +1 -1
  266. package/dist/matter/order-placed-date/order-placed-date.d.ts +5 -8
  267. package/dist/matter/order-placed-date/order-placed-date.js +7 -8
  268. package/dist/matter/order-placed-date/order-placed-date.js.map +1 -1
  269. package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.d.ts +90 -17
  270. package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js +93 -117
  271. package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js.map +1 -1
  272. package/dist/matter/order-progress/order-progress.d.ts +19 -8
  273. package/dist/matter/order-progress/order-progress.js +37 -45
  274. package/dist/matter/order-progress/order-progress.js.map +1 -1
  275. package/dist/matter/order-summary/order-summary.d.ts +19 -9
  276. package/dist/matter/order-summary/order-summary.js +38 -44
  277. package/dist/matter/order-summary/order-summary.js.map +1 -1
  278. package/dist/matter/order-tracking-link/order-tracking-link.d.ts +43 -0
  279. package/dist/matter/order-tracking-link/order-tracking-link.js +107 -0
  280. package/dist/matter/order-tracking-link/order-tracking-link.js.map +1 -0
  281. package/dist/matter/payment/payment-card-capture.js +17 -10
  282. package/dist/matter/payment/payment-card-capture.js.map +1 -1
  283. package/dist/matter/payment/payment-controller.d.ts +4 -2
  284. package/dist/matter/payment/payment-controller.js +30 -9
  285. package/dist/matter/payment/payment-controller.js.map +1 -1
  286. package/dist/matter/payment/payment-method-badges.js +1 -1
  287. package/dist/matter/payment/payment.d.ts +69 -19
  288. package/dist/matter/payment/payment.js +101 -35
  289. package/dist/matter/payment/payment.js.map +1 -1
  290. package/dist/matter/payment/use-payment-method-selection.d.ts +25 -4
  291. package/dist/matter/payment/use-payment-method-selection.js +94 -32
  292. package/dist/matter/payment/use-payment-method-selection.js.map +1 -1
  293. package/dist/matter/payment/use-payment-submit-gate.d.ts +14 -3
  294. package/dist/matter/payment/use-payment-submit-gate.js +47 -8
  295. package/dist/matter/payment/use-payment-submit-gate.js.map +1 -1
  296. package/dist/matter/place-order/place-order.d.ts +171 -57
  297. package/dist/matter/place-order/place-order.js +376 -185
  298. package/dist/matter/place-order/place-order.js.map +1 -1
  299. package/dist/matter/pricing/pricing.d.ts +152 -13
  300. package/dist/matter/pricing/pricing.js +153 -52
  301. package/dist/matter/pricing/pricing.js.map +1 -1
  302. package/dist/matter/product-information/product-information.d.ts +27 -4
  303. package/dist/matter/product-information/product-information.js +32 -15
  304. package/dist/matter/product-information/product-information.js.map +1 -1
  305. package/dist/matter/product-list/product-list.d.ts +24 -6
  306. package/dist/matter/product-list/product-list.js +32 -26
  307. package/dist/matter/product-list/product-list.js.map +1 -1
  308. package/dist/matter/product-shelf/product-shelf.d.ts +1 -3
  309. package/dist/matter/product-shelf/product-shelf.js +2 -15
  310. package/dist/matter/product-shelf/product-shelf.js.map +1 -1
  311. package/dist/matter/region/region.d.ts +33 -16
  312. package/dist/matter/region/region.js +59 -52
  313. package/dist/matter/region/region.js.map +1 -1
  314. package/dist/matter/save-card/save-card.d.ts +43 -8
  315. package/dist/matter/save-card/save-card.js +61 -23
  316. package/dist/matter/save-card/save-card.js.map +1 -1
  317. package/dist/matter/saved-cards/saved-cards.d.ts +113 -21
  318. package/dist/matter/saved-cards/saved-cards.js +349 -77
  319. package/dist/matter/saved-cards/saved-cards.js.map +1 -1
  320. package/dist/matter/shipping-address/address-payload.js +25 -0
  321. package/dist/matter/shipping-address/address-payload.js.map +1 -0
  322. package/dist/matter/shipping-address/country-descriptors.js +71 -71
  323. package/dist/matter/shipping-address/country-descriptors.js.map +1 -1
  324. package/dist/matter/shipping-address/library-country-descriptors.js +136 -0
  325. package/dist/matter/shipping-address/library-country-descriptors.js.map +1 -0
  326. package/dist/matter/shipping-address/shipping-address.d.ts +312 -45
  327. package/dist/matter/shipping-address/shipping-address.js +443 -188
  328. package/dist/matter/shipping-address/shipping-address.js.map +1 -1
  329. package/dist/matter/shipping-simulator/shipping-simulator.d.ts +250 -24
  330. package/dist/matter/shipping-simulator/shipping-simulator.js +257 -51
  331. package/dist/matter/shipping-simulator/shipping-simulator.js.map +1 -1
  332. package/dist/matter/sign-in/sign-in.d.ts +108 -0
  333. package/dist/matter/sign-in/sign-in.js +285 -0
  334. package/dist/matter/sign-in/sign-in.js.map +1 -0
  335. package/dist/matter/sign-in-disclosure/sign-in-disclosure.d.ts +81 -0
  336. package/dist/matter/sign-in-disclosure/sign-in-disclosure.js +232 -0
  337. package/dist/matter/sign-in-disclosure/sign-in-disclosure.js.map +1 -0
  338. package/dist/matter/sign-in-form/sign-in-form.d.ts +93 -62
  339. package/dist/matter/sign-in-form/sign-in-form.js +134 -144
  340. package/dist/matter/sign-in-form/sign-in-form.js.map +1 -1
  341. package/dist/particles/binding-switcher/binding-switcher.d.ts +29 -8
  342. package/dist/particles/binding-switcher/binding-switcher.js +37 -26
  343. package/dist/particles/binding-switcher/binding-switcher.js.map +1 -1
  344. package/dist/particles/card-summary/card-summary.d.ts +38 -8
  345. package/dist/particles/card-summary/card-summary.js +55 -22
  346. package/dist/particles/card-summary/card-summary.js.map +1 -1
  347. package/dist/particles/carousel/carousel.d.ts +99 -11
  348. package/dist/particles/carousel/carousel.js +103 -35
  349. package/dist/particles/carousel/carousel.js.map +1 -1
  350. package/dist/particles/copy-text/copy-text.js +5 -15
  351. package/dist/particles/copy-text/copy-text.js.map +1 -1
  352. package/dist/particles/dialog/dialog.d.ts +14 -6
  353. package/dist/particles/dialog/dialog.js +6 -3
  354. package/dist/particles/dialog/dialog.js.map +1 -1
  355. package/dist/particles/drawer/drawer.js +1 -1
  356. package/dist/particles/drawer/drawer.js.map +1 -1
  357. package/dist/particles/email-field/email-field.d.ts +2 -1
  358. package/dist/particles/email-field/email-field.js +2 -1
  359. package/dist/particles/email-field/email-field.js.map +1 -1
  360. package/dist/particles/footer-link-group/footer-link-group.js +1 -0
  361. package/dist/particles/footer-link-group/footer-link-group.js.map +1 -1
  362. package/dist/particles/form/form.d.ts +85 -13
  363. package/dist/particles/form/form.js +91 -42
  364. package/dist/particles/form/form.js.map +1 -1
  365. package/dist/particles/gallery/gallery.d.ts +129 -12
  366. package/dist/particles/gallery/gallery.js +121 -34
  367. package/dist/particles/gallery/gallery.js.map +1 -1
  368. package/dist/particles/order-details-back/order-details-back.d.ts +5 -3
  369. package/dist/particles/order-details-back/order-details-back.js +8 -10
  370. package/dist/particles/order-details-back/order-details-back.js.map +1 -1
  371. package/dist/particles/order-status-badge/order-status-badge.d.ts +3 -3
  372. package/dist/particles/order-status-badge/order-status-badge.js +4 -20
  373. package/dist/particles/order-status-badge/order-status-badge.js.map +1 -1
  374. package/dist/particles/password-field/password-field.d.ts +1 -1
  375. package/dist/particles/password-field/password-field.js +2 -4
  376. package/dist/particles/password-field/password-field.js.map +1 -1
  377. package/dist/particles/phone-field/phone-field.d.ts +4 -4
  378. package/dist/particles/phone-field/phone-field.js +8 -11
  379. package/dist/particles/phone-field/phone-field.js.map +1 -1
  380. package/dist/particles/spinner/spinner.d.ts +24 -4
  381. package/dist/particles/spinner/spinner.js +25 -9
  382. package/dist/particles/spinner/spinner.js.map +1 -1
  383. package/dist/particles/switch/switch.d.ts +4 -1
  384. package/dist/particles/switch/switch.js +3 -1
  385. package/dist/particles/switch/switch.js.map +1 -1
  386. package/dist/particles/toast/toast.d.ts +29 -3
  387. package/dist/particles/toast/toast.js +34 -10
  388. package/dist/particles/toast/toast.js.map +1 -1
  389. package/dist/schema.graphql +164 -56
  390. package/dist/sdk/address/address-fields.js +4 -4
  391. package/dist/sdk/address/address-fields.js.map +1 -1
  392. package/dist/sdk/address/constants.js +1 -6
  393. package/dist/sdk/address/constants.js.map +1 -1
  394. package/dist/sdk/address/messages.js +44 -44
  395. package/dist/sdk/address/messages.js.map +1 -1
  396. package/dist/sdk/address/postal-code.js +15 -2
  397. package/dist/sdk/address/postal-code.js.map +1 -1
  398. package/dist/sdk/address/types.d.ts +5 -3
  399. package/dist/sdk/address/validate-address.js +3 -3
  400. package/dist/sdk/address/validate-address.js.map +1 -1
  401. package/dist/sdk/analytics/use-analytics-actions.d.ts +1 -1
  402. package/dist/sdk/analytics/use-analytics-actions.js.map +1 -1
  403. package/dist/sdk/cart/use-cart-actions.js.map +1 -1
  404. package/dist/sdk/data/index.js +2 -2
  405. package/dist/sdk/data/reactive-list-item-data-provider.js +2 -2
  406. package/dist/sdk/generated/gql.js +1 -1
  407. package/dist/sdk/generated/gql.js.map +1 -1
  408. package/dist/sdk/generated/graphql.d.ts +20 -5
  409. package/dist/sdk/generated/graphql.js +6 -0
  410. package/dist/sdk/generated/graphql.js.map +1 -1
  411. package/dist/sdk/i18n/format-error-code.js +23 -0
  412. package/dist/sdk/i18n/format-error-code.js.map +1 -0
  413. package/dist/sdk/i18n/message-formatter.d.ts +22 -0
  414. package/dist/sdk/i18n/message-formatter.js +140 -0
  415. package/dist/sdk/i18n/message-formatter.js.map +1 -0
  416. package/dist/sdk/i18n/use-message-formatter.d.ts +8 -0
  417. package/dist/sdk/i18n/use-message-formatter.js +18 -0
  418. package/dist/sdk/i18n/use-message-formatter.js.map +1 -0
  419. package/dist/sdk/identity/use-identity-actions.js.map +1 -1
  420. package/dist/sdk/navigation/redirect.d.ts +2 -0
  421. package/dist/sdk/navigation/redirect.js +19 -1
  422. package/dist/sdk/navigation/redirect.js.map +1 -1
  423. package/dist/sdk/navigation/types.d.ts +13 -0
  424. package/dist/sdk/payment/bin-format.js +20 -0
  425. package/dist/sdk/payment/bin-format.js.map +1 -0
  426. package/dist/sdk/payment/challenge-return.js +37 -0
  427. package/dist/sdk/payment/challenge-return.js.map +1 -0
  428. package/dist/sdk/payment/confirmation-last-four.js +39 -0
  429. package/dist/sdk/payment/confirmation-last-four.js.map +1 -0
  430. package/dist/sdk/payment/gateway.d.ts +1 -1
  431. package/dist/sdk/payment/gateway.js +8 -2
  432. package/dist/sdk/payment/gateway.js.map +1 -1
  433. package/dist/sdk/payment/operations.d.ts +1 -0
  434. package/dist/sdk/payment/operations.js +28 -6
  435. package/dist/sdk/payment/operations.js.map +1 -1
  436. package/dist/sdk/payment/resumed-purchase.d.ts +1 -0
  437. package/dist/sdk/payment/resumed-purchase.js +119 -0
  438. package/dist/sdk/payment/resumed-purchase.js.map +1 -0
  439. package/dist/sdk/payment/security-code-mask.js +16 -23
  440. package/dist/sdk/payment/security-code-mask.js.map +1 -1
  441. package/dist/sdk/payment/submission-registry.js +6 -2
  442. package/dist/sdk/payment/submission-registry.js.map +1 -1
  443. package/dist/sdk/payment/use-payment-actions.d.ts +18 -3
  444. package/dist/sdk/payment/use-payment-actions.js +23 -3
  445. package/dist/sdk/payment/use-payment-actions.js.map +1 -1
  446. package/dist/sdk/payment/use-place-order.d.ts +10 -2
  447. package/dist/sdk/payment/use-place-order.js +138 -76
  448. package/dist/sdk/payment/use-place-order.js.map +1 -1
  449. package/dist/sdk/provider/storefront-provider.d.ts +1 -7
  450. package/dist/sdk/provider/storefront-provider.js +4 -11
  451. package/dist/sdk/provider/storefront-provider.js.map +1 -1
  452. package/dist/sdk/seo/entity-landing.d.ts +24 -0
  453. package/dist/sdk/seo/entity-landing.js +30 -0
  454. package/dist/sdk/seo/entity-landing.js.map +1 -0
  455. package/dist/sdk/seo/page-alternates.d.ts +3 -2
  456. package/dist/sdk/seo/page-alternates.js +4 -2
  457. package/dist/sdk/seo/page-alternates.js.map +1 -1
  458. package/dist/sdk/seo/search-landing.d.ts +42 -0
  459. package/dist/sdk/seo/search-landing.js +85 -0
  460. package/dist/sdk/seo/search-landing.js.map +1 -0
  461. package/dist/sdk/session/mock-session.d.ts +9 -0
  462. package/dist/sdk/session/mock-session.js +31 -0
  463. package/dist/sdk/session/mock-session.js.map +1 -0
  464. package/dist/sdk/session/read-server-session.d.ts +3 -0
  465. package/dist/sdk/session/read-server-session.js +5 -0
  466. package/dist/sdk/session/read-server-session.js.map +1 -1
  467. package/dist/sdk/session/return-path-segment.d.ts +10 -0
  468. package/dist/sdk/session/return-path-segment.js +15 -0
  469. package/dist/sdk/session/return-path-segment.js.map +1 -0
  470. package/dist/sdk/session/use-session-actions.js.map +1 -1
  471. package/dist/sdk/shipping/use-cart-shipping-simulation.js.map +1 -1
  472. package/dist/sdk/shipping/use-shipping-actions.js.map +1 -1
  473. package/dist/sdk/shipping/use-shipping-simulation.js.map +1 -1
  474. package/dist/utils/safe-href.d.ts +2 -0
  475. package/package.json +4 -3
  476. package/skills/storefront-asset/SKILL.md +2 -2
  477. package/skills/storefront-asset/references/api-side.md +27 -14
  478. package/skills/storefront-asset/references/findings.md +5 -2
  479. package/src/styles/tailwind.css +8 -0
  480. package/dist/matter/shipping-address/country-descriptors.d.ts +0 -1
  481. package/dist/message-locales.json +0 -7
  482. package/dist/sdk/i18n/client.d.ts +0 -4
  483. package/dist/sdk/i18n/client.js +0 -4
  484. package/dist/sdk/i18n/locales.d.ts +0 -8
  485. package/dist/sdk/i18n/locales.js +0 -57
  486. package/dist/sdk/i18n/locales.js.map +0 -1
  487. package/dist/sdk/i18n/messages/en-US.js +0 -183
  488. package/dist/sdk/i18n/messages/en-US.js.map +0 -1
  489. package/dist/sdk/i18n/messages/en-US.json +0 -178
  490. package/dist/sdk/i18n/messages/en-US.json.d.ts +0 -182
  491. package/dist/sdk/i18n/messages/es-ES.js +0 -183
  492. package/dist/sdk/i18n/messages/es-ES.js.map +0 -1
  493. package/dist/sdk/i18n/messages/es-ES.json +0 -178
  494. package/dist/sdk/i18n/messages/pt-BR.js +0 -183
  495. package/dist/sdk/i18n/messages/pt-BR.js.map +0 -1
  496. package/dist/sdk/i18n/messages/pt-BR.json +0 -178
  497. package/dist/sdk/i18n/provider.d.ts +0 -1
  498. package/dist/sdk/i18n/provider.js +0 -30
  499. package/dist/sdk/i18n/provider.js.map +0 -1
  500. package/dist/sdk/i18n/server.d.ts +0 -28
  501. package/dist/sdk/i18n/server.js +0 -59
  502. package/dist/sdk/i18n/server.js.map +0 -1
  503. package/dist/utils/resolve-authored-copy.js +0 -18
  504. package/dist/utils/resolve-authored-copy.js.map +0 -1
  505. package/dist/utils/substitute-template.js +0 -33
  506. package/dist/utils/substitute-template.js.map +0 -1
@@ -1,4 +1,5 @@
1
1
  import { ShippingOption } from "../shipping-simulator/shipping-simulator.js";
2
+ import "../../sdk/shipping/option-select-operations.js";
2
3
  import "../../sdk/actions/types.js";
3
4
  //#region src/matter/delivery-options/use-delivery-option-selection.d.ts
4
5
  export type RawDeliveryOptionsData = {
@@ -49,7 +49,7 @@ function useDeliveryOptionSelection({ $data: $dataProp, $actions, mockOptions })
49
49
  if (selectionToken.current !== token) return;
50
50
  const [firstError] = userErrors;
51
51
  if (firstError) {
52
- setSelectionError(firstError.message);
52
+ setSelectionError(firstError);
53
53
  callbacks?.onSettled?.(false);
54
54
  } else callbacks?.onSettled?.(true);
55
55
  });
@@ -1 +1 @@
1
- {"version":3,"file":"use-delivery-option-selection.js","names":[],"sources":["../../../src/matter/delivery-options/use-delivery-option-selection.ts"],"sourcesContent":["'use client';\n\nimport { useMemo, useRef, useState } from 'react';\nimport type { ComponentActions } from '../../sdk/actions/types.js';\nimport { useDataOverride } from '../../sdk/data/data-override-context.js';\nimport type { ShippingOption, ShippingSimulatorContextValue } from '../shipping-simulator/shipping-simulator.js';\n\n// ---------------------------------------------------------------------------\n// Raw data type (shape of the reactive fragment result). `$data` is the unwrapped\n// `Shipping` entity the reactive runtime forwards (Decision 7 / INV-7), not `{ shipping: … }`.\n// Shared by DeliveryOptionsRoot and its collapsed variants (Accordion/Dialog/Drawer), all of\n// which read the same `shipping { options … selectedOptionId }` selection.\n// ---------------------------------------------------------------------------\n\nexport type RawDeliveryOptionsData = {\n options: ShippingOption[];\n selectedOptionId: string | null;\n};\n\nconst EMPTY_OPTIONS: ShippingOption[] = [];\n\n/**\n * Joins the structural classes a collapsed variant always applies (positioning, sizing, animation)\n * with the page-supplied visual override, dropping empty slots. Keeps the visual layer out of the\n * component (Free Particle Model) while guaranteeing the overlay still positions itself.\n */\nexport function cx(...classes: Array<string | undefined>): string {\n return classes.filter(Boolean).join(' ');\n}\n\nexport type DeliveryOptionSelection = {\n /** Real options when the fetch has any, else the `mockOptions` fallback, else empty. */\n options: ShippingOption[];\n /** Group value: the persisted `selectedOptionId` for real data, local state under mock. */\n selectedOptionId: string | null;\n /** True while the mock fallback is showing (no real options + `mockOptions` present). */\n usingMockOptions: boolean;\n /** Message of the first `userError` from the latest real selection, or `null`. */\n selectionError: string | null;\n /**\n * Selects an option. Under mock data the choice is local-only and never dispatches the action.\n * Under real data it dispatches `shipping.selectOption`, request-sequenced so only the latest\n * click wins the error state. `onSettled(ok)` fires once the selection resolves — `ok` is `false`\n * when the mutation surfaced a `userError` (or no action was injected) — letting collapsed\n * variants close only on success.\n */\n selectOption: (optionId: string, callbacks?: { onSettled?: (ok: boolean) => void }) => void;\n /** The FSPG-832 simulator context value (inert simulation fields) providers must supply. */\n contextValue: ShippingSimulatorContextValue;\n};\n\n/**\n * Shared selection engine behind `DeliveryOptionsRoot` and its collapsed variants\n * (`DeliveryOptionsAccordion` / `Dialog` / `Drawer`). It owns the four behaviours the spec\n * requires identically across every surface, so they cannot drift apart:\n *\n * - real-vs-mock option resolution — real options of any length always win (INV-8);\n * - the local mock selection, reset whenever the real↔mock boundary flips so a stale mock\n * choice from before a real-options interlude never reappears (Decision 7);\n * - the reactive `selectedOptionId` binding (Decision 5 — no local state for real data);\n * - the request-sequenced `selectOption` dispatch that resolves `userErrors` for inline display\n * (US-4), guarding against an earlier click's result overwriting a later one.\n *\n * Callers render `selectionError` (as `role=\"alert\"`) and wire `contextValue` themselves; the\n * collapsed variants additionally use `onSettled` to close their panel only on success.\n */\nexport function useDeliveryOptionSelection({\n $data: $dataProp,\n $actions,\n mockOptions,\n}: {\n $data?: RawDeliveryOptionsData | null;\n $actions?: ComponentActions;\n mockOptions?: ShippingOption[];\n}): DeliveryOptionSelection {\n const $data = useDataOverride($dataProp);\n const realOptions = $data?.options;\n const usingMockOptions = !realOptions?.length && !!mockOptions?.length;\n const options = realOptions?.length ? realOptions : (mockOptions ?? EMPTY_OPTIONS);\n\n const [mockSelectedOptionId, setMockSelectedOptionId] = useState<string | null>(null);\n const [wasUsingMockOptions, setWasUsingMockOptions] = useState(usingMockOptions);\n if (usingMockOptions !== wasUsingMockOptions) {\n setWasUsingMockOptions(usingMockOptions);\n setMockSelectedOptionId(null);\n }\n const selectedOptionId = usingMockOptions ? mockSelectedOptionId : ($data?.selectedOptionId ?? null);\n\n const [selectionError, setSelectionError] = useState<string | null>(null);\n const selectionToken = useRef(0);\n\n function selectOption(optionId: string, callbacks?: { onSettled?: (ok: boolean) => void }) {\n if (usingMockOptions) {\n setMockSelectedOptionId(optionId);\n callbacks?.onSettled?.(true);\n return;\n }\n setSelectionError(null);\n const dispatch = $actions?.shipping?.selectOption;\n if (!dispatch) {\n callbacks?.onSettled?.(false);\n return;\n }\n const token = ++selectionToken.current;\n dispatch(optionId).then((userErrors) => {\n if (selectionToken.current !== token) return;\n const [firstError] = userErrors;\n if (firstError) {\n setSelectionError(firstError.message);\n callbacks?.onSettled?.(false);\n } else {\n callbacks?.onSettled?.(true);\n }\n });\n }\n\n const contextValue = useMemo<ShippingSimulatorContextValue>(\n () => ({\n postalCode: '',\n setPostalCode: () => {},\n status: 'idle',\n shippingOptions: options,\n userErrors: [],\n submit: () => {},\n }),\n [options],\n );\n\n return { options, selectedOptionId, usingMockOptions, selectionError, selectOption, contextValue };\n}\n"],"mappings":";;;;AAmBA,MAAM,gBAAkC,CAAC;;;;;;;;;;;;;;;;AA+CzC,SAAgB,2BAA2B,EACzC,OAAO,WACP,UACA,eAK0B;CAC1B,MAAM,QAAQ,gBAAgB,SAAS;CACvC,MAAM,cAAc,OAAO;CAC3B,MAAM,mBAAmB,CAAC,aAAa,UAAU,CAAC,CAAC,aAAa;CAChE,MAAM,UAAU,aAAa,SAAS,cAAe,eAAe;CAEpE,MAAM,CAAC,sBAAsB,2BAA2B,SAAwB,IAAI;CACpF,MAAM,CAAC,qBAAqB,0BAA0B,SAAS,gBAAgB;CAC/E,IAAI,qBAAqB,qBAAqB;EAC5C,uBAAuB,gBAAgB;EACvC,wBAAwB,IAAI;CAC9B;CACA,MAAM,mBAAmB,mBAAmB,uBAAwB,OAAO,oBAAoB;CAE/F,MAAM,CAAC,gBAAgB,qBAAqB,SAAwB,IAAI;CACxE,MAAM,iBAAiB,OAAO,CAAC;CAE/B,SAAS,aAAa,UAAkB,WAAmD;EACzF,IAAI,kBAAkB;GACpB,wBAAwB,QAAQ;GAChC,WAAW,YAAY,IAAI;GAC3B;EACF;EACA,kBAAkB,IAAI;EACtB,MAAM,WAAW,UAAU,UAAU;EACrC,IAAI,CAAC,UAAU;GACb,WAAW,YAAY,KAAK;GAC5B;EACF;EACA,MAAM,QAAQ,EAAE,eAAe;EAC/B,SAAS,QAAQ,CAAC,CAAC,MAAM,eAAe;GACtC,IAAI,eAAe,YAAY,OAAO;GACtC,MAAM,CAAC,cAAc;GACrB,IAAI,YAAY;IACd,kBAAkB,WAAW,OAAO;IACpC,WAAW,YAAY,KAAK;GAC9B,OACE,WAAW,YAAY,IAAI;EAE/B,CAAC;CACH;CAcA,OAAO;EAAE;EAAS;EAAkB;EAAkB;EAAgB;EAAc,cAZ/D,eACZ;GACL,YAAY;GACZ,qBAAqB,CAAC;GACtB,QAAQ;GACR,iBAAiB;GACjB,YAAY,CAAC;GACb,cAAc,CAAC;EACjB,IACA,CAAC,OAAO,CAGqF;CAAE;AACnG"}
1
+ {"version":3,"file":"use-delivery-option-selection.js","names":[],"sources":["../../../src/matter/delivery-options/use-delivery-option-selection.ts"],"sourcesContent":["'use client';\n\nimport { useMemo, useRef, useState } from 'react';\nimport type { ComponentActions } from '../../sdk/actions/types.js';\nimport { useDataOverride } from '../../sdk/data/data-override-context.js';\nimport type { ShippingOptionSelectUserError } from '../../sdk/shipping/option-select-operations.js';\nimport type { ShippingOption, ShippingSimulatorContextValue } from '../shipping-simulator/shipping-simulator.js';\n\n// ---------------------------------------------------------------------------\n// Raw data type (shape of the reactive fragment result). `$data` is the unwrapped\n// `Shipping` entity the reactive runtime forwards (Decision 7 / INV-7), not `{ shipping: … }`.\n// Shared by DeliveryOptionsRoot and its collapsed variants (Accordion/Dialog/Drawer), all of\n// which read the same `shipping { options … selectedOptionId }` selection.\n// ---------------------------------------------------------------------------\n\nexport type RawDeliveryOptionsData = {\n options: ShippingOption[];\n selectedOptionId: string | null;\n};\n\nconst EMPTY_OPTIONS: ShippingOption[] = [];\n\n/**\n * The codes a selection can resolve: `ShippingOptionSelectErrorCode` (the sdk types `code` as a string)\n * plus the client-minted transport failure. Each surface words them from its own `$content`.\n */\nexport type DeliveryOptionSelectErrorCode =\n | 'MISSING_CART_CONTEXT'\n | 'CART_NOT_FOUND'\n | 'OPTION_UNAVAILABLE'\n | 'MISSING_SHIPPING_ADDRESS'\n | 'NETWORK_ERROR';\n\n/**\n * Joins the structural classes a collapsed variant always applies (positioning, sizing, animation)\n * with the page-supplied visual override, dropping empty slots. Keeps the visual layer out of the\n * component (Free Particle Model) while guaranteeing the overlay still positions itself.\n */\nexport function cx(...classes: Array<string | undefined>): string {\n return classes.filter(Boolean).join(' ');\n}\n\nexport type DeliveryOptionSelection = {\n /** Real options when the fetch has any, else the `mockOptions` fallback, else empty. */\n options: ShippingOption[];\n /** Group value: the persisted `selectedOptionId` for real data, local state under mock. */\n selectedOptionId: string | null;\n /** True while the mock fallback is showing (no real options + `mockOptions` present). */\n usingMockOptions: boolean;\n /** The first `userError` from the latest real selection, or `null`. */\n selectionError: ShippingOptionSelectUserError | null;\n /**\n * Selects an option. Under mock data the choice is local-only and never dispatches the action.\n * Under real data it dispatches `shipping.selectOption`, request-sequenced so only the latest\n * click wins the error state. `onSettled(ok)` fires once the selection resolves — `ok` is `false`\n * when the mutation surfaced a `userError` (or no action was injected) — letting collapsed\n * variants close only on success.\n */\n selectOption: (optionId: string, callbacks?: { onSettled?: (ok: boolean) => void }) => void;\n /** The FSPG-832 simulator context value (inert simulation fields) providers must supply. */\n contextValue: ShippingSimulatorContextValue;\n};\n\n/**\n * Shared selection engine behind `DeliveryOptionsRoot` and its collapsed variants\n * (`DeliveryOptionsAccordion` / `Dialog` / `Drawer`). It owns the four behaviours the spec\n * requires identically across every surface, so they cannot drift apart:\n *\n * - real-vs-mock option resolution — real options of any length always win (INV-8);\n * - the local mock selection, reset whenever the real↔mock boundary flips so a stale mock\n * choice from before a real-options interlude never reappears (Decision 7);\n * - the reactive `selectedOptionId` binding (Decision 5 — no local state for real data);\n * - the request-sequenced `selectOption` dispatch that resolves `userErrors` for inline display\n * (US-4), guarding against an earlier click's result overwriting a later one.\n *\n * Callers render `selectionError` (as `role=\"alert\"`) and wire `contextValue` themselves; the\n * collapsed variants additionally use `onSettled` to close their panel only on success.\n */\nexport function useDeliveryOptionSelection({\n $data: $dataProp,\n $actions,\n mockOptions,\n}: {\n $data?: RawDeliveryOptionsData | null;\n $actions?: ComponentActions;\n mockOptions?: ShippingOption[];\n}): DeliveryOptionSelection {\n const $data = useDataOverride($dataProp);\n const realOptions = $data?.options;\n const usingMockOptions = !realOptions?.length && !!mockOptions?.length;\n const options = realOptions?.length ? realOptions : (mockOptions ?? EMPTY_OPTIONS);\n\n const [mockSelectedOptionId, setMockSelectedOptionId] = useState<string | null>(null);\n const [wasUsingMockOptions, setWasUsingMockOptions] = useState(usingMockOptions);\n if (usingMockOptions !== wasUsingMockOptions) {\n setWasUsingMockOptions(usingMockOptions);\n setMockSelectedOptionId(null);\n }\n const selectedOptionId = usingMockOptions ? mockSelectedOptionId : ($data?.selectedOptionId ?? null);\n\n const [selectionError, setSelectionError] = useState<ShippingOptionSelectUserError | null>(null);\n const selectionToken = useRef(0);\n\n function selectOption(optionId: string, callbacks?: { onSettled?: (ok: boolean) => void }) {\n if (usingMockOptions) {\n setMockSelectedOptionId(optionId);\n callbacks?.onSettled?.(true);\n return;\n }\n setSelectionError(null);\n const dispatch = $actions?.shipping?.selectOption;\n if (!dispatch) {\n callbacks?.onSettled?.(false);\n return;\n }\n const token = ++selectionToken.current;\n dispatch(optionId).then((userErrors) => {\n if (selectionToken.current !== token) return;\n const [firstError] = userErrors;\n if (firstError) {\n setSelectionError(firstError);\n callbacks?.onSettled?.(false);\n } else {\n callbacks?.onSettled?.(true);\n }\n });\n }\n\n const contextValue = useMemo<ShippingSimulatorContextValue>(\n () => ({\n postalCode: '',\n setPostalCode: () => {},\n status: 'idle',\n shippingOptions: options,\n userErrors: [],\n submit: () => {},\n }),\n [options],\n );\n\n return { options, selectedOptionId, usingMockOptions, selectionError, selectOption, contextValue };\n}\n"],"mappings":";;;;AAoBA,MAAM,gBAAkC,CAAC;;;;;;;;;;;;;;;;AA0DzC,SAAgB,2BAA2B,EACzC,OAAO,WACP,UACA,eAK0B;CAC1B,MAAM,QAAQ,gBAAgB,SAAS;CACvC,MAAM,cAAc,OAAO;CAC3B,MAAM,mBAAmB,CAAC,aAAa,UAAU,CAAC,CAAC,aAAa;CAChE,MAAM,UAAU,aAAa,SAAS,cAAe,eAAe;CAEpE,MAAM,CAAC,sBAAsB,2BAA2B,SAAwB,IAAI;CACpF,MAAM,CAAC,qBAAqB,0BAA0B,SAAS,gBAAgB;CAC/E,IAAI,qBAAqB,qBAAqB;EAC5C,uBAAuB,gBAAgB;EACvC,wBAAwB,IAAI;CAC9B;CACA,MAAM,mBAAmB,mBAAmB,uBAAwB,OAAO,oBAAoB;CAE/F,MAAM,CAAC,gBAAgB,qBAAqB,SAA+C,IAAI;CAC/F,MAAM,iBAAiB,OAAO,CAAC;CAE/B,SAAS,aAAa,UAAkB,WAAmD;EACzF,IAAI,kBAAkB;GACpB,wBAAwB,QAAQ;GAChC,WAAW,YAAY,IAAI;GAC3B;EACF;EACA,kBAAkB,IAAI;EACtB,MAAM,WAAW,UAAU,UAAU;EACrC,IAAI,CAAC,UAAU;GACb,WAAW,YAAY,KAAK;GAC5B;EACF;EACA,MAAM,QAAQ,EAAE,eAAe;EAC/B,SAAS,QAAQ,CAAC,CAAC,MAAM,eAAe;GACtC,IAAI,eAAe,YAAY,OAAO;GACtC,MAAM,CAAC,cAAc;GACrB,IAAI,YAAY;IACd,kBAAkB,UAAU;IAC5B,WAAW,YAAY,KAAK;GAC9B,OACE,WAAW,YAAY,IAAI;EAE/B,CAAC;CACH;CAcA,OAAO;EAAE;EAAS;EAAkB;EAAkB;EAAgB;EAAc,cAZ/D,eACZ;GACL,YAAY;GACZ,qBAAqB,CAAC;GACtB,QAAQ;GACR,iBAAiB;GACjB,YAAY,CAAC;GACb,cAAc,CAAC;EACjB,IACA,CAAC,OAAO,CAGqF;CAAE;AACnG"}
@@ -1,19 +1,40 @@
1
+ import { ContentValue, MessageLocaleProp } from "../../core/dist/define-content-type.js";
1
2
  import { ComponentDefinition } from "../../core/dist/define-component.js";
2
3
  import "../../core/dist/index.js";
3
4
  import { ComponentActions } from "../../sdk/actions/types.js";
4
5
  import { ComponentPropsWithRef } from "react";
5
6
  //#region src/matter/email-identification/email-identification.d.ts
7
+ export declare const EmailIdentificationControlContent: {
8
+ readonly id: "email-identification-control";
9
+ readonly title: "Email Identification Control";
10
+ readonly description: "The inline message shown when saving the email fails.";
11
+ readonly schema: {
12
+ readonly type: "object";
13
+ readonly additionalProperties: false;
14
+ readonly properties: {
15
+ readonly genericErrorMessage: {
16
+ readonly type: "string";
17
+ readonly title: "Save failure message";
18
+ readonly description: "Shown for a network failure and for any refusal the shopper cannot act on.";
19
+ readonly format: "icu-message";
20
+ readonly messageSource: "Unable to save your details. Please try again.";
21
+ };
22
+ };
23
+ };
24
+ };
6
25
  /** ClientProfile slice forwarded by the reactive runtime — only `email` is consumed for pre-fill. */
7
26
  export type EmailIdentificationSlice = {
8
27
  email?: string | null;
9
28
  };
10
- export type EmailIdentificationControlProps = Omit<ComponentPropsWithRef<'div'>, 'onChange'> & {
29
+ export type EmailIdentificationControlProps = Omit<ComponentPropsWithRef<'div'>, 'onChange'> & MessageLocaleProp & {
11
30
  /** Accessible label passed to the EmailField. */
12
31
  label?: string;
13
32
  /** Input placeholder passed to the EmailField. */
14
33
  placeholder?: string;
15
34
  /** Inline error text for an invalid email format (port of `checkout/form-messages.invalid-email`). */
16
35
  invalidEmailMessage?: string;
36
+ /** The inline message for a refused save. */
37
+ $content?: ContentValue<typeof EmailIdentificationControlContent>;
17
38
  /** ClientProfile slice forwarded by the reactive runtime; `null` until the entity resolves. */
18
39
  $data?: EmailIdentificationSlice | null;
19
40
  /** Compiler-injected action surface; carries `identity.clientProfileUpdate`. */
@@ -29,9 +50,10 @@ export declare const EmailIdentificationControlDefinition: ComponentDefinition<E
29
50
  * flight the field is disabled and `data-fs-email-identification-pending` is present so a
30
51
  * checkout-CTA guard can block. When the session reports `canEditData: false` (identified but
31
52
  * unauthenticated claimed profile — VTEX refuses the write server-side) the field renders disabled
32
- * with `data-fs-email-identification-readonly`. Server `userErrors` are surfaced inline; the
53
+ * with `data-fs-email-identification-readonly`. Server `userErrors` are surfaced inline, worded by the
54
+ * `$content` field for their code (genericErrorMessage for a code it does not know); the
33
55
  * session state is never computed locally.
34
56
  */
35
- export declare function EmailIdentificationControl({ label, placeholder, invalidEmailMessage, $data: $dataProp, $actions: $actionsProp, className, ...props }: EmailIdentificationControlProps): import("react/jsx-runtime").JSX.Element;
57
+ export declare function EmailIdentificationControl({ label, placeholder, invalidEmailMessage, $content, $locale, $data: $dataProp, $actions: $actionsProp, className, ...props }: EmailIdentificationControlProps): import("react/jsx-runtime").JSX.Element;
36
58
  //#endregion
37
59
  //# sourceMappingURL=email-identification.d.ts.map
@@ -1,17 +1,17 @@
1
1
  "use client";
2
2
  import { defineComponent } from "../../core/dist/define-component.js";
3
+ import { defineContentType } from "../../core/dist/define-content-type.js";
3
4
  import "../../core/dist/index.js";
5
+ import { useMessageFormatter } from "../../sdk/i18n/use-message-formatter.js";
4
6
  import { EmailField, isValidEmail } from "../../particles/email-field/email-field.js";
5
7
  import { useActionsOverride } from "../../sdk/actions/actions-override-context.js";
8
+ import { formatErrorCode } from "../../sdk/i18n/format-error-code.js";
6
9
  import { useDataOverride } from "../../sdk/data/data-override-context.js";
7
10
  import { useSession } from "../session/session.js";
8
11
  import { useEffect, useState } from "react";
9
12
  import { jsx } from "react/jsx-runtime";
10
- const EmailIdentificationControlDefinition = defineComponent({
11
- name: "EmailIdentificationControl",
12
- importPath: "@vtex/faststore/components",
13
- component: EmailIdentificationControl,
14
- fragment: `
13
+ //#region src/matter/email-identification/email-identification.tsx
14
+ const fragment = `
15
15
  fragment EmailIdentificationData on Query {
16
16
  clientProfile {
17
17
  __typename
@@ -19,7 +19,39 @@ const EmailIdentificationControlDefinition = defineComponent({
19
19
  email
20
20
  }
21
21
  }
22
- `,
22
+ `;
23
+ const EmailIdentificationControlContent = defineContentType({
24
+ id: "email-identification-control",
25
+ title: "Email Identification Control",
26
+ description: "The inline message shown when saving the email fails.",
27
+ schema: {
28
+ type: "object",
29
+ additionalProperties: false,
30
+ properties: { genericErrorMessage: {
31
+ type: "string",
32
+ title: "Save failure message",
33
+ description: "Shown for a network failure and for any refusal the shopper cannot act on.",
34
+ format: "icu-message",
35
+ messageSource: "Unable to save your details. Please try again."
36
+ } }
37
+ }
38
+ });
39
+ /**
40
+ * `ClientProfileUpdateErrorCode` of API Core's schema plus the client-minted transport failure. None is
41
+ * something the shopper can fix by editing the email, so all share the generic message.
42
+ */
43
+ const EMAIL_IDENTIFICATION_ERROR_FIELDS = {
44
+ MISSING_CART_CONTEXT: "genericErrorMessage",
45
+ CART_NOT_FOUND: "genericErrorMessage",
46
+ NO_PROFILE_FIELD_PROVIDED: "genericErrorMessage",
47
+ NETWORK_ERROR: "genericErrorMessage"
48
+ };
49
+ const EmailIdentificationControlDefinition = defineComponent({
50
+ name: "EmailIdentificationControl",
51
+ importPath: "@vtex/faststore/components",
52
+ component: EmailIdentificationControl,
53
+ content: EmailIdentificationControlContent,
54
+ fragment,
23
55
  fetchStrategy: "reactive",
24
56
  actions: { identity: ["clientProfileUpdate"] },
25
57
  requiresContext: "session",
@@ -41,7 +73,7 @@ const EmailIdentificationControlDefinition = defineComponent({
41
73
  label: "Invalid email message"
42
74
  }
43
75
  },
44
- guideline: "Checkout-bound email field: pre-fills from clientProfile.email and persists a valid changed email via $actions.identity.clientProfileUpdate (anonymous→identified). Must be inside SessionRoot. See email-identification.md."
76
+ guideline: "Checkout-bound email field: pre-fills from clientProfile.email and persists a valid changed email via $actions.identity.clientProfileUpdate (anonymous→identified); a refused save shows the $content field genericErrorMessage. Must be inside SessionRoot. See email-identification.md."
45
77
  });
46
78
  /**
47
79
  * Matter that binds the presentational `EmailField` to the User Identity foundation. It reads
@@ -52,12 +84,14 @@ const EmailIdentificationControlDefinition = defineComponent({
52
84
  * flight the field is disabled and `data-fs-email-identification-pending` is present so a
53
85
  * checkout-CTA guard can block. When the session reports `canEditData: false` (identified but
54
86
  * unauthenticated claimed profile — VTEX refuses the write server-side) the field renders disabled
55
- * with `data-fs-email-identification-readonly`. Server `userErrors` are surfaced inline; the
87
+ * with `data-fs-email-identification-readonly`. Server `userErrors` are surfaced inline, worded by the
88
+ * `$content` field for their code (genericErrorMessage for a code it does not know); the
56
89
  * session state is never computed locally.
57
90
  */
58
- function EmailIdentificationControl({ label, placeholder, invalidEmailMessage, $data: $dataProp, $actions: $actionsProp, className, ...props }) {
91
+ function EmailIdentificationControl({ label, placeholder, invalidEmailMessage, $content, $locale, $data: $dataProp, $actions: $actionsProp, className, ...props }) {
59
92
  const $data = useDataOverride($dataProp);
60
93
  const $actions = useActionsOverride($actionsProp);
94
+ const { format } = useMessageFormatter(EmailIdentificationControlContent, $content);
61
95
  const { canEditData } = useSession();
62
96
  const readOnly = !canEditData;
63
97
  const savedEmail = $data?.email ?? "";
@@ -67,6 +101,9 @@ function EmailIdentificationControl({ label, placeholder, invalidEmailMessage, $
67
101
  useEffect(() => {
68
102
  setValue(savedEmail);
69
103
  }, [savedEmail]);
104
+ function serverErrorMessage(error) {
105
+ return formatErrorCode(EmailIdentificationControlContent, EMAIL_IDENTIFICATION_ERROR_FIELDS, error, format, "genericErrorMessage");
106
+ }
70
107
  function handleValueChange(next) {
71
108
  setValue(next);
72
109
  if (serverError) setServerError(null);
@@ -83,7 +120,7 @@ function EmailIdentificationControl({ label, placeholder, invalidEmailMessage, $
83
120
  setServerError(null);
84
121
  try {
85
122
  const errors = await $actions?.identity?.clientProfileUpdate?.({ email: trimmed }) ?? [];
86
- if (errors.length > 0) setServerError(errors[0]?.message ?? null);
123
+ if (errors.length > 0) setServerError(errors[0] ?? null);
87
124
  } finally {
88
125
  setPending(false);
89
126
  }
@@ -100,7 +137,7 @@ function EmailIdentificationControl({ label, placeholder, invalidEmailMessage, $
100
137
  value,
101
138
  disabled: pending || readOnly,
102
139
  invalid: serverError != null,
103
- errorMessage: serverError ?? invalidEmailMessage,
140
+ errorMessage: serverError ? serverErrorMessage(serverError) : invalidEmailMessage,
104
141
  onValueChange: handleValueChange,
105
142
  onBlur: handleBlur,
106
143
  required: true
@@ -108,6 +145,6 @@ function EmailIdentificationControl({ label, placeholder, invalidEmailMessage, $
108
145
  });
109
146
  }
110
147
  //#endregion
111
- export { EmailIdentificationControl, EmailIdentificationControlDefinition };
148
+ export { EMAIL_IDENTIFICATION_ERROR_FIELDS, EmailIdentificationControl, EmailIdentificationControlContent, EmailIdentificationControlDefinition };
112
149
 
113
150
  //# sourceMappingURL=email-identification.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"email-identification.js","names":[],"sources":["../../../src/matter/email-identification/email-identification.tsx"],"sourcesContent":["'use client';\n\nimport { defineComponent } from '@vtex/fs-core';\nimport type { ComponentPropsWithRef } from 'react';\nimport { useEffect, useState } from 'react';\nimport { EmailField, isValidEmail } from '../../particles/email-field/email-field.js';\nimport { useActionsOverride } from '../../sdk/actions/actions-override-context.js';\nimport type { ComponentActions } from '../../sdk/actions/types.js';\nimport { useDataOverride } from '../../sdk/data/data-override-context.js';\nimport { useSession } from '../session/session.js';\n\n// ---------------------------------------------------------------------------\n// GraphQL Fragment (colocated, ADR-0011) — reads only clientProfile.email.\n// Authored as a raw string (not the codegen graphql() factory), mirroring the ShippingSimulator\n// matter: the compiler derives the entity fragment on `clientProfile` and subscribes reactively.\n// ---------------------------------------------------------------------------\n\nconst fragment = /* GraphQL */ `\n fragment EmailIdentificationData on Query {\n clientProfile {\n __typename\n id\n email\n }\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** ClientProfile slice forwarded by the reactive runtime — only `email` is consumed for pre-fill. */\nexport type EmailIdentificationSlice = {\n email?: string | null;\n};\n\nexport type EmailIdentificationControlProps = Omit<ComponentPropsWithRef<'div'>, 'onChange'> & {\n /** Accessible label passed to the EmailField. */\n label?: string;\n /** Input placeholder passed to the EmailField. */\n placeholder?: string;\n /** Inline error text for an invalid email format (port of `checkout/form-messages.invalid-email`). */\n invalidEmailMessage?: string;\n /** ClientProfile slice forwarded by the reactive runtime; `null` until the entity resolves. */\n $data?: EmailIdentificationSlice | null;\n /** Compiler-injected action surface; carries `identity.clientProfileUpdate`. */\n $actions?: ComponentActions;\n};\n\n// ---------------------------------------------------------------------------\n// Definition\n// ---------------------------------------------------------------------------\n\nexport const EmailIdentificationControlDefinition = defineComponent<EmailIdentificationControlProps>({\n name: 'EmailIdentificationControl',\n importPath: '@vtex/faststore/components',\n component: EmailIdentificationControl,\n fragment,\n fetchStrategy: 'reactive',\n actions: { identity: ['clientProfileUpdate'] },\n requiresContext: 'session',\n editor: { label: 'Email Identification', category: 'identity' },\n schema: {\n label: { type: 'string', label: 'Label' },\n placeholder: { type: 'string', label: 'Placeholder' },\n invalidEmailMessage: { type: 'string', label: 'Invalid email message' },\n },\n guideline:\n 'Checkout-bound email field: pre-fills from clientProfile.email and persists a valid changed email via $actions.identity.clientProfileUpdate (anonymous→identified). Must be inside SessionRoot. See email-identification.md.',\n});\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\n/**\n * Matter that binds the presentational `EmailField` to the User Identity foundation. It reads\n * `clientProfile.email` (colocated reactive fragment) for the pre-fill, reads the identification\n * tri-state and `canEditData` from `useSession()` (which also enforces the `SessionRoot` ancestor),\n * and on a **valid, changed** email persists only the `email` field through\n * `$actions.identity.clientProfileUpdate` (async / pessimistic, Decision 1). While the write is in\n * flight the field is disabled and `data-fs-email-identification-pending` is present so a\n * checkout-CTA guard can block. When the session reports `canEditData: false` (identified but\n * unauthenticated claimed profile — VTEX refuses the write server-side) the field renders disabled\n * with `data-fs-email-identification-readonly`. Server `userErrors` are surfaced inline; the\n * session state is never computed locally.\n */\nexport function EmailIdentificationControl({\n label,\n placeholder,\n invalidEmailMessage,\n $data: $dataProp,\n $actions: $actionsProp,\n className,\n ...props\n}: EmailIdentificationControlProps) {\n const $data = useDataOverride($dataProp);\n const $actions = useActionsOverride($actionsProp);\n // Also enforces the SessionRoot ancestor: useSession() throws when rendered outside one.\n const { canEditData } = useSession();\n // VTEX refuses profile edits for an identified-but-unauthenticated claimed profile; render the\n // field read-only instead of accepting a write that is doomed server-side.\n const readOnly = !canEditData;\n\n const savedEmail = $data?.email ?? '';\n const [value, setValue] = useState(savedEmail);\n const [pending, setPending] = useState(false);\n const [serverError, setServerError] = useState<string | null>(null);\n\n // Sync the pre-fill when the saved profile email resolves or changes (identified/logged-in shopper).\n // Does not fire while the shopper is typing, since `savedEmail` only changes when the profile does.\n useEffect(() => {\n setValue(savedEmail);\n }, [savedEmail]);\n\n function handleValueChange(next: string) {\n setValue(next);\n if (serverError) setServerError(null);\n }\n\n async function handleBlur() {\n const trimmed = value.trim();\n // Cleared field → re-fill with the saved email; clearing must not visually \"un-identify\"\n // (changing email = switching user is a deliberate act, done by typing a new one).\n if (trimmed === '' && savedEmail !== '') {\n setValue(savedEmail);\n return;\n }\n // Invalid format → EmailField shows its own inline error; no persist, no step advance.\n if (!isValidEmail(trimmed)) return;\n // Unchanged → nothing to persist.\n if (trimmed === savedEmail) return;\n\n setPending(true);\n setServerError(null);\n try {\n const errors = (await $actions?.identity?.clientProfileUpdate?.({ email: trimmed })) ?? [];\n if (errors.length > 0) setServerError(errors[0]?.message ?? null);\n } finally {\n setPending(false);\n }\n }\n\n return (\n <div\n {...props}\n className={className}\n data-fs-email-identification-control=\"\"\n {...(pending ? { 'data-fs-email-identification-pending': '' } : {})}\n {...(readOnly ? { 'data-fs-email-identification-readonly': '' } : {})}\n >\n <EmailField\n label={label}\n placeholder={placeholder}\n value={value}\n disabled={pending || readOnly}\n invalid={serverError != null}\n errorMessage={serverError ?? invalidEmailMessage}\n onValueChange={handleValueChange}\n onBlur={handleBlur}\n required\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;AAqDA,MAAa,uCAAuC,gBAAiD;CACnG,MAAM;CACN,YAAY;CACZ,WAAW;CACX;;;;;;;;;CACA,eAAe;CACf,SAAS,EAAE,UAAU,CAAC,qBAAqB,EAAE;CAC7C,iBAAiB;CACjB,QAAQ;EAAE,OAAO;EAAwB,UAAU;CAAW;CAC9D,QAAQ;EACN,OAAO;GAAE,MAAM;GAAU,OAAO;EAAQ;EACxC,aAAa;GAAE,MAAM;GAAU,OAAO;EAAc;EACpD,qBAAqB;GAAE,MAAM;GAAU,OAAO;EAAwB;CACxE;CACA,WACE;AACJ,CAAC;;;;;;;;;;;;;AAkBD,SAAgB,2BAA2B,EACzC,OACA,aACA,qBACA,OAAO,WACP,UAAU,cACV,WACA,GAAG,SAC+B;CAClC,MAAM,QAAQ,gBAAgB,SAAS;CACvC,MAAM,WAAW,mBAAmB,YAAY;CAEhD,MAAM,EAAE,gBAAgB,WAAW;CAGnC,MAAM,WAAW,CAAC;CAElB,MAAM,aAAa,OAAO,SAAS;CACnC,MAAM,CAAC,OAAO,YAAY,SAAS,UAAU;CAC7C,MAAM,CAAC,SAAS,cAAc,SAAS,KAAK;CAC5C,MAAM,CAAC,aAAa,kBAAkB,SAAwB,IAAI;CAIlE,gBAAgB;EACd,SAAS,UAAU;CACrB,GAAG,CAAC,UAAU,CAAC;CAEf,SAAS,kBAAkB,MAAc;EACvC,SAAS,IAAI;EACb,IAAI,aAAa,eAAe,IAAI;CACtC;CAEA,eAAe,aAAa;EAC1B,MAAM,UAAU,MAAM,KAAK;EAG3B,IAAI,YAAY,MAAM,eAAe,IAAI;GACvC,SAAS,UAAU;GACnB;EACF;EAEA,IAAI,CAAC,aAAa,OAAO,GAAG;EAE5B,IAAI,YAAY,YAAY;EAE5B,WAAW,IAAI;EACf,eAAe,IAAI;EACnB,IAAI;GACF,MAAM,SAAU,MAAM,UAAU,UAAU,sBAAsB,EAAE,OAAO,QAAQ,CAAC,KAAM,CAAC;GACzF,IAAI,OAAO,SAAS,GAAG,eAAe,OAAO,EAAE,EAAE,WAAW,IAAI;EAClE,UAAU;GACR,WAAW,KAAK;EAClB;CACF;CAEA,OACE,oBAAC,OAAD;EACE,GAAI;EACO;EACX,wCAAqC;EACrC,GAAK,UAAU,EAAE,wCAAwC,GAAG,IAAI,CAAC;EACjE,GAAK,WAAW,EAAE,yCAAyC,GAAG,IAAI,CAAC;EAEnE,UAAA,oBAAC,YAAD;GACS;GACM;GACN;GACP,UAAU,WAAW;GACrB,SAAS,eAAe;GACxB,cAAc,eAAe;GAC7B,eAAe;GACf,QAAQ;GACR,UAAA;EACD,CAAA;CACE,CAAA;AAET"}
1
+ {"version":3,"file":"email-identification.js","names":[],"sources":["../../../src/matter/email-identification/email-identification.tsx"],"sourcesContent":["'use client';\n\nimport {\n type ContentValue,\n defineComponent,\n defineContentType,\n type MessageFieldName,\n type MessageLocaleProp,\n} from '@vtex/fs-core';\nimport type { ComponentPropsWithRef } from 'react';\nimport { useEffect, useState } from 'react';\nimport { EmailField, isValidEmail } from '../../particles/email-field/email-field.js';\nimport { useActionsOverride } from '../../sdk/actions/actions-override-context.js';\nimport type { ComponentActions } from '../../sdk/actions/types.js';\nimport { useDataOverride } from '../../sdk/data/data-override-context.js';\nimport { formatErrorCode } from '../../sdk/i18n/format-error-code.js';\nimport { useMessageFormatter } from '../../sdk/i18n/use-message-formatter.js';\nimport type { ClientProfileUserError } from '../../sdk/identity/operations.js';\nimport { useSession } from '../session/session.js';\n\n// ---------------------------------------------------------------------------\n// GraphQL Fragment (colocated, ADR-0011) — reads only clientProfile.email.\n// Authored as a raw string (not the codegen graphql() factory), mirroring the ShippingSimulator\n// matter: the compiler derives the entity fragment on `clientProfile` and subscribes reactively.\n// ---------------------------------------------------------------------------\n\nconst fragment = /* GraphQL */ `\n fragment EmailIdentificationData on Query {\n clientProfile {\n __typename\n id\n email\n }\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Content model\n// ---------------------------------------------------------------------------\n\nexport const EmailIdentificationControlContent = defineContentType({\n id: 'email-identification-control',\n title: 'Email Identification Control',\n description: 'The inline message shown when saving the email fails.',\n schema: {\n type: 'object',\n additionalProperties: false,\n properties: {\n genericErrorMessage: {\n type: 'string',\n title: 'Save failure message',\n description: 'Shown for a network failure and for any refusal the shopper cannot act on.',\n format: 'icu-message',\n messageSource: 'Unable to save your details. Please try again.',\n },\n },\n },\n});\n\n/**\n * `ClientProfileUpdateErrorCode` of API Core's schema plus the client-minted transport failure. None is\n * something the shopper can fix by editing the email, so all share the generic message.\n */\nexport const EMAIL_IDENTIFICATION_ERROR_FIELDS = {\n MISSING_CART_CONTEXT: 'genericErrorMessage',\n CART_NOT_FOUND: 'genericErrorMessage',\n NO_PROFILE_FIELD_PROVIDED: 'genericErrorMessage',\n NETWORK_ERROR: 'genericErrorMessage',\n} as const satisfies Record<string, MessageFieldName<typeof EmailIdentificationControlContent>>;\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** ClientProfile slice forwarded by the reactive runtime — only `email` is consumed for pre-fill. */\nexport type EmailIdentificationSlice = {\n email?: string | null;\n};\n\nexport type EmailIdentificationControlProps = Omit<ComponentPropsWithRef<'div'>, 'onChange'> &\n MessageLocaleProp & {\n /** Accessible label passed to the EmailField. */\n label?: string;\n /** Input placeholder passed to the EmailField. */\n placeholder?: string;\n /** Inline error text for an invalid email format (port of `checkout/form-messages.invalid-email`). */\n invalidEmailMessage?: string;\n /** The inline message for a refused save. */\n $content?: ContentValue<typeof EmailIdentificationControlContent>;\n /** ClientProfile slice forwarded by the reactive runtime; `null` until the entity resolves. */\n $data?: EmailIdentificationSlice | null;\n /** Compiler-injected action surface; carries `identity.clientProfileUpdate`. */\n $actions?: ComponentActions;\n };\n\n// ---------------------------------------------------------------------------\n// Definition\n// ---------------------------------------------------------------------------\n\nexport const EmailIdentificationControlDefinition = defineComponent<EmailIdentificationControlProps>({\n name: 'EmailIdentificationControl',\n importPath: '@vtex/faststore/components',\n component: EmailIdentificationControl,\n content: EmailIdentificationControlContent,\n fragment,\n fetchStrategy: 'reactive',\n actions: { identity: ['clientProfileUpdate'] },\n requiresContext: 'session',\n editor: { label: 'Email Identification', category: 'identity' },\n schema: {\n label: { type: 'string', label: 'Label' },\n placeholder: { type: 'string', label: 'Placeholder' },\n invalidEmailMessage: { type: 'string', label: 'Invalid email message' },\n },\n guideline:\n 'Checkout-bound email field: pre-fills from clientProfile.email and persists a valid changed email via $actions.identity.clientProfileUpdate (anonymous→identified); a refused save shows the $content field genericErrorMessage. Must be inside SessionRoot. See email-identification.md.',\n});\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\n/**\n * Matter that binds the presentational `EmailField` to the User Identity foundation. It reads\n * `clientProfile.email` (colocated reactive fragment) for the pre-fill, reads the identification\n * tri-state and `canEditData` from `useSession()` (which also enforces the `SessionRoot` ancestor),\n * and on a **valid, changed** email persists only the `email` field through\n * `$actions.identity.clientProfileUpdate` (async / pessimistic, Decision 1). While the write is in\n * flight the field is disabled and `data-fs-email-identification-pending` is present so a\n * checkout-CTA guard can block. When the session reports `canEditData: false` (identified but\n * unauthenticated claimed profile — VTEX refuses the write server-side) the field renders disabled\n * with `data-fs-email-identification-readonly`. Server `userErrors` are surfaced inline, worded by the\n * `$content` field for their code (genericErrorMessage for a code it does not know); the\n * session state is never computed locally.\n */\nexport function EmailIdentificationControl({\n label,\n placeholder,\n invalidEmailMessage,\n $content,\n $locale,\n $data: $dataProp,\n $actions: $actionsProp,\n className,\n ...props\n}: EmailIdentificationControlProps) {\n const $data = useDataOverride($dataProp);\n const $actions = useActionsOverride($actionsProp);\n const { format } = useMessageFormatter(EmailIdentificationControlContent, $content);\n // Also enforces the SessionRoot ancestor: useSession() throws when rendered outside one.\n const { canEditData } = useSession();\n // VTEX refuses profile edits for an identified-but-unauthenticated claimed profile; render the\n // field read-only instead of accepting a write that is doomed server-side.\n const readOnly = !canEditData;\n\n const savedEmail = $data?.email ?? '';\n const [value, setValue] = useState(savedEmail);\n const [pending, setPending] = useState(false);\n const [serverError, setServerError] = useState<ClientProfileUserError | null>(null);\n\n // Sync the pre-fill when the saved profile email resolves or changes (identified/logged-in shopper).\n // Does not fire while the shopper is typing, since `savedEmail` only changes when the profile does.\n useEffect(() => {\n setValue(savedEmail);\n }, [savedEmail]);\n\n function serverErrorMessage(error: ClientProfileUserError): string {\n return formatErrorCode(\n EmailIdentificationControlContent,\n EMAIL_IDENTIFICATION_ERROR_FIELDS,\n error,\n format,\n 'genericErrorMessage',\n );\n }\n\n function handleValueChange(next: string) {\n setValue(next);\n if (serverError) setServerError(null);\n }\n\n async function handleBlur() {\n const trimmed = value.trim();\n // Cleared field → re-fill with the saved email; clearing must not visually \"un-identify\"\n // (changing email = switching user is a deliberate act, done by typing a new one).\n if (trimmed === '' && savedEmail !== '') {\n setValue(savedEmail);\n return;\n }\n // Invalid format → EmailField shows its own inline error; no persist, no step advance.\n if (!isValidEmail(trimmed)) return;\n // Unchanged → nothing to persist.\n if (trimmed === savedEmail) return;\n\n setPending(true);\n setServerError(null);\n try {\n const errors = (await $actions?.identity?.clientProfileUpdate?.({ email: trimmed })) ?? [];\n if (errors.length > 0) setServerError(errors[0] ?? null);\n } finally {\n setPending(false);\n }\n }\n\n return (\n <div\n {...props}\n className={className}\n data-fs-email-identification-control=\"\"\n {...(pending ? { 'data-fs-email-identification-pending': '' } : {})}\n {...(readOnly ? { 'data-fs-email-identification-readonly': '' } : {})}\n >\n <EmailField\n label={label}\n placeholder={placeholder}\n value={value}\n disabled={pending || readOnly}\n invalid={serverError != null}\n errorMessage={serverError ? serverErrorMessage(serverError) : invalidEmailMessage}\n onValueChange={handleValueChange}\n onBlur={handleBlur}\n required\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AA0BA,MAAM,WAAyB;;;;;;;;;AAc/B,MAAa,oCAAoC,kBAAkB;CACjE,IAAI;CACJ,OAAO;CACP,aAAa;CACb,QAAQ;EACN,MAAM;EACN,sBAAsB;EACtB,YAAY,EACV,qBAAqB;GACnB,MAAM;GACN,OAAO;GACP,aAAa;GACb,QAAQ;GACR,eAAe;EACjB,EACF;CACF;AACF,CAAC;;;;;AAMD,MAAa,oCAAoC;CAC/C,sBAAsB;CACtB,gBAAgB;CAChB,2BAA2B;CAC3B,eAAe;AACjB;AA+BA,MAAa,uCAAuC,gBAAiD;CACnG,MAAM;CACN,YAAY;CACZ,WAAW;CACX,SAAS;CACT;CACA,eAAe;CACf,SAAS,EAAE,UAAU,CAAC,qBAAqB,EAAE;CAC7C,iBAAiB;CACjB,QAAQ;EAAE,OAAO;EAAwB,UAAU;CAAW;CAC9D,QAAQ;EACN,OAAO;GAAE,MAAM;GAAU,OAAO;EAAQ;EACxC,aAAa;GAAE,MAAM;GAAU,OAAO;EAAc;EACpD,qBAAqB;GAAE,MAAM;GAAU,OAAO;EAAwB;CACxE;CACA,WACE;AACJ,CAAC;;;;;;;;;;;;;;AAmBD,SAAgB,2BAA2B,EACzC,OACA,aACA,qBACA,UACA,SACA,OAAO,WACP,UAAU,cACV,WACA,GAAG,SAC+B;CAClC,MAAM,QAAQ,gBAAgB,SAAS;CACvC,MAAM,WAAW,mBAAmB,YAAY;CAChD,MAAM,EAAE,WAAW,oBAAoB,mCAAmC,QAAQ;CAElF,MAAM,EAAE,gBAAgB,WAAW;CAGnC,MAAM,WAAW,CAAC;CAElB,MAAM,aAAa,OAAO,SAAS;CACnC,MAAM,CAAC,OAAO,YAAY,SAAS,UAAU;CAC7C,MAAM,CAAC,SAAS,cAAc,SAAS,KAAK;CAC5C,MAAM,CAAC,aAAa,kBAAkB,SAAwC,IAAI;CAIlF,gBAAgB;EACd,SAAS,UAAU;CACrB,GAAG,CAAC,UAAU,CAAC;CAEf,SAAS,mBAAmB,OAAuC;EACjE,OAAO,gBACL,mCACA,mCACA,OACA,QACA,qBACF;CACF;CAEA,SAAS,kBAAkB,MAAc;EACvC,SAAS,IAAI;EACb,IAAI,aAAa,eAAe,IAAI;CACtC;CAEA,eAAe,aAAa;EAC1B,MAAM,UAAU,MAAM,KAAK;EAG3B,IAAI,YAAY,MAAM,eAAe,IAAI;GACvC,SAAS,UAAU;GACnB;EACF;EAEA,IAAI,CAAC,aAAa,OAAO,GAAG;EAE5B,IAAI,YAAY,YAAY;EAE5B,WAAW,IAAI;EACf,eAAe,IAAI;EACnB,IAAI;GACF,MAAM,SAAU,MAAM,UAAU,UAAU,sBAAsB,EAAE,OAAO,QAAQ,CAAC,KAAM,CAAC;GACzF,IAAI,OAAO,SAAS,GAAG,eAAe,OAAO,MAAM,IAAI;EACzD,UAAU;GACR,WAAW,KAAK;EAClB;CACF;CAEA,OACE,oBAAC,OAAD;EACE,GAAI;EACO;EACX,wCAAqC;EACrC,GAAK,UAAU,EAAE,wCAAwC,GAAG,IAAI,CAAC;EACjE,GAAK,WAAW,EAAE,yCAAyC,GAAG,IAAI,CAAC;EAEnE,UAAA,oBAAC,YAAD;GACS;GACM;GACN;GACP,UAAU,WAAW;GACrB,SAAS,eAAe;GACxB,cAAc,cAAc,mBAAmB,WAAW,IAAI;GAC9D,eAAe;GACf,QAAQ;GACR,UAAA;EACD,CAAA;CACE,CAAA;AAET"}
@@ -1,3 +1,4 @@
1
+ import { ContentValue, MessageLocaleProp } from "../../core/dist/define-content-type.js";
1
2
  import { ComponentDefinition } from "../../core/dist/define-component.js";
2
3
  import "../../core/dist/index.js";
3
4
  import { ComponentPropsWithRef } from "react";
@@ -27,17 +28,88 @@ export type FreeShippingProgressRootProps = ComponentPropsWithRef<'div'> & {
27
28
  itemsTotal?: number;
28
29
  $data?: FreeShippingProgressData['cart'] | null;
29
30
  };
30
- export type FreeShippingProgressBarProps = ComponentPropsWithRef<'div'>;
31
- export type FreeShippingProgressMessageProps = ComponentPropsWithRef<'div'> & {
32
- label?: string;
33
- qualifiedLabel?: string;
31
+ export declare const FreeShippingProgressMessageContent: {
32
+ readonly id: "free-shipping-progress-message";
33
+ readonly title: "Free Shipping Progress Message";
34
+ readonly description: "The below-threshold and earned free-shipping messages.";
35
+ readonly schema: {
36
+ readonly type: "object";
37
+ readonly additionalProperties: false;
38
+ readonly properties: {
39
+ readonly label: {
40
+ readonly type: "string";
41
+ readonly title: "Below-threshold label";
42
+ readonly description: "Shown while the cart is below the threshold; value is the formatted amount still missing.";
43
+ readonly format: "icu-message";
44
+ readonly messageSource: "{value} away from free shipping";
45
+ readonly messageArguments: {
46
+ readonly type: "object";
47
+ readonly properties: {
48
+ readonly value: {
49
+ readonly type: "string";
50
+ };
51
+ };
52
+ };
53
+ readonly messageExample: {
54
+ readonly value: "$25.00";
55
+ };
56
+ };
57
+ readonly qualifiedLabel: {
58
+ readonly type: "string";
59
+ readonly title: "Qualified label";
60
+ readonly format: "icu-message";
61
+ readonly messageSource: "You got free shipping!";
62
+ };
63
+ };
64
+ };
65
+ };
66
+ export declare const FreeShippingProgressBarContent: {
67
+ readonly id: "free-shipping-progress-bar";
68
+ readonly title: "Free Shipping Progress Bar";
69
+ readonly description: "The value text a screen reader announces for the progress bar.";
70
+ readonly schema: {
71
+ readonly type: "object";
72
+ readonly additionalProperties: false;
73
+ readonly properties: {
74
+ readonly valueText: {
75
+ readonly type: "string";
76
+ readonly title: "Below-threshold value text";
77
+ readonly description: "Announced while the cart is below the threshold; value is the formatted amount still missing.";
78
+ readonly format: "icu-message";
79
+ readonly messageSource: "{value} left for free shipping";
80
+ readonly messageArguments: {
81
+ readonly type: "object";
82
+ readonly properties: {
83
+ readonly value: {
84
+ readonly type: "string";
85
+ };
86
+ };
87
+ };
88
+ readonly messageExample: {
89
+ readonly value: "$25.00";
90
+ };
91
+ };
92
+ readonly qualifiedValueText: {
93
+ readonly type: "string";
94
+ readonly title: "Qualified value text";
95
+ readonly format: "icu-message";
96
+ readonly messageSource: "Free shipping earned";
97
+ };
98
+ };
99
+ };
100
+ };
101
+ export type FreeShippingProgressBarProps = ComponentPropsWithRef<'div'> & MessageLocaleProp & {
102
+ $content?: ContentValue<typeof FreeShippingProgressBarContent>;
103
+ };
104
+ export type FreeShippingProgressMessageProps = ComponentPropsWithRef<'div'> & MessageLocaleProp & {
105
+ $content?: ContentValue<typeof FreeShippingProgressMessageContent>;
34
106
  };
35
107
  export declare const FreeShippingProgressRootDefinition: ComponentDefinition<FreeShippingProgressRootProps>;
36
- export declare const FreeShippingProgressBarDefinition: ComponentDefinition<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>>;
108
+ export declare const FreeShippingProgressBarDefinition: ComponentDefinition<FreeShippingProgressBarProps>;
37
109
  export declare const FreeShippingProgressMessageDefinition: ComponentDefinition<FreeShippingProgressMessageProps>;
38
110
  export declare function FreeShippingProgressRoot({ threshold, remaining, qualified, itemsTotal, $data: $dataProp, className, children, ...props }: FreeShippingProgressRootProps): import("react/jsx-runtime").JSX.Element | null;
39
- export declare function FreeShippingProgressBar({ className, ...props }: FreeShippingProgressBarProps): import("react/jsx-runtime").JSX.Element;
40
- export declare function FreeShippingProgressMessage({ label, qualifiedLabel, className, children, ...props }: FreeShippingProgressMessageProps): import("react/jsx-runtime").JSX.Element;
111
+ export declare function FreeShippingProgressBar({ $content, $locale, className, ...props }: FreeShippingProgressBarProps): import("react/jsx-runtime").JSX.Element;
112
+ export declare function FreeShippingProgressMessage({ $content, $locale, className, children, ...props }: FreeShippingProgressMessageProps): import("react/jsx-runtime").JSX.Element;
41
113
  export declare const FreeShippingProgress: {
42
114
  Root: typeof FreeShippingProgressRoot;
43
115
  Bar: typeof FreeShippingProgressBar;
@@ -1,13 +1,73 @@
1
1
  "use client";
2
2
  import { defineComponent } from "../../core/dist/define-component.js";
3
+ import { defineContentType } from "../../core/dist/define-content-type.js";
3
4
  import "../../core/dist/index.js";
4
5
  import { useStorefrontContext } from "../../sdk/context/storefront-context.js";
6
+ import { useMessageFormatter } from "../../sdk/i18n/use-message-formatter.js";
5
7
  import { useDataOverride } from "../../sdk/data/data-override-context.js";
6
8
  import { isFiniteAmount } from "../cart/cart.js";
7
9
  import { Meter } from "../../particles/meter/meter.js";
8
10
  import { createContext, useContext } from "react";
9
11
  import { jsx } from "react/jsx-runtime";
10
12
  //#region src/matter/free-shipping-progress/free-shipping-progress.tsx
13
+ const FreeShippingProgressMessageContent = defineContentType({
14
+ id: "free-shipping-progress-message",
15
+ title: "Free Shipping Progress Message",
16
+ description: "The below-threshold and earned free-shipping messages.",
17
+ schema: {
18
+ type: "object",
19
+ additionalProperties: false,
20
+ properties: {
21
+ label: {
22
+ type: "string",
23
+ title: "Below-threshold label",
24
+ description: "Shown while the cart is below the threshold; value is the formatted amount still missing.",
25
+ format: "icu-message",
26
+ messageSource: "{value} away from free shipping",
27
+ messageArguments: {
28
+ type: "object",
29
+ properties: { value: { type: "string" } }
30
+ },
31
+ messageExample: { value: "$25.00" }
32
+ },
33
+ qualifiedLabel: {
34
+ type: "string",
35
+ title: "Qualified label",
36
+ format: "icu-message",
37
+ messageSource: "You got free shipping!"
38
+ }
39
+ }
40
+ }
41
+ });
42
+ const FreeShippingProgressBarContent = defineContentType({
43
+ id: "free-shipping-progress-bar",
44
+ title: "Free Shipping Progress Bar",
45
+ description: "The value text a screen reader announces for the progress bar.",
46
+ schema: {
47
+ type: "object",
48
+ additionalProperties: false,
49
+ properties: {
50
+ valueText: {
51
+ type: "string",
52
+ title: "Below-threshold value text",
53
+ description: "Announced while the cart is below the threshold; value is the formatted amount still missing.",
54
+ format: "icu-message",
55
+ messageSource: "{value} left for free shipping",
56
+ messageArguments: {
57
+ type: "object",
58
+ properties: { value: { type: "string" } }
59
+ },
60
+ messageExample: { value: "$25.00" }
61
+ },
62
+ qualifiedValueText: {
63
+ type: "string",
64
+ title: "Qualified value text",
65
+ format: "icu-message",
66
+ messageSource: "Free shipping earned"
67
+ }
68
+ }
69
+ }
70
+ });
11
71
  const fragment = `
12
72
  fragment FreeShippingProgressData on Query {
13
73
  cart {
@@ -122,34 +182,25 @@ const FreeShippingProgressBarDefinition = defineComponent({
122
182
  name: "FreeShippingProgressBar",
123
183
  importPath: "@vtex/faststore/components",
124
184
  component: FreeShippingProgressBar,
185
+ content: FreeShippingProgressBarContent,
125
186
  editor: {
126
187
  label: "Free Shipping Progress Bar",
127
188
  category: "commerce"
128
189
  },
129
190
  schema: {},
130
- guideline: "Meter bar that fills toward the free-shipping goal, full when earned. Must be inside FreeShippingProgressRoot. See free-shipping-progress.md."
191
+ guideline: "Meter bar that fills toward the free-shipping goal, full when earned; screen readers announce the $content fields valueText ({value} is the formatted remaining amount) and qualifiedValueText. Must be inside FreeShippingProgressRoot. See free-shipping-progress.md."
131
192
  });
132
193
  const FreeShippingProgressMessageDefinition = defineComponent({
133
194
  name: "FreeShippingProgressMessage",
134
195
  importPath: "@vtex/faststore/components",
135
196
  component: FreeShippingProgressMessage,
197
+ content: FreeShippingProgressMessageContent,
136
198
  editor: {
137
199
  label: "Free Shipping Progress Message",
138
200
  category: "commerce"
139
201
  },
140
- schema: {
141
- label: {
142
- type: "string",
143
- default: "faltam {value} para frete grátis",
144
- label: "Below-threshold Label"
145
- },
146
- qualifiedLabel: {
147
- type: "string",
148
- default: "você ganhou frete grátis!",
149
- label: "Qualified Label"
150
- }
151
- },
152
- guideline: "Below-threshold vs earned copy, front-formatted from the active storefront context. Must be inside FreeShippingProgressRoot. See free-shipping-progress.md."
202
+ schema: {},
203
+ guideline: "Below-threshold vs earned copy from the $content fields label ({value} is the formatted remaining amount) and qualifiedLabel; children replace both. Must be inside FreeShippingProgressRoot. See free-shipping-progress.md."
153
204
  });
154
205
  function FreeShippingProgressRoot({ threshold, remaining, qualified, itemsTotal, $data: $dataProp, className, children, ...props }) {
155
206
  const { currency } = useStorefrontContext();
@@ -176,11 +227,13 @@ function FreeShippingProgressRoot({ threshold, remaining, qualified, itemsTotal,
176
227
  })
177
228
  });
178
229
  }
179
- function FreeShippingProgressBar({ className, ...props }) {
230
+ function FreeShippingProgressBar({ $content, $locale, className, ...props }) {
180
231
  const { fill, isQualified, liveRemaining } = useFreeShippingProgress();
181
232
  const { locale, currency } = useStorefrontContext();
182
- const ariaValueText = isQualified ? "frete grátis conquistado" : `${formatCurrency(liveRemaining, locale, currency)} restantes para frete grátis`;
233
+ const { format } = useMessageFormatter(FreeShippingProgressBarContent, $content);
234
+ const ariaValueText = isQualified ? format("qualifiedValueText") : format("valueText", { value: formatCurrency(liveRemaining, locale, currency) });
183
235
  return /* @__PURE__ */ jsx(Meter.Root, {
236
+ "aria-label": "Progresso para frete grátis",
184
237
  ...props,
185
238
  value: Math.round(fill * 100),
186
239
  min: 0,
@@ -191,15 +244,19 @@ function FreeShippingProgressBar({ className, ...props }) {
191
244
  children: /* @__PURE__ */ jsx(Meter.Track, { children: /* @__PURE__ */ jsx(Meter.Indicator, {}) })
192
245
  });
193
246
  }
194
- function FreeShippingProgressMessage({ label = "faltam {value} para frete grátis", qualifiedLabel = "você ganhou frete grátis!", className, children, ...props }) {
247
+ function FreeShippingProgressMessage({ $content, $locale, className, children, ...props }) {
195
248
  const { isQualified, liveRemaining } = useFreeShippingProgress();
196
249
  const { locale, currency } = useStorefrontContext();
197
- const text = isQualified ? qualifiedLabel : label.replace("{value}", formatCurrency(liveRemaining, locale, currency));
250
+ const { format } = useMessageFormatter(FreeShippingProgressMessageContent, $content);
251
+ function message() {
252
+ if (isQualified) return format("qualifiedLabel");
253
+ return format("label", { value: formatCurrency(liveRemaining, locale, currency) });
254
+ }
198
255
  return /* @__PURE__ */ jsx("div", {
199
256
  ...props,
200
257
  className,
201
258
  "data-fs-free-shipping-progress-message": "",
202
- children: children ?? text
259
+ children: children ?? message()
203
260
  });
204
261
  }
205
262
  const FreeShippingProgress = {
@@ -208,6 +265,6 @@ const FreeShippingProgress = {
208
265
  Message: FreeShippingProgressMessage
209
266
  };
210
267
  //#endregion
211
- export { FreeShippingProgress, FreeShippingProgressBar, FreeShippingProgressBarDefinition, FreeShippingProgressMessage, FreeShippingProgressMessageDefinition, FreeShippingProgressRoot, FreeShippingProgressRootDefinition };
268
+ export { FreeShippingProgress, FreeShippingProgressBar, FreeShippingProgressBarContent, FreeShippingProgressBarDefinition, FreeShippingProgressMessage, FreeShippingProgressMessageContent, FreeShippingProgressMessageDefinition, FreeShippingProgressRoot, FreeShippingProgressRootDefinition };
212
269
 
213
270
  //# sourceMappingURL=free-shipping-progress.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"free-shipping-progress.js","names":[],"sources":["../../../src/matter/free-shipping-progress/free-shipping-progress.tsx"],"sourcesContent":["'use client';\n\nimport { defineComponent } from '@vtex/fs-core';\nimport { type ComponentPropsWithRef, createContext, useContext } from 'react';\nimport { Meter } from '../../particles/meter/meter.js';\nimport { useStorefrontContext } from '../../sdk/context/storefront-context.js';\nimport { useDataOverride } from '../../sdk/data/data-override-context.js';\nimport { isFiniteAmount } from '../cart/cart.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ntype MoneyValue = { amount: number | string; currencyCode: string };\n\ntype FreeShippingProgressData = {\n cart?: {\n id: string;\n totalizers?: { id: string; value: MoneyValue }[] | null;\n freeShippingProgress?: {\n threshold: MoneyValue | null;\n remaining: MoneyValue;\n qualified: boolean;\n } | null;\n } | null;\n};\n\ntype FreeShippingProgressContextValue = {\n isQualified: boolean;\n fill: number;\n liveRemaining: number;\n};\n\nexport type FreeShippingProgressRootProps = ComponentPropsWithRef<'div'> & {\n threshold?: number;\n remaining?: number;\n qualified?: boolean;\n itemsTotal?: number;\n $data?: FreeShippingProgressData['cart'] | null;\n};\n\nexport type FreeShippingProgressBarProps = ComponentPropsWithRef<'div'>;\nexport type FreeShippingProgressMessageProps = ComponentPropsWithRef<'div'> & {\n label?: string;\n qualifiedLabel?: string;\n};\n\n// ---------------------------------------------------------------------------\n// GraphQL Fragment — narrow cart slice (Items totalizer + freeShippingProgress)\n// ---------------------------------------------------------------------------\n\nconst fragment = /* GraphQL */ `\n fragment FreeShippingProgressData on Query {\n cart {\n id\n totalizers {\n id\n value {\n amount\n currencyCode\n }\n }\n freeShippingProgress {\n threshold {\n amount\n currencyCode\n }\n remaining {\n amount\n currencyCode\n }\n qualified\n }\n }\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Context\n// ---------------------------------------------------------------------------\n\nconst FSP_CONTEXT_UNSET = Symbol('FreeShippingProgressContextUnset');\n\nconst FreeShippingProgressContext = createContext<FreeShippingProgressContextValue | typeof FSP_CONTEXT_UNSET>(\n FSP_CONTEXT_UNSET,\n);\n\nfunction useFreeShippingProgress(): FreeShippingProgressContextValue {\n const ctx = useContext(FreeShippingProgressContext);\n if (ctx === FSP_CONTEXT_UNSET) {\n throw new Error('useFreeShippingProgress() must be used inside a <FreeShippingProgressRoot> subtree.');\n }\n return ctx;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction formatCurrency(value: number, locale: string, currency: string): string {\n return new Intl.NumberFormat(locale, { style: 'currency', currency }).format(value);\n}\n\nfunction clamp01(value: number): number {\n return Math.min(Math.max(value, 0), 1);\n}\n\ntype FreeShippingProgressCart = NonNullable<FreeShippingProgressData['cart']>;\ntype FreeShippingProgressState = NonNullable<FreeShippingProgressCart['freeShippingProgress']>;\n\nfunction previewCart(\n {\n threshold,\n remaining,\n qualified,\n itemsTotal,\n }: Pick<FreeShippingProgressRootProps, 'threshold' | 'remaining' | 'qualified' | 'itemsTotal'>,\n currency: string,\n): FreeShippingProgressCart | null {\n if (qualified === undefined && threshold === undefined && remaining === undefined && itemsTotal === undefined) {\n return null;\n }\n return {\n id: 'preview',\n totalizers:\n itemsTotal === undefined ? [] : [{ id: 'Items', value: { amount: itemsTotal, currencyCode: currency } }],\n freeShippingProgress: {\n threshold: threshold == null ? null : { amount: threshold, currencyCode: currency },\n remaining: { amount: remaining ?? threshold ?? 0, currencyCode: currency },\n qualified: qualified ?? false,\n },\n };\n}\n\n// The server measures the Items totalizer, never the grand total (shipping and discounts do not count).\nfunction itemsSubtotal(cart: FreeShippingProgressCart): number | null {\n const itemsAmount = cart.totalizers?.find((totalizer) => totalizer.id === 'Items')?.value.amount;\n return isFiniteAmount(itemsAmount) ? Number(itemsAmount) : null;\n}\n\n// Usable threshold: present, finite, positive. Null/NaN/zero → no fill, no remaining.\nfunction usableThreshold(threshold: MoneyValue | null): number | null {\n if (threshold == null) return null;\n const parsed = Number(threshold.amount);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : null;\n}\n\nfunction fillRatio(isQualified: boolean, thresholdAmount: number | null, covered: number): number {\n if (isQualified) return 1;\n if (thresholdAmount === null) return 0;\n return clamp01(covered / thresholdAmount);\n}\n\nfunction computeProgress(\n fsp: FreeShippingProgressState,\n items: number | null,\n thresholdAmount: number | null,\n): FreeShippingProgressContextValue {\n if (items === null) {\n // No usable Items amount: show the server's own answer rather than guess.\n const isQualified = fsp.qualified;\n const liveRemaining =\n !isQualified && isFiniteAmount(fsp.remaining.amount) ? Math.max(Number(fsp.remaining.amount), 0) : 0;\n const fill = fillRatio(isQualified, thresholdAmount, (thresholdAmount ?? 0) - liveRemaining);\n return { isQualified, fill, liveRemaining };\n }\n\n const isQualified = fsp.qualified || (thresholdAmount !== null && items >= thresholdAmount);\n const liveRemaining = isQualified || thresholdAmount === null ? 0 : Math.max(thresholdAmount - items, 0);\n return { isQualified, fill: fillRatio(isQualified, thresholdAmount, items), liveRemaining };\n}\n\n// ---------------------------------------------------------------------------\n// Definitions\n// ---------------------------------------------------------------------------\n\nexport const FreeShippingProgressRootDefinition = defineComponent<FreeShippingProgressRootProps>({\n name: 'FreeShippingProgressRoot',\n importPath: '@vtex/faststore/components',\n component: FreeShippingProgressRoot,\n fragment,\n fetchStrategy: 'reactive',\n editor: { label: 'Free Shipping Progress', category: 'commerce' },\n schema: {},\n guideline:\n 'Free-shipping progress bar for the top of a cart/mini-cart drawer: shows how much more to spend for free shipping and flips to an earned state when met. Renders nothing until a destination and an eligible promotion exist (self-hides on null). See free-shipping-progress.md.',\n});\n\nexport const FreeShippingProgressBarDefinition = defineComponent<FreeShippingProgressBarProps>({\n name: 'FreeShippingProgressBar',\n importPath: '@vtex/faststore/components',\n component: FreeShippingProgressBar,\n editor: { label: 'Free Shipping Progress Bar', category: 'commerce' },\n schema: {},\n guideline:\n 'Meter bar that fills toward the free-shipping goal, full when earned. Must be inside FreeShippingProgressRoot. See free-shipping-progress.md.',\n});\n\nexport const FreeShippingProgressMessageDefinition = defineComponent<FreeShippingProgressMessageProps>({\n name: 'FreeShippingProgressMessage',\n importPath: '@vtex/faststore/components',\n component: FreeShippingProgressMessage,\n editor: { label: 'Free Shipping Progress Message', category: 'commerce' },\n schema: {\n label: { type: 'string', default: 'faltam {value} para frete grátis', label: 'Below-threshold Label' },\n qualifiedLabel: { type: 'string', default: 'você ganhou frete grátis!', label: 'Qualified Label' },\n },\n guideline:\n 'Below-threshold vs earned copy, front-formatted from the active storefront context. Must be inside FreeShippingProgressRoot. See free-shipping-progress.md.',\n});\n\n// ---------------------------------------------------------------------------\n// Implementations\n// ---------------------------------------------------------------------------\n\nexport function FreeShippingProgressRoot({\n threshold,\n remaining,\n qualified,\n itemsTotal,\n $data: $dataProp,\n className,\n children,\n ...props\n}: FreeShippingProgressRootProps) {\n // Only the synthesized preview cart below needs it; the leaves read the context where they format.\n const { currency } = useStorefrontContext();\n const $data = useDataOverride($dataProp);\n\n // Story / presentational overrides synthesize the field when no live cart is present.\n const cart = $data ?? previewCart({ threshold, remaining, qualified, itemsTotal }, currency);\n\n const fsp = cart?.freeShippingProgress;\n if (!cart || fsp == null) return null;\n\n const { isQualified, fill, liveRemaining } = computeProgress(\n fsp,\n itemsSubtotal(cart),\n usableThreshold(fsp.threshold),\n );\n\n const value: FreeShippingProgressContextValue = { isQualified, fill, liveRemaining };\n\n return (\n <FreeShippingProgressContext value={value}>\n <div {...props} className={className} data-fs-free-shipping-progress-root=\"\">\n {children}\n </div>\n </FreeShippingProgressContext>\n );\n}\n\nexport function FreeShippingProgressBar({ className, ...props }: FreeShippingProgressBarProps) {\n const { fill, isQualified, liveRemaining } = useFreeShippingProgress();\n const { locale, currency } = useStorefrontContext();\n const ariaValueText = isQualified\n ? 'frete grátis conquistado'\n : `${formatCurrency(liveRemaining, locale, currency)} restantes para frete grátis`;\n\n return (\n <Meter.Root\n {...props}\n value={Math.round(fill * 100)}\n min={0}\n max={100}\n getAriaValueText={() => ariaValueText}\n className={className}\n data-fs-free-shipping-progress-bar=\"\"\n >\n <Meter.Track>\n <Meter.Indicator />\n </Meter.Track>\n </Meter.Root>\n );\n}\n\nexport function FreeShippingProgressMessage({\n label = 'faltam {value} para frete grátis',\n qualifiedLabel = 'você ganhou frete grátis!',\n className,\n children,\n ...props\n}: FreeShippingProgressMessageProps) {\n const { isQualified, liveRemaining } = useFreeShippingProgress();\n const { locale, currency } = useStorefrontContext();\n const text = isQualified ? qualifiedLabel : label.replace('{value}', formatCurrency(liveRemaining, locale, currency));\n\n return (\n <div {...props} className={className} data-fs-free-shipping-progress-message=\"\">\n {children ?? text}\n </div>\n );\n}\n\nexport const FreeShippingProgress = {\n Root: FreeShippingProgressRoot,\n Bar: FreeShippingProgressBar,\n Message: FreeShippingProgressMessage,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"free-shipping-progress.js","names":[],"sources":["../../../src/matter/free-shipping-progress/free-shipping-progress.tsx"],"sourcesContent":["'use client';\n\nimport { type ContentValue, defineComponent, defineContentType, type MessageLocaleProp } from '@vtex/fs-core';\nimport { type ComponentPropsWithRef, createContext, useContext } from 'react';\nimport { Meter } from '../../particles/meter/meter.js';\nimport { useStorefrontContext } from '../../sdk/context/storefront-context.js';\nimport { useDataOverride } from '../../sdk/data/data-override-context.js';\nimport { useMessageFormatter } from '../../sdk/i18n/use-message-formatter.js';\nimport { isFiniteAmount } from '../cart/cart.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ntype MoneyValue = { amount: number | string; currencyCode: string };\n\ntype FreeShippingProgressData = {\n cart?: {\n id: string;\n totalizers?: { id: string; value: MoneyValue }[] | null;\n freeShippingProgress?: {\n threshold: MoneyValue | null;\n remaining: MoneyValue;\n qualified: boolean;\n } | null;\n } | null;\n};\n\ntype FreeShippingProgressContextValue = {\n isQualified: boolean;\n fill: number;\n liveRemaining: number;\n};\n\nexport type FreeShippingProgressRootProps = ComponentPropsWithRef<'div'> & {\n threshold?: number;\n remaining?: number;\n qualified?: boolean;\n itemsTotal?: number;\n $data?: FreeShippingProgressData['cart'] | null;\n};\n\nexport const FreeShippingProgressMessageContent = defineContentType({\n id: 'free-shipping-progress-message',\n title: 'Free Shipping Progress Message',\n description: 'The below-threshold and earned free-shipping messages.',\n schema: {\n type: 'object',\n additionalProperties: false,\n properties: {\n label: {\n type: 'string',\n title: 'Below-threshold label',\n description: 'Shown while the cart is below the threshold; value is the formatted amount still missing.',\n format: 'icu-message',\n messageSource: '{value} away from free shipping',\n messageArguments: { type: 'object', properties: { value: { type: 'string' } } },\n messageExample: { value: '$25.00' },\n },\n qualifiedLabel: {\n type: 'string',\n title: 'Qualified label',\n format: 'icu-message',\n messageSource: 'You got free shipping!',\n },\n },\n },\n});\n\nexport const FreeShippingProgressBarContent = defineContentType({\n id: 'free-shipping-progress-bar',\n title: 'Free Shipping Progress Bar',\n description: 'The value text a screen reader announces for the progress bar.',\n schema: {\n type: 'object',\n additionalProperties: false,\n properties: {\n valueText: {\n type: 'string',\n title: 'Below-threshold value text',\n description: 'Announced while the cart is below the threshold; value is the formatted amount still missing.',\n format: 'icu-message',\n messageSource: '{value} left for free shipping',\n messageArguments: { type: 'object', properties: { value: { type: 'string' } } },\n messageExample: { value: '$25.00' },\n },\n qualifiedValueText: {\n type: 'string',\n title: 'Qualified value text',\n format: 'icu-message',\n messageSource: 'Free shipping earned',\n },\n },\n },\n});\n\nexport type FreeShippingProgressBarProps = ComponentPropsWithRef<'div'> &\n MessageLocaleProp & {\n $content?: ContentValue<typeof FreeShippingProgressBarContent>;\n };\nexport type FreeShippingProgressMessageProps = ComponentPropsWithRef<'div'> &\n MessageLocaleProp & {\n $content?: ContentValue<typeof FreeShippingProgressMessageContent>;\n };\n\n// ---------------------------------------------------------------------------\n// GraphQL Fragment — narrow cart slice (Items totalizer + freeShippingProgress)\n// ---------------------------------------------------------------------------\n\nconst fragment = /* GraphQL */ `\n fragment FreeShippingProgressData on Query {\n cart {\n id\n totalizers {\n id\n value {\n amount\n currencyCode\n }\n }\n freeShippingProgress {\n threshold {\n amount\n currencyCode\n }\n remaining {\n amount\n currencyCode\n }\n qualified\n }\n }\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Context\n// ---------------------------------------------------------------------------\n\nconst FSP_CONTEXT_UNSET = Symbol('FreeShippingProgressContextUnset');\n\nconst FreeShippingProgressContext = createContext<FreeShippingProgressContextValue | typeof FSP_CONTEXT_UNSET>(\n FSP_CONTEXT_UNSET,\n);\n\nfunction useFreeShippingProgress(): FreeShippingProgressContextValue {\n const ctx = useContext(FreeShippingProgressContext);\n if (ctx === FSP_CONTEXT_UNSET) {\n throw new Error('useFreeShippingProgress() must be used inside a <FreeShippingProgressRoot> subtree.');\n }\n return ctx;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction formatCurrency(value: number, locale: string, currency: string): string {\n return new Intl.NumberFormat(locale, { style: 'currency', currency }).format(value);\n}\n\nfunction clamp01(value: number): number {\n return Math.min(Math.max(value, 0), 1);\n}\n\ntype FreeShippingProgressCart = NonNullable<FreeShippingProgressData['cart']>;\ntype FreeShippingProgressState = NonNullable<FreeShippingProgressCart['freeShippingProgress']>;\n\nfunction previewCart(\n {\n threshold,\n remaining,\n qualified,\n itemsTotal,\n }: Pick<FreeShippingProgressRootProps, 'threshold' | 'remaining' | 'qualified' | 'itemsTotal'>,\n currency: string,\n): FreeShippingProgressCart | null {\n if (qualified === undefined && threshold === undefined && remaining === undefined && itemsTotal === undefined) {\n return null;\n }\n return {\n id: 'preview',\n totalizers:\n itemsTotal === undefined ? [] : [{ id: 'Items', value: { amount: itemsTotal, currencyCode: currency } }],\n freeShippingProgress: {\n threshold: threshold == null ? null : { amount: threshold, currencyCode: currency },\n remaining: { amount: remaining ?? threshold ?? 0, currencyCode: currency },\n qualified: qualified ?? false,\n },\n };\n}\n\n// The server measures the Items totalizer, never the grand total (shipping and discounts do not count).\nfunction itemsSubtotal(cart: FreeShippingProgressCart): number | null {\n const itemsAmount = cart.totalizers?.find((totalizer) => totalizer.id === 'Items')?.value.amount;\n return isFiniteAmount(itemsAmount) ? Number(itemsAmount) : null;\n}\n\n// Usable threshold: present, finite, positive. Null/NaN/zero → no fill, no remaining.\nfunction usableThreshold(threshold: MoneyValue | null): number | null {\n if (threshold == null) return null;\n const parsed = Number(threshold.amount);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : null;\n}\n\nfunction fillRatio(isQualified: boolean, thresholdAmount: number | null, covered: number): number {\n if (isQualified) return 1;\n if (thresholdAmount === null) return 0;\n return clamp01(covered / thresholdAmount);\n}\n\nfunction computeProgress(\n fsp: FreeShippingProgressState,\n items: number | null,\n thresholdAmount: number | null,\n): FreeShippingProgressContextValue {\n if (items === null) {\n // No usable Items amount: show the server's own answer rather than guess.\n const isQualified = fsp.qualified;\n const liveRemaining =\n !isQualified && isFiniteAmount(fsp.remaining.amount) ? Math.max(Number(fsp.remaining.amount), 0) : 0;\n const fill = fillRatio(isQualified, thresholdAmount, (thresholdAmount ?? 0) - liveRemaining);\n return { isQualified, fill, liveRemaining };\n }\n\n const isQualified = fsp.qualified || (thresholdAmount !== null && items >= thresholdAmount);\n const liveRemaining = isQualified || thresholdAmount === null ? 0 : Math.max(thresholdAmount - items, 0);\n return { isQualified, fill: fillRatio(isQualified, thresholdAmount, items), liveRemaining };\n}\n\n// ---------------------------------------------------------------------------\n// Definitions\n// ---------------------------------------------------------------------------\n\nexport const FreeShippingProgressRootDefinition = defineComponent<FreeShippingProgressRootProps>({\n name: 'FreeShippingProgressRoot',\n importPath: '@vtex/faststore/components',\n component: FreeShippingProgressRoot,\n fragment,\n fetchStrategy: 'reactive',\n editor: { label: 'Free Shipping Progress', category: 'commerce' },\n schema: {},\n guideline:\n 'Free-shipping progress bar for the top of a cart/mini-cart drawer: shows how much more to spend for free shipping and flips to an earned state when met. Renders nothing until a destination and an eligible promotion exist (self-hides on null). See free-shipping-progress.md.',\n});\n\nexport const FreeShippingProgressBarDefinition = defineComponent<FreeShippingProgressBarProps>({\n name: 'FreeShippingProgressBar',\n importPath: '@vtex/faststore/components',\n component: FreeShippingProgressBar,\n content: FreeShippingProgressBarContent,\n editor: { label: 'Free Shipping Progress Bar', category: 'commerce' },\n schema: {},\n guideline:\n 'Meter bar that fills toward the free-shipping goal, full when earned; screen readers announce the $content fields valueText ({value} is the formatted remaining amount) and qualifiedValueText. Must be inside FreeShippingProgressRoot. See free-shipping-progress.md.',\n});\n\nexport const FreeShippingProgressMessageDefinition = defineComponent<FreeShippingProgressMessageProps>({\n name: 'FreeShippingProgressMessage',\n importPath: '@vtex/faststore/components',\n component: FreeShippingProgressMessage,\n content: FreeShippingProgressMessageContent,\n editor: { label: 'Free Shipping Progress Message', category: 'commerce' },\n schema: {},\n guideline:\n 'Below-threshold vs earned copy from the $content fields label ({value} is the formatted remaining amount) and qualifiedLabel; children replace both. Must be inside FreeShippingProgressRoot. See free-shipping-progress.md.',\n});\n\n// ---------------------------------------------------------------------------\n// Implementations\n// ---------------------------------------------------------------------------\n\nexport function FreeShippingProgressRoot({\n threshold,\n remaining,\n qualified,\n itemsTotal,\n $data: $dataProp,\n className,\n children,\n ...props\n}: FreeShippingProgressRootProps) {\n // Only the synthesized preview cart below needs it; the leaves read the context where they format.\n const { currency } = useStorefrontContext();\n const $data = useDataOverride($dataProp);\n\n // Story / presentational overrides synthesize the field when no live cart is present.\n const cart = $data ?? previewCart({ threshold, remaining, qualified, itemsTotal }, currency);\n\n const fsp = cart?.freeShippingProgress;\n if (!cart || fsp == null) return null;\n\n const { isQualified, fill, liveRemaining } = computeProgress(\n fsp,\n itemsSubtotal(cart),\n usableThreshold(fsp.threshold),\n );\n\n const value: FreeShippingProgressContextValue = { isQualified, fill, liveRemaining };\n\n return (\n <FreeShippingProgressContext value={value}>\n <div {...props} className={className} data-fs-free-shipping-progress-root=\"\">\n {children}\n </div>\n </FreeShippingProgressContext>\n );\n}\n\nexport function FreeShippingProgressBar({ $content, $locale, className, ...props }: FreeShippingProgressBarProps) {\n const { fill, isQualified, liveRemaining } = useFreeShippingProgress();\n const { locale, currency } = useStorefrontContext();\n const { format } = useMessageFormatter(FreeShippingProgressBarContent, $content);\n const ariaValueText = isQualified\n ? format('qualifiedValueText')\n : format('valueText', { value: formatCurrency(liveRemaining, locale, currency) });\n\n return (\n <Meter.Root\n aria-label=\"Progresso para frete grátis\"\n {...props}\n value={Math.round(fill * 100)}\n min={0}\n max={100}\n getAriaValueText={() => ariaValueText}\n className={className}\n data-fs-free-shipping-progress-bar=\"\"\n >\n <Meter.Track>\n <Meter.Indicator />\n </Meter.Track>\n </Meter.Root>\n );\n}\n\nexport function FreeShippingProgressMessage({\n $content,\n $locale,\n className,\n children,\n ...props\n}: FreeShippingProgressMessageProps) {\n const { isQualified, liveRemaining } = useFreeShippingProgress();\n const { locale, currency } = useStorefrontContext();\n const { format } = useMessageFormatter(FreeShippingProgressMessageContent, $content);\n\n function message(): string {\n if (isQualified) return format('qualifiedLabel');\n return format('label', { value: formatCurrency(liveRemaining, locale, currency) });\n }\n\n return (\n <div {...props} className={className} data-fs-free-shipping-progress-message=\"\">\n {children ?? message()}\n </div>\n );\n}\n\nexport const FreeShippingProgress = {\n Root: FreeShippingProgressRoot,\n Bar: FreeShippingProgressBar,\n Message: FreeShippingProgressMessage,\n};\n"],"mappings":"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"}