@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
@@ -0,0 +1,176 @@
1
+ # SignInDisclosure (Root + Trigger + ModalPanel)
2
+
3
+ **Category:** identity
4
+ **Purpose:** Opens the sign-in surface in place, as a modal, and closes it by itself when the shopper signs in. `SignInDisclosureRoot` owns whether the modal is showing and shares it as the `sign-in-disclosure` context; it renders no element of its own. `SignInDisclosureTrigger` is the login button — any number may be composed, and every one opens the same panel. `SignInModalPanel` is the modal: a labelled dialog with a close control, holding the sign-in parts as its children. None of the three reads data; the account configuration reaches them through `SignInRoot`.
5
+
6
+ ---
7
+
8
+ ## Visual cues (how to identify in an image)
9
+
10
+ - A **login button** ("Entrar", "Sign in") in a header, or beside the step that needs an account, that does not navigate away — this is `SignInDisclosureTrigger`. The same button may appear in more than one place.
11
+ - A **centered card over a dimmed page**, titled "Entrar" or similar, with a close control ("Fechar", an X) in its top corner and the email field and a code or password step inside — this is `SignInModalPanel` open.
12
+ - A **grey rounded bar** where the login button will be, shown briefly while the account configuration loads — the trigger's skeleton.
13
+ - **No login button at all** for a signed-in shopper, and none in a store whose account enables no sign-in method.
14
+
15
+ ---
16
+
17
+ ## When to use
18
+
19
+ - A login button that must be available from more than one point of a page or layout, opening sign-in over the current step instead of navigating to `/login`.
20
+ - A sign-in surface whose modal should return the shopper to the step they were on, and close without a click when the session becomes signed in.
21
+
22
+ ## When NOT to use
23
+
24
+ - A plain link to the `/login` page → `AccountEntryPoint`, which adapts to the session and navigates.
25
+ - A modal for anything other than sign-in → compose the `Dialog` particles. A merchant-composed `DialogRoot` cannot be told to close when the shopper signs in (see Common mistakes).
26
+ - A page with no `SignInRoot` and no `SessionRoot` above → `SignInDisclosureRoot` throws until both are present.
27
+
28
+ ---
29
+
30
+ ## Composition
31
+
32
+ ```
33
+ SessionRoot (required ancestor of SignInRoot)
34
+ └── SignInRoot (required ancestor: reads the account's enabled methods once)
35
+ └── SignInDisclosureRoot (renders no element; owns the open state)
36
+ ├── SignInDisclosureTrigger (any number, anywhere below the Root)
37
+ ├── SignInDisclosureTrigger
38
+ └── SignInModalPanel (exactly one; portalled, kept mounted while closed)
39
+ ├── SignInEmailControl
40
+ ├── SignInMethodSwitch / SignInMethodOption
41
+ └── AccessCodeSignInRoot / SignInForm …
42
+ ```
43
+
44
+ Hosted in a layout, the Root wraps the header **and** the `Slot`: a page then composes a `SignInDisclosureTrigger` of its own and no root, and the layout's panel answers it.
45
+
46
+ `SignInDisclosureRoot` **must** have a `SignInRoot` ancestor — `useSignIn() must be used inside a <SignInRoot> subtree.` otherwise. `SignInDisclosureTrigger` and `SignInModalPanel` **must** be descendants of `SignInDisclosureRoot` — `useSignInDisclosure() must be used inside a <SignInDisclosureRoot> subtree.` otherwise (runtime guards, not compiler-checked beyond context ancestry).
47
+
48
+ ---
49
+
50
+ ## Props
51
+
52
+ ### `SignInDisclosureRoot`
53
+
54
+ | Prop | Type | Default | Notes |
55
+ |------|------|---------|-------|
56
+ | `children` | `ReactNode` | — | Always rendered, in every session state and for every account configuration. |
57
+
58
+ No schema props. It declares no fragment, no `fetchStrategy` and no `$data`.
59
+
60
+ ### `SignInDisclosureTrigger`
61
+
62
+ | Prop | Type | Default | Notes |
63
+ |------|------|---------|-------|
64
+ | `label` | string | — | The button's text. |
65
+
66
+ Extends `ComponentPropsWithRef<'button'>`. The rendered element is always a `<button type="button">`; a `type` passed in is overridden so the trigger never submits an enclosing form. A caller's `onClick` runs first and may call `preventDefault()` to keep the panel shut.
67
+
68
+ ### `SignInModalPanel`
69
+
70
+ | Prop | Type | Default | Notes |
71
+ |------|------|---------|-------|
72
+ | `title` | string | — | The dialog's accessible name, drawn in the header. Author it: without it the dialog has no name. |
73
+ | `closeLabel` | string | — | The close control's text and accessible name. |
74
+ | `signedInFocusLabel` | string | — | Written into the focus anchor when the session becomes signed in while the page is open, so a screen reader announces that the modal closed because sign-in succeeded. A shopper who was already signed in when the page loaded is told nothing. The anchor is clipped, so the text is never drawn. No default. |
75
+
76
+ Extends `ComponentPropsWithRef<'div'>`, spread onto the dialog element, except `hidden`, `tabIndex`, `aria-label` and `aria-labelledby`: the panel owns those (closed means `hidden`; the title names the dialog), so the type omits them and a value that gets past it is discarded. There is **no** `open`, `defaultOpen` or `onOpenChange`: whether the panel is showing is state, never a prop.
77
+
78
+ No prop in this family carries a default: copy is the merchant's own message, so no English fallback ships.
79
+
80
+ ---
81
+
82
+ ## Behavior
83
+
84
+ - **One panel, many triggers.** Each trigger sets the one open state; the panel needs no trigger at all (`useSignInDisclosure().setOpen(true)` opens it).
85
+ - **Resolved before enabled.** The trigger checks `useSignIn().resolved` before it reads a flag. While the account configuration has not arrived it draws a silent placeholder (`data-fs-sign-in-disclosure-trigger-skeleton`, `aria-hidden="true"`, no role, not focusable); once resolved with no method enabled it renders nothing.
86
+ - **Signed in renders no trigger.** For a `loggedIn` session the trigger renders nothing — no button and no placeholder. The panel stays in the document, closed.
87
+ - **The close is derived.** The published `open` is `localOpen && state !== 'loggedIn'`, so no committed render shows an open panel to a signed-in shopper. The panel closes the moment the session reaches `loggedIn`, with no event and no prop. `setOpen(true)` made while signed in does nothing, and a later sign-out does not reopen the panel.
88
+ - **Kept mounted.** The panel renders Base UI's `Dialog` with the portal kept mounted, so its children are mounted before the first open and survive every close: a shopper who steps out to read an emailed code returns to the same access-code step with the same token, and the email they typed. A typed password is the exception: `SignInForm` empties it, and its errors, when the panel closes, so a credential the shopper never submitted does not wait in the hidden subtree for the next person at the page. Closed, the dialog element carries `hidden`, which takes it out of the accessibility tree and the tab order.
89
+ - **Dismissal.** Escape, a press on the overlay and the close control each close it. Page scroll is locked and focus is trapped while it is open.
90
+ - **Focus.** Opening moves focus into the panel. A shopper-driven close returns focus to the trigger that opened it. A self-close removes that trigger, so focus goes to the panel's in-flow focus anchor (`role="status"`, `tabindex="-1"`, empty until the session changes while the page is open) instead of `document.body`, and the anchor then carries `signedInFocusLabel`. The anchor sits in the layout's flow, outside the panel, so the panel's `style` does not reach it: it ships clipped (still in the accessibility tree, never drawn).
91
+ - **No actions.** Nothing in this family dispatches a mutation. The session change that closes the panel is produced by the method components inside it.
92
+
93
+ ### Hooks
94
+
95
+ | Hook | Notes |
96
+ |------|-------|
97
+ | `useSignInDisclosure()` | `{ open, setOpen }`. Throws outside a `SignInDisclosureRoot`. |
98
+
99
+ ---
100
+
101
+ ## `data-fs-*` hooks
102
+
103
+ | Attribute | Element | Meaning |
104
+ |---|---|---|
105
+ | `data-fs-sign-in-disclosure-trigger` | trigger button | The login button is offered |
106
+ | `data-fs-sign-in-disclosure-trigger-skeleton` | trigger placeholder | The account configuration has not arrived |
107
+ | `data-fs-sign-in-state` | trigger and placeholder | `ready` or `loading` |
108
+ | `data-fs-sign-in-modal-panel` | dialog element | The panel. Base UI adds `data-open` or `data-closed`; closed also carries `hidden` |
109
+ | `data-fs-sign-in-modal-backdrop` | overlay | The overlay behind the panel |
110
+ | `data-fs-sign-in-modal-header` | header row | Holds the title and the close control |
111
+ | `data-fs-sign-in-modal-title` | heading | The dialog's accessible name |
112
+ | `data-fs-sign-in-modal-close` | close button | Closes the panel |
113
+ | `data-fs-sign-in-modal-focus-anchor` | in-flow div | Where focus lands after a self-close; clipped, empty until the shopper signs in while the page is open |
114
+
115
+ The panel carries no `data-fs-dialog-*` hooks: it renders Base UI's `Dialog` directly and styles through its own hooks. Position the panel through the `style` array on `SignInModalPanel` (it lands on the dialog element); the overlay is a separate portalled sibling.
116
+
117
+ ---
118
+
119
+ ## Canonical schema example
120
+
121
+ A layout hosting the surface, with a header trigger and the panel; a page adds its own trigger and no root:
122
+
123
+ ```json
124
+ {
125
+ "type": "SessionRoot",
126
+ "children": [
127
+ {
128
+ "type": "SignInRoot",
129
+ "children": [
130
+ {
131
+ "type": "SignInDisclosureRoot",
132
+ "children": [
133
+ { "type": "Container", "children": [
134
+ { "type": "SignInDisclosureTrigger", "props": { "label": "entrar" } },
135
+ { "type": "Slot" }
136
+ ] },
137
+ {
138
+ "type": "SignInModalPanel",
139
+ "props": { "title": "Entrar", "closeLabel": "Fechar", "signedInFocusLabel": "Você entrou na sua conta." },
140
+ "children": [
141
+ { "type": "SignInEmailControl", "props": { "label": "e-mail" } },
142
+ { "type": "AccessCodeSignInRoot", "children": [
143
+ { "type": "AccessCodeRequestControl", "props": { "label": "solicitar código de acesso" } },
144
+ { "type": "AccessCodeValidateControl", "props": { "label": "código recebido por e-mail", "submitLabel": "entrar" } }
145
+ ] }
146
+ ]
147
+ }
148
+ ]
149
+ }
150
+ ]
151
+ }
152
+ ]
153
+ }
154
+ ```
155
+
156
+ ---
157
+
158
+ ## Common mistakes
159
+
160
+ - **Composing a bare `DialogRoot` around the sign-in parts.** A merchant-composed `DialogRoot` cannot close itself: schema composition wires no callbacks, so after a successful sign-in it sits open over a panel whose every part has already rendered nothing. Use `SignInModalPanel`, which closes on the session change.
161
+ - **Omitting `title`.** The dialog is named by its title and by nothing else; without it the dialog has no accessible name.
162
+ - **Omitting `closeLabel`.** No default ships, so the close control then has no accessible name. Escape and an overlay press still dismiss the panel, but a screen-reader shopper meets an unnamed button inside a focus-trapped dialog. Author it.
163
+ - **Passing `hidden`, `tabIndex`, `aria-label` or `aria-labelledby` to the panel.** They are discarded: the panel keeps itself hidden while closed and named by its title.
164
+ - **Composing a second `SignInModalPanel` under one Root.** Both would open. Context ancestry is validated, arity is not.
165
+ - **Composing a trigger or the panel outside `SignInDisclosureRoot`.** Both throw, naming the Root to add.
166
+ - **Expecting an `open` prop.** There is none, by design: the open state is not authorable and cannot be faked.
167
+
168
+ ---
169
+
170
+ ## Related
171
+
172
+ - [[sign-in]] — provides the required `SignInRoot` ancestor; the trigger gates on its `resolved` and `anyMethodEnabled`.
173
+ - [[session]] — provides the `loggedIn` state that closes the panel and removes the triggers.
174
+ - [[access-code-sign-in]] — the access-code method family, composed inside the panel.
175
+ - [[sign-in-form]] — the password method family, composed inside the panel.
176
+ - [[account-entry-point]] — the header link that navigates to `/login`, which this family does not replace.
@@ -1,28 +1,29 @@
1
1
  # SignInForm
2
2
 
3
3
  **Category:** identity
4
- **Purpose:** Composes `EmailField` + `PasswordField` under one submit and dispatches `$actions.session.loginWithPassword({ email, password })`. It pre-fills the email from `clientProfile.email`, blocks the dispatch on client-side email/password validation, maps the resolved `userErrors` to one inline form-level message, and self-gates to `null` once `useSession()` reports `loggedIn`. It must sit inside a `SessionRoot`.
4
+ **Purpose:** The password method of the sign-in surface. It sits under `SignInRoot`, which reads the account's enabled methods once and owns the one email draft every method shares; `SignInEmailControl` is the email field. `SignInForm` is a password field and a submit that dispatches `$actions.session.loginWithPassword({ email, password })` with that shared draft. It renders nothing until the account configuration has arrived, when the account disables passwords, while another sign-in method is the active one, and once `useSession()` reports `loggedIn`. It renders no email field of its own.
5
5
 
6
6
  ---
7
7
 
8
8
  ## Visual cues (how to identify in an image)
9
9
 
10
- - A **combined email + password login form** inside a checkout User Identity / sign-in step, with a single submit button (e.g. "Sign In").
11
- - Distinct from `EmailIdentificationControl` (email-only, no password, no submit button) — `SignInForm` always has both fields and one submit.
12
- - A form-level error banner (`role="alert"`) below the fields, separate from any per-field inline error — that banner is this component's own `data-fs-sign-in-form-error` region, not a page-level failure gate.
10
+ - A **password input with a show/hide toggle and one submit button** (e.g. "Sign In"), sitting under the sign-in step's email field — the email field is `SignInEmailControl`, not part of this component.
11
+ - Distinct from `EmailIdentificationControl` (email-only, no password, no submit button) and from `AccessCodeSignIn.*` (an emailed one-time code, no password).
12
+ - A rejected password shows its message **under the password input**; any other failure shows a form-level banner (`role="alert"`) below it — that banner is this component's own `data-fs-sign-in-form-error` region, not a page-level failure gate.
13
13
 
14
- Use `SignInForm` (not a bare `EmailField` + `PasswordField` pair) whenever the shopper must authenticate with an existing password.
14
+ Use `SignInForm` whenever the shopper must authenticate with an existing password.
15
15
 
16
16
  ---
17
17
 
18
18
  ## When to use
19
19
 
20
- - The password sign-in step of the checkout User Identity flow, for a shopper who is `anonymous` or `identified` but not yet `loggedIn`.
21
- - Anywhere a combined email+password credential submit is needed that writes through the `session` action namespace.
20
+ - The password sign-in step of the checkout User Identity flow, for a shopper who is `anonymous` or `identified` but not yet `loggedIn`, as one of the sign-in methods composed under a `SignInRoot`.
21
+ - The signed-out branch of a page that must follow the account's configuration (for example My Account), composed under a `SignInRoot` like any other method.
22
22
 
23
23
  ## When NOT to use
24
24
 
25
- - Passwordless / access-code (two-step) sign-in → a separate component (FSPG-872), not a variant of this one.
25
+ - Passwordless / access-code (two-step) sign-in → `AccessCodeSignIn.*`, a separate family composed beside this one under the same `SignInRoot`.
26
+ - Rendering outside a `SignInRoot` → there is no standalone use; the page fails the build (see Composition).
26
27
  - Email-only pre-fill/identification with no password → use `EmailIdentificationControl`.
27
28
  - Logged-in summary, sign-out, or profile editing → out of scope (FSPG-867); `SignInForm` only self-gates to `null` once logged in, it renders no logged-in UI.
28
29
  - Password recovery ("Forgot password?") → out of scope for this component; deferred.
@@ -32,15 +33,18 @@ Use `SignInForm` (not a bare `EmailField` + `PasswordField` pair) whenever the s
32
33
  ## Composition
33
34
 
34
35
  ```
35
- SessionRoot (provides the session tri-state; required ancestor)
36
- └── SignInForm (data-fs-sign-in-form)
37
- ├── EmailField (pre-filled from clientProfile.email; own inline format error)
38
- ├── PasswordField (presence-only validation owned by SignInForm)
39
- ├── form-level error (data-fs-sign-in-form-error, role="alert")
40
- └── Button (submit) (data-fs-sign-in-form-submit)
36
+ SessionRoot (provides the session tri-state; required ancestor of SignInRoot)
37
+ └── SignInRoot (reads the account once; owns the shared email draft and the active method; required ancestor)
38
+ ├── SignInEmailControl (the one email field, for every method)
39
+ └── SignInForm (data-fs-sign-in-form; renders only while password is the active, enabled, resolved method)
40
+ ├── PasswordField (presence check owned by SignInForm; carries INVALID_CREDENTIALS)
41
+ ├── form-level error (data-fs-sign-in-form-error, role="alert")
42
+ └── Button (submit) (data-fs-sign-in-form-submit)
41
43
  ```
42
44
 
43
- `SignInForm` **must** have a `SessionRoot` ancestor — `useSession()` throws otherwise.
45
+ `SignInForm` **must** be a descendant of `SignInRoot`, which itself needs a `SessionRoot` ancestor. A schema that composes `SignInForm` without a `SignInRoot` ancestor fails the **build**: `sukima generate` rejects it with the diagnostic code `context-constraint-violation`, because the matter `requiresContext: 'sign-in'`. Rendering it directly in TSX (a story or a test) with no `SignInRoot` throws `useSignIn() must be used inside a <SignInRoot> subtree.`
46
+
47
+ `SignInEmailControl` sits **above** `SignInForm`, as its sibling, so the email stays anchored while the method below it swaps. The compiler does not require it, but a page that omits it has no email input anywhere and the submit stays disabled. To offer another method beside this one, compose `SignInMethodSwitch` or `SignInMethodOption` under the same Root; see [[sign-in]] and [[access-code-sign-in]].
44
48
 
45
49
  ---
46
50
 
@@ -48,33 +52,44 @@ SessionRoot (provides the session tri-state; required ancestor)
48
52
 
49
53
  | Prop | Type | Default | Notes |
50
54
  |------|------|---------|-------|
51
- | `emailLabel` / `emailPlaceholder` | string | `'Email'` / `'you@example.com'` | Passed to `EmailField`. |
52
- | `passwordLabel` / `passwordPlaceholder` | string | `'Password'` / `''` | Passed to `PasswordField`. |
53
- | `showPasswordLabel` / `hidePasswordLabel` | string | `'Show password'` / `'Hide password'` | Passed to `PasswordField`'s reveal toggle. |
54
- | `submitLabel` | string | `'Sign In'` | Submit button text. |
55
- | `invalidEmailMessage` | string | `'Enter a valid email address.'` | Shown on `EmailField` when the pre-submit format check fails. |
56
- | `passwordRequiredMessage` | string | `'Enter your password.'` | Shown on `PasswordField` when submitted empty. |
57
- | `invalidCredentialsMessage` | string | `'Incorrect email or password. Please try again.'` | Form-level error for `INVALID_CREDENTIALS`. |
58
- | `blockedMessage` | string | `'This account has been blocked. Please contact support.'` | Form-level error for `BLOCKED`. |
59
- | `networkErrorMessage` | string | `'Unable to complete the request. Please try again.'` | Form-level error for the synthetic `NETWORK_ERROR`. |
60
- | `genericErrorMessage` | string | `'Unable to sign in. Please try again.'` | Fallback for any other/unrecognized `SessionErrorCode`. |
61
- | `$data` | `{ email?: string \| null } \| null` | injected | `clientProfile` slice from the reactive runtime. Not authored in schema. |
55
+ | `passwordPlaceholder` | string | `''` | Passed to `PasswordField`. |
56
+ | `$content` | `ContentValue<typeof SignInFormContent>` | — | The labels and error messages below. |
62
57
  | `$actions` | injected | — | Carries `session.loginWithPassword` (compiler-injected). |
63
58
 
64
- **Data:** declares a colocated `fragment SignInFormData on Query { clientProfile { __typename id email } }` with `fetchStrategy: 'reactive'` — the minimal slice this matter owns (only `email`, for pre-fill).
59
+ Content type `sign-in-form`. Every field is a message with no arguments; an unauthored one renders empty and logs `message.missing`.
60
+
61
+ | Content field | Source (en) | Notes |
62
+ |---|---|---|
63
+ | `passwordLabel` | Password | `PasswordField` label. |
64
+ | `showPasswordLabel` / `hidePasswordLabel` | Show password / Hide password | `PasswordField`'s reveal toggle; `SignInForm` formats them and passes the strings down. |
65
+ | `submitLabel` | Sign In | Submit button text. |
66
+ | `passwordRequiredMessage` | Enter your password. | Shown on `PasswordField` when submitted empty. |
67
+ | `invalidCredentialsMessage` | Incorrect email or password. Please try again. | Shown on `PasswordField` for `INVALID_CREDENTIALS`. Names neither half, because the platform returns the same code for a wrong password and an unknown account. |
68
+ | `blockedMessage` | Access to this account is temporarily blocked. Please try again later. | Form-level error for `BLOCKED`. |
69
+ | `networkErrorMessage` | Unable to complete the request. Please try again. | Form-level error for the synthetic `NETWORK_ERROR`. |
70
+ | `genericErrorMessage` | Unable to sign in. Please try again. | Form-level fallback for any other/unrecognized `SessionErrorCode`. |
71
+
72
+ The email's label, placeholder and invalid-format message are `SignInEmailControl`'s props, not this component's. The component renders no email field.
73
+
74
+ **Data:** none. The matter declares **no fragment** and no `fetchStrategy`, and takes no data prop: it reads the `sign-in` context through `useSignIn()` (`email`, `method`, `passwordEnabled`, `resolved`) and the session tri-state through `useSession()`. It never reads which methods the account enables itself — `SignInRoot` is the one reader.
75
+
76
+ **Write:** declares `actions: { session: ['loginWithPassword'] }`. The write is **pessimistic/async** — it awaits the resolved `userErrors` before doing anything. While in flight, the password input and submit button are disabled and the root carries `data-fs-sign-in-form-pending`, so a checkout-CTA guard can block on it the same way it does for `EmailIdentificationControl`. A second submit that arrives while one is in flight is ignored, even in the same event batch. The shared email input is not disabled.
65
77
 
66
- **Write:** declares `actions: { session: ['loginWithPassword'] }`. The write is **pessimistic/async** — it awaits the resolved `userErrors` before doing anything. While in flight, the fields and submit button are disabled and the root carries `data-fs-sign-in-form-pending`, so a checkout-CTA guard can block on it the same way it does for `EmailIdentificationControl`.
78
+ **Gate:** renders its form only when **all four** hold: `useSession().state !== 'loggedIn'`, and, from `useSignIn()`, `resolved`, `passwordEnabled` and `method === 'password'`. Otherwise it returns `null` rather than unmounting, so a half-typed password survives a method switch.
67
79
 
68
80
  ---
69
81
 
70
82
  ## Behavior
71
83
 
72
- - **Pre-fill:** the email field shows `clientProfile.email` (empty when unset) and remains editable; it re-syncs if the pre-fill resolves or changes later.
73
- - **Client-side validation:** an invalid email format or an empty password blocks the dispatch entirely — no network round trip, the offending field shows its own inline error.
74
- - **Happy path:** dispatches `$actions.session.loginWithPassword({ email, password })` exactly once; on `userErrors: []`, no local "logged in" flag is set — the next render reads the already-flipped `useSession().state` and self-gates to `null`.
75
- - **Login errors:** a non-empty `userErrors[0]` maps through `mapSessionErrorMessage` to one of `invalidCredentialsMessage` / `blockedMessage` / `networkErrorMessage` / `genericErrorMessage`, rendered in the single `data-fs-sign-in-form-error` region — structurally distinct from any ancestor `UNAUTHORIZED` gate.
76
- - **Retry:** after a failed attempt the password is cleared (credential hygiene) but the email is kept; a fresh submit clears the prior form-level error.
77
- - **Self-gating:** renders the form for `anonymous`/`identified`, returns `null` for `loggedIn` — derived from `useSession()` on every render, never stored locally.
84
+ - **Gating:** see the four conditions above. A store whose account disables passwords never shows the form, and neither does one whose configuration has not arrived yet; once it arrives the form appears. With both methods enabled the access code is the default, and the form appears when the shopper selects the password method.
85
+ - **Shared email:** the dispatch's `email` is the `SignInRoot` draft, read at submit time and trimmed. The submit is disabled while the draft is not a valid address, and while a dispatch is in flight.
86
+ - **Presence check:** submitting with an empty password blocks the dispatch and shows `passwordRequiredMessage` on the `PasswordField`; typing clears it.
87
+ - **Happy path:** dispatches `$actions.session.loginWithPassword({ email, password })` exactly once; on `userErrors: []`, no local "logged in" flag is set — the next render reads the already-flipped `useSession().state` and returns `null`.
88
+ - **Login errors:** the first `userErrors` entry maps through `mapSessionErrorField` to the message that words it. `INVALID_CREDENTIALS` renders as the `PasswordField`'s inline error (the field is marked invalid); `BLOCKED`, `NETWORK_ERROR` and any other code render in the single `data-fs-sign-in-form-error` region — structurally distinct from any ancestor `UNAUTHORIZED` gate.
89
+ - **Retry:** once a dispatch has been sent the password is cleared, accepted or rejected (credential hygiene), but the shared email is kept; a fresh submit clears the prior errors, and an edit made in `SignInEmailControl` reaches the next dispatch.
90
+ - **Credential pair:** the password input carries `autocomplete="current-password"` and `SignInEmailControl`'s input carries `autocomplete="username"` by default, so a browser that resolves the username hint document-wide saves and fills the address and the password as one credential. The pairing is **not** complete: `SignInRoot` renders no form element, so the email input is a sibling of `<form data-fs-sign-in-form>` rather than inside it, and a browser that scopes the username search to the form owner still saves the credential against no username. Closing that needs a `form=` association the components do not set yet. Overriding `autoComplete` on `SignInEmailControl` breaks what pairing there is.
91
+ - **Session change:** when the session reaches `loggedIn` the password and both error states are cleared, so a credential never outlives the session it was typed for.
92
+ - **Panel close:** inside a `SignInModalPanel`, closing the panel clears the password and both error states the same way. The panel keeps its children mounted, so without this an unsubmitted password would sit in the hidden subtree for the life of the page; the shared email stays. Outside a disclosure nothing closes, so nothing is cleared.
78
93
 
79
94
  ---
80
95
 
@@ -85,13 +100,25 @@ SessionRoot (provides the session tri-state; required ancestor)
85
100
  "type": "SessionRoot",
86
101
  "children": [
87
102
  {
88
- "type": "SignInForm",
89
- "props": {
90
- "emailLabel": "Email",
91
- "passwordLabel": "Password",
92
- "submitLabel": "Sign In",
93
- "invalidCredentialsMessage": "Incorrect email or password. Please try again."
94
- }
103
+ "type": "SignInRoot",
104
+ "children": [
105
+ { "type": "SignInEmailControl", "props": { "label": "Email", "placeholder": "you@example.com" } },
106
+ {
107
+ "type": "SignInForm",
108
+ "props": {
109
+ "passwordLabel": "Password",
110
+ "showPasswordLabel": "Show password",
111
+ "hidePasswordLabel": "Hide password",
112
+ "submitLabel": "Sign In",
113
+ "passwordRequiredMessage": "Enter your password.",
114
+ "invalidCredentialsMessage": "Incorrect email or password. Please try again.",
115
+ "blockedMessage": "Access to this account is temporarily blocked. Please try again later.",
116
+ "networkErrorMessage": "Unable to complete the request. Please try again.",
117
+ "genericErrorMessage": "Unable to sign in. Please try again."
118
+ }
119
+ },
120
+ { "type": "SignInMethodOption", "props": { "method": "accessCode", "label": "Use a code instead" } }
121
+ ]
95
122
  }
96
123
  ]
97
124
  }
@@ -101,17 +128,21 @@ SessionRoot (provides the session tri-state; required ancestor)
101
128
 
102
129
  ## Common mistakes
103
130
 
104
- - **Rendering it outside `SessionRoot`.** `useSession()` throws; every identity page must host a `SessionRoot`.
131
+ - **Composing it without a `SignInRoot` ancestor.** The build fails with `context-constraint-violation`; the Root is also what makes the form follow the account's configuration.
132
+ - **Composing it without a `SignInEmailControl`.** The form has no email field of its own, so the shopper has nowhere to type the address and the submit stays disabled.
133
+ - **Expecting an email label, placeholder or invalid-format message on it.** Those belong to `SignInEmailControl`; this component has no email field to label or style.
134
+ - **Expecting it to read data or pre-fill the email.** It declares no fragment and takes no data prop; the Root seeds the shared draft from the shopper's profile.
105
135
  - **Conflating the form-level error with the top-level `UNAUTHORIZED` gate.** They are different error classes (ADR-00007) rendered in different places; `SignInForm` never reads or reacts to the top-level gate.
106
136
  - **Computing the logged-in state locally.** Read it from `useSession()`; `SignInForm` holds no local "am I logged in" flag.
107
- - **Adding a second submit or a two-step email-then-password flow.** The password method is one combined form with a single submit; a two-step flow is the separate access-code component (FSPG-872).
108
- - **Retaining the password after a failed attempt.** It is cleared from state immediately; only the email survives a failed attempt.
137
+ - **Reading the account's enabled methods in a custom part.** Read `useSignIn()`; `SignInRoot` is the one reader of `sessionAuthProviders`.
138
+ - **Adding a second submit or a two-step email-then-password flow.** The password method is one form with a single submit; a two-step flow is the separate access-code family.
139
+ - **Retaining the password after a failed attempt.** It is cleared from state as soon as the dispatch answers; only the shared email survives a failed attempt.
109
140
 
110
141
  ---
111
142
 
112
143
  ## Related
113
144
 
114
- - [[email-field]] — the presentational particle this composes for the email input.
115
- - [[password-field]] — the presentational particle this composes for the password input; `SignInForm` owns its presence check.
116
- - [[email-identification]] — the sibling matter this mirrors in shape (colocated fragment, `pending` convention), without a password or submit step.
145
+ - [[sign-in]] — provides the shared email draft, the active method and the account's enabled-method flags this form reads.
146
+ - [[access-code-sign-in]] — the sibling method composed beside this one under the same `SignInRoot`.
147
+ - [[password-field]] — the presentational particle this composes for the password input; `SignInForm` owns its presence check and its rejected-credentials message.
117
148
  - [[session]] — provides the identification tri-state and the required `SessionRoot` ancestor.
@@ -101,7 +101,7 @@ Bound to a CMS entry, the element authors no `loadingLabel` at all — the entry
101
101
 
102
102
  | Component | What you style | Plausible classes |
103
103
  |---|---|---|
104
- | `SignInRedirect` | The one element the route renders, which is the waiting message. Style it as a centered full-page state rather than as an inline label | `flex min-h-[420px] items-center justify-center text-[14px] font-medium text-[#6B7280]` |
104
+ | `SignInRedirect` | The one element the route renders, which is the waiting message. Style it as a centered full-page state rather than as an inline label | `flex min-h-[420px] items-center justify-center text-[14px] font-medium text-[var(--color-text-muted)]` |
105
105
 
106
106
  That element carries both hooks: `data-fs-sign-in-redirect` is the component's identity, and `data-fs-sign-in-redirect-loading` is the waiting look. They are the same element here, so either reaches it — use the identity for the page state and the loading hook when a rule has to survive the part being rendered on its own.
107
107
 
@@ -113,7 +113,7 @@ That element carries both hooks: `data-fs-sign-in-redirect` is the component's i
113
113
  "platformLoginUrl": "/api/io/login",
114
114
  "loadingLabel": "Redirecionando para o login…"
115
115
  },
116
- "style": ["flex", "min-h-[420px]", "items-center", "justify-center", "text-[14px]", "text-[#6B7280]"]
116
+ "style": ["flex", "min-h-[420px]", "items-center", "justify-center", "text-[14px]", "text-[var(--color-text-muted)]"]
117
117
  }
118
118
  }
119
119
  ```
@@ -128,6 +128,8 @@ A spinner beside the text is a decoration the component does not render. Draw it
128
128
  }
129
129
  ```
130
130
 
131
+ The colors that several elements share are variables of the page or layout `theme`, which declares them: `{"--color-text-muted": "#6B7280"}`. A color used once stays a hex.
132
+
131
133
  ---
132
134
 
133
135
  ## Related
@@ -0,0 +1,173 @@
1
+ # SignIn (Root + EmailControl + MethodSwitch + MethodOption)
2
+
3
+ **Category:** identity
4
+ **Purpose:** The shared surface under every sign-in method. `SignInRoot` reads the account's enabled methods once (`sessionAuthProviders { __typename id passwordAuthentication accessKeyAuthentication }`), owns the one email draft and the active method, and publishes them as the `sign-in` context; it renders no element of its own and always renders its children. `SignInEmailControl` is the one email field. `SignInMethodSwitch` and `SignInMethodOption` move the active method: the first as a single toggle, the second as one selectable option per method. Each part gates itself, so a single-method store needs no authoring decision.
5
+
6
+ ---
7
+
8
+ ## Visual cues (how to identify in an image)
9
+
10
+ - **One email field**, with the sign-in method drawn below it and no second email field further down — this is `SignInEmailControl` over whichever method the page composed.
11
+ - A **single link-like button** that flips between "sign in with a code" and "sign in with a password" under the email field — `SignInMethodSwitch`.
12
+ - **Two side-by-side choices** ("Receive a code" / "Use my password"), one of them marked as the current one — a `SignInMethodOption` per method.
13
+ - **One default method plus a "use password instead" link** — a single `SignInMethodOption` beside the default method's form.
14
+ - A **grey placeholder bar** where the email field will be, shown briefly while the account configuration loads — the email control's skeleton.
15
+
16
+ ---
17
+
18
+ ## When to use
19
+
20
+ - The checkout User Identity step, whenever more than one sign-in method (password, access code) shares an email address.
21
+ - As the single place a page learns which methods the account enables: compose the method families under this Root instead of letting each read the account on its own.
22
+
23
+ ## When NOT to use
24
+
25
+ - A page with exactly one sign-in method and no shared email → use that method's own family directly.
26
+ - Collecting an email that is written to the cart → `EmailIdentificationControl` is the cart-writing path. `SignInEmailControl` never writes anywhere; its value is only the draft the method families sign in with.
27
+ - Placing the Root where a `SessionRoot` is not an ancestor → `useSession()` throws.
28
+
29
+ ---
30
+
31
+ ## Composition
32
+
33
+ ```
34
+ SessionRoot (provides the session tri-state; required ancestor)
35
+ └── SignInRoot (renders no element; reads the account once; owns the email draft and the active method)
36
+ ├── SignInEmailControl (data-fs-sign-in-email; skeleton while unresolved)
37
+ ├── SignInMethodSwitch (presentation 1)
38
+ ├── SignInMethodOption method="accessCode" (presentations 2 and 3)
39
+ ├── SignInMethodOption method="password" (presentation 2)
40
+ ├── SignInForm (the password method; see sign-in-form.md)
41
+ └── AccessCodeSignInRoot (the access-code method; see access-code-sign-in.md)
42
+ ```
43
+
44
+ The two method families bind to this Root rather than reading the account themselves: `SignInForm`
45
+ and `AccessCodeSignInRoot` each render only while their own method is the active one, and both take
46
+ the email from `SignInEmailControl` instead of carrying a field of their own.
47
+
48
+ Compose the switch **or** the options, not both. Three presentations, each a reading of "present one sign-in option per enabled method":
49
+
50
+ | Presentation | Composition | What the shopper sees |
51
+ |---|---|---|
52
+ | 1. One toggle | `SignInMethodSwitch` alone | The active method and one button that moves to the other. Renders only when both methods are enabled |
53
+ | 2. One option per enabled method | one `SignInMethodOption` per method (`method="password"` and `method="accessCode"`) | Every enabled method visible at once, the active one marked selected. A single-method store renders exactly one, because the other option gates itself out |
54
+ | 3. Default method plus one escape hatch | the default method's form, beside a single `SignInMethodOption` for the other | The default method (access code when both are enabled) with the other one click away |
55
+
56
+ `SignInRoot` **must** have a `SessionRoot` ancestor. `SignInEmailControl`, `SignInMethodSwitch` and `SignInMethodOption` **must** be descendants of `SignInRoot` — `useSignIn()` throws `useSignIn() must be used inside a <SignInRoot> subtree.` otherwise (runtime guard, not compiler-checked).
57
+
58
+ `SignInEmailControl` is not required by the compiler, but a page that omits it has no email input anywhere. Composing two `SignInMethodOption` elements with the same `method` makes both claim the selected state; nothing catches it.
59
+
60
+ ---
61
+
62
+ ## Props
63
+
64
+ ### `SignInRoot`
65
+
66
+ | Prop | Type | Default | Notes |
67
+ |------|------|---------|-------|
68
+ | `$data` | `{ clientProfile: { email } \| null, sessionAuthProviders: { passwordAuthentication, accessKeyAuthentication } \| null } \| null` | injected | Colocated `on Query` fragment slice. |
69
+ | `children` | `ReactNode` | — | Always rendered, in every session state and for every flag combination. |
70
+
71
+ **Data:** declares `fragment SignInData on Query { clientProfile { __typename id email } sessionAuthProviders { __typename id passwordAuthentication accessKeyAuthentication } }` with `fetchStrategy: 'reactive'`, `requiresContext: 'session'` and `providesContext: 'sign-in'`. It declares no actions.
72
+
73
+ ### `SignInEmailControl`
74
+
75
+ | Prop | Type | Default | Notes |
76
+ |------|------|---------|-------|
77
+ | `label` | string | — | Passed to `EmailField`. |
78
+ | `placeholder` | string | — | Passed to `EmailField`. |
79
+ | `invalidEmailMessage` | string | — | `EmailField`'s inline error text, shown on blur of a non-empty, malformed address. Omitted, no inline error text renders. |
80
+ | `name` | string | `'email'` | Passed to `EmailField`; the input's `name`. |
81
+ | `autoComplete` | string | `'username'` | Passed to `EmailField`; the input's `autocomplete` token. The default marks the input as the username half of the credential the password step submits, so a browser's password manager saves the address with the password and fills both on the next visit. |
82
+
83
+ ### `SignInMethodSwitch`
84
+
85
+ | Prop | Type | Default | Notes |
86
+ |------|------|---------|-------|
87
+ | `toAccessCodeLabel` | string | — | Button text while the password is the active method. |
88
+ | `toPasswordLabel` | string | — | Button text while the access code is the active method. |
89
+
90
+ ### `SignInMethodOption`
91
+
92
+ | Prop | Type | Default | Notes |
93
+ |------|------|---------|-------|
94
+ | `method` | `'password' \| 'accessCode'` | required | Which method this option selects. The option renders nothing when the account disables that method. |
95
+ | `label` | string | — | The option's button text. |
96
+
97
+ No label prop in this family carries a default: labels are the merchant's own message, so no English
98
+ fallback ships. The two defaults above are `SignInEmailControl`'s `name` and `autoComplete`, which are
99
+ HTML attribute tokens rather than copy.
100
+
101
+ ---
102
+
103
+ ## Behavior
104
+
105
+ - **Resolved before enabled.** The Root derives `resolved` from three signals: the reactive page has settled, the entity slice is the cache's own answer, and `sessionAuthProviders` is present. Every part checks `resolved` before it reads a flag, so "the configuration has not arrived" is never mistaken for "the account enables nothing". Only `SignInEmailControl` draws something meanwhile — its skeleton (`data-fs-sign-in-email-skeleton`, `aria-hidden="true"`).
106
+ - **Signed in renders nothing.** When `useSession().state` is `loggedIn`, the email control, switch and options render nothing; the Root keeps rendering its other children.
107
+ - **No method enabled renders nothing.** With both flags `false`, the email control, switch and options all render nothing.
108
+ - **Active method.** The shopper's choice if they made one; otherwise the access code when it is enabled, otherwise the password. The default is derived, so a choice made before the configuration resolved cannot pin a stale default, and a shopper's choice survives a rerender. Once the configuration has resolved, a choice for a method the account no longer enables falls back to the default, so `method` never names a disabled method; while it is unresolved the choice is kept.
109
+ - **One email draft.** Owned by the Root, seeded from `clientProfile.email` while the shopper has not edited it, and never re-seeded after an edit. It survives a method change. When the session becomes `loggedIn` the shopper's edit is dropped and the draft falls back to the profile email, so the Root, which never unmounts, does not carry a typed address to the next shopper. It is never written to the cart.
110
+ - **Selected state.** A `SignInMethodOption` carries `data-fs-sign-in-method-option-selected` and an `aria-pressed="true"` button only while its method is the active one. Activating the selected option changes nothing.
111
+ - **No actions.** The family dispatches no mutation; the switch, the options and the draft are local state.
112
+
113
+ ### Hooks
114
+
115
+ | Hook | Notes |
116
+ |------|-------|
117
+ | `useSignIn()` | `{ email, setEmail, method, setMethod, passwordEnabled, accessCodeEnabled, anyMethodEnabled, bothMethodsEnabled, resolved }`. Throws outside a `SignInRoot`. |
118
+
119
+ ---
120
+
121
+ ## `data-fs-*` hooks
122
+
123
+ | Attribute | Element | Meaning |
124
+ |---|---|---|
125
+ | `data-fs-sign-in-email` | email wrapper | The email field is present and the configuration resolved |
126
+ | `data-fs-sign-in-email-skeleton`, `data-fs-sign-in-email-skeleton-line` | skeleton | The configuration has not arrived |
127
+ | `data-fs-sign-in-method-switch` | switch wrapper | Both methods are enabled |
128
+ | `data-fs-sign-in-method` | switch wrapper | `password` or `accessCode`: the active method |
129
+ | `data-fs-sign-in-method-switch-button` | switch button | The control that moves the method |
130
+ | `data-fs-sign-in-method-option` | option wrapper | Value is the method this option selects |
131
+ | `data-fs-sign-in-method-option-selected` | option wrapper | Present only while this option's method is active |
132
+ | `data-fs-sign-in-method-option-button` | option button | The control that activates this option's method |
133
+
134
+ ---
135
+
136
+ ## Canonical schema example
137
+
138
+ Presentation 2, one option per enabled method:
139
+
140
+ ```json
141
+ {
142
+ "type": "SessionRoot",
143
+ "children": [
144
+ {
145
+ "type": "SignInRoot",
146
+ "children": [
147
+ { "type": "SignInEmailControl", "props": { "label": "E-mail", "placeholder": "voce@exemplo.com" } },
148
+ { "type": "SignInMethodOption", "props": { "method": "accessCode", "label": "Receber um código" } },
149
+ { "type": "SignInMethodOption", "props": { "method": "password", "label": "Usar minha senha" } }
150
+ ]
151
+ }
152
+ ]
153
+ }
154
+ ```
155
+
156
+ ---
157
+
158
+ ## Common mistakes
159
+
160
+ - **Composing a method part outside `SignInRoot`.** `useSignIn()` throws immediately.
161
+ - **Composing both `SignInMethodSwitch` and `SignInMethodOption`.** Pick one presentation; the two together offer the same choice twice.
162
+ - **Omitting `method` on `SignInMethodOption`.** An option that does not say which method it selects has no meaning.
163
+ - **Expecting a `null` `$data` at runtime for an unresolved read.** A reactive `$data` is never `null`; only `sessionAuthProviders` is absent. `$data={null}` is the component-test equivalent.
164
+ - **Adding a second `SessionRoot`, or reading `sessionAuthProviders` in a method family of your own.** This Root is the one place the account's methods are read.
165
+
166
+ ---
167
+
168
+ ## Related
169
+
170
+ - [[session]] — provides the required `SessionRoot` ancestor and the `loggedIn` state that empties every part.
171
+ - [[email-field]] — the particle `SignInEmailControl` composes.
172
+ - [[access-code-sign-in]] — the access-code method family, which composes under this Root.
173
+ - [[sign-in-form]] — the password method family, which composes under this Root.
@@ -61,11 +61,22 @@ Renders `ToastViewport` into `document.body`. No props, context-only.
61
61
 
62
62
  The fixed-position stack container. Renders a `<div>` — style it directly.
63
63
 
64
- - **No children:** renders one default toast per active toast, in queue order: `ToastRoot` > `ToastTitle` + `ToastDescription` + `ToastAction` + `ToastClose`. Each part renders nothing when the toast has no matching text or `actionProps`, so a reversible toast shows its action between the text and the close button. The close button is named from the message catalog (`fs/toast.dismiss`); its `×` glyph is hidden from assistive technology. The default toast has no status icon and adds no `data-fs-*` hook beyond the existing ones.
65
- - **With children:** renders exactly those children and no default toast. `null`, `false` and `undefined` count as no children.
66
- - **Region name:** every viewport gets `aria-label` from the message catalog (`fs/toast.region`, "Notifications") unless you pass your own `aria-label`.
64
+ - **No children:** renders one default toast per active toast, in queue order: `ToastRoot` > `ToastTitle` + `ToastDescription` + `ToastAction` + `ToastClose`. Each part renders nothing when the toast has no matching text or `actionProps`, so a reversible toast shows its action between the text and the close button. The close button is named by the `dismissLabel` message; its `×` glyph is hidden from assistive technology. The default toast has no status icon and adds no `data-fs-*` hook beyond the existing ones.
65
+ - **With children:** renders exactly those children and no default toast, and does not read `dismissLabel`. `null`, `false` and `undefined` count as no children.
66
+ - **Region name:** every viewport's `aria-label` is the `regionLabel` message. A missing message renders an empty name and logs `message.missing`.
67
67
 
68
- No props beyond standard `className`/HTML attributes. It reads the message catalog, so it needs an intl provider ancestor (a generated app's root layout provides one).
68
+ | Prop | Type | Default | Notes |
69
+ |------|------|---------|-------|
70
+ | `$content` | `ContentValue<typeof ToastViewportContent>` | — | The viewport's messages (below). |
71
+
72
+ Other props are standard `className`/HTML attributes, except `aria-label`, which comes from `regionLabel`. It formats its messages in the storefront locale, so it needs a `StorefrontContextProvider` ancestor (a generated app's root layout provides one).
73
+
74
+ Content type `toast-viewport`:
75
+
76
+ | Content field | Description |
77
+ |---|---|
78
+ | regionLabel | The viewport's accessible name |
79
+ | dismissLabel | The default toast's close button name |
69
80
 
70
81
  ### ToastList
71
82