@verbb/formie-browser 1.0.13 → 1.0.14

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 (381) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/dist/chunks/{address-country-Rx6GQTND.js → address-country-Dn71jroa.js} +10 -4
  3. package/dist/chunks/{address-finder-k7_BXaRe.js → address-finder-O49uDRoR.js} +2 -2
  4. package/dist/chunks/{address-state-BwE01m2_.js → address-state-ByYatUur.js} +154 -143
  5. package/dist/chunks/{api-DqpfkZWL.js → api-D6kJ7kXZ.js} +183 -179
  6. package/dist/chunks/{api-BUb6P-xu.js → api-DYYsVIub.js} +77 -47
  7. package/dist/chunks/{api-sPqGbOww.js → api-ghNr2uxX.js} +15 -9
  8. package/dist/chunks/{bpoint-Dlq34XH1.js → bpoint-D0RKFM4F.js} +3 -3
  9. package/dist/chunks/calculations-YEoVCG2q.js +310 -0
  10. package/dist/chunks/{captcha-eu-CGm8Lbrj.js → captcha-eu-DERJbXnH.js} +5 -4
  11. package/dist/chunks/{checkbox-radio-BY2aTCOG.js → checkbox-radio-gsm8QPJg.js} +74 -75
  12. package/dist/chunks/{combobox-C0EuExSI.js → combobox-CWNdx4Fk.js} +290 -279
  13. package/dist/chunks/conditions-DqNHLTbN.js +464 -0
  14. package/dist/chunks/country-from-ip-DDj_mFki.js +29 -0
  15. package/dist/chunks/csrf-DxHg_ZYt.js +61 -0
  16. package/dist/chunks/{custom-google-maps-BsaSirEZ.js → custom-google-maps-C4l2S3GO.js} +9 -3
  17. package/dist/chunks/{custom-link-CJ1-FjEM.js → custom-link-CLazgKYH.js} +8 -2
  18. package/dist/chunks/{custom-maps-DYW_pBid.js → custom-maps-DqcAlD0v.js} +10 -4
  19. package/dist/chunks/{date-picker-F9BUBDSW.js → date-picker-RUnevF7l.js} +455 -432
  20. package/dist/chunks/{dist-D6i-VNgM.js → dist-ZLeW0zZ3.js} +1281 -453
  21. package/dist/chunks/{eway-D9_m8ooj.js → eway-or6dtjoT.js} +3 -3
  22. package/dist/chunks/field-references.resolver-Ca8MguFv.js +104 -0
  23. package/dist/chunks/{file-upload-rqfZNqlH.js → file-upload-Bm-TXyNB.js} +104 -96
  24. package/dist/chunks/friendly-captcha-v1-GFqCt1Mh.js +34 -0
  25. package/dist/chunks/{friendly-captcha-v2-CLSAbkqx.js → friendly-captcha-v2-WoW246JG.js} +6 -5
  26. package/dist/chunks/{friendly-challenge-8uPatWqk.js → friendly-challenge-DPG9MJb1.js} +111 -102
  27. package/dist/chunks/{go-cardless-DAT3ZaQf.js → go-cardless-DzJ-0FKg.js} +2 -2
  28. package/dist/chunks/google-address-C1P1nTDM.js +163 -0
  29. package/dist/chunks/{hcaptcha-CGLAmgjO.js → hcaptcha-D0T8aIHz.js} +3 -3
  30. package/dist/chunks/{hidden-D7_Ch-QN.js → hidden-BZhXnNPe.js} +8 -2
  31. package/dist/chunks/http-C2QdHuWO.js +27 -0
  32. package/dist/chunks/{leaflet-src-j-lHNmhR.js → leaflet-src-DE6rv6M-.js} +42 -46
  33. package/dist/chunks/{loqate-CJPzBmSm.js → loqate-DD1S7PY9.js} +2 -2
  34. package/dist/chunks/{mollie-Bibhl67p.js → mollie-DG8Ju83x.js} +2 -2
  35. package/dist/chunks/{moneris-H2wSqk9h.js → moneris-C8m3Fvqu.js} +3 -3
  36. package/dist/chunks/opayo-B3EvrVxw.js +188 -0
  37. package/dist/chunks/{paddle-DkvIxQdG.js → paddle-BIYR9Um3.js} +3 -3
  38. package/dist/chunks/{password-validation-D06uH9va.js → password-validation-C8_uO_c_.js} +18 -12
  39. package/dist/chunks/{paypal-CQpAF7Ua.js → paypal-B_yxIo2d.js} +7 -5
  40. package/dist/chunks/{payway-CwDkC7YZ.js → payway-CeOzS0sL.js} +3 -3
  41. package/dist/chunks/{phone-country-D3ayr60L.js → phone-country-bAqje17P.js} +80 -63
  42. package/dist/chunks/{place-kit-BGHklIZ-.js → place-kit-BE5gi3vo.js} +3 -3
  43. package/dist/chunks/{placekit-autocomplete.esm-DWVabQlq.js → placekit-autocomplete.esm-CZZERYur.js} +11 -15
  44. package/dist/chunks/{recaptcha-enterprise-XPId5-bS.js → recaptcha-enterprise-CruXddZq.js} +4 -4
  45. package/dist/chunks/{recaptcha-shared-CLYJvojk.js → recaptcha-shared-AQRMDMme.js} +1 -1
  46. package/dist/chunks/{recaptcha-v2-checkbox-Cy-0PEPc.js → recaptcha-v2-checkbox-CCnJYCnG.js} +4 -4
  47. package/dist/chunks/{recaptcha-v2-invisible-BwRH540O.js → recaptcha-v2-invisible-BuVqRRYn.js} +4 -4
  48. package/dist/chunks/{recaptcha-v3-No4Ykrhk.js → recaptcha-v3-CloqhO2A.js} +4 -4
  49. package/dist/chunks/{repeater-BVnPUqTj.js → repeater-DwE27jI1.js} +25 -19
  50. package/dist/chunks/request-profile-DhwkeCpS.js +10 -0
  51. package/dist/chunks/rich-text-uV4o_pGk.js +361 -0
  52. package/dist/chunks/{chunk-3b4jIN3o.js → rolldown-runtime-DtPi1Y-2.js} +2 -2
  53. package/dist/chunks/{sdk-BhHAYgga.js → sdk-lkwSvlpM.js} +282 -234
  54. package/dist/chunks/{shared-Bx9s0i0P.js → shared-OKhSay59.js} +27 -21
  55. package/dist/chunks/{signature-IOhuicje.js → signature-7cldFbqj.js} +138 -112
  56. package/dist/chunks/{snaptcha-DKx98oon.js → snaptcha-C04kNGYQ.js} +2 -2
  57. package/dist/chunks/{square-DwdcOI1G.js → square-DEzxv9D9.js} +8 -6
  58. package/dist/chunks/{stripe-DaoG2FT1.js → stripe-CVPQGDz3.js} +10 -11
  59. package/dist/chunks/{summary-Dks0gXS3.js → summary-BF_8mrXI.js} +47 -45
  60. package/dist/chunks/{survey-likert-DkE6bR7B.js → survey-likert-fk1hUPff.js} +7 -1
  61. package/dist/chunks/{survey-rank-DN6x4IZM.js → survey-rank-BsLGl2LX.js} +37 -25
  62. package/dist/chunks/{survey-rating-BnsNL9U5.js → survey-rating-DVS6e6fM.js} +17 -5
  63. package/dist/chunks/{table-CAjCJHrL.js → table-DnIBdeKF.js} +21 -15
  64. package/dist/chunks/{text-limit-BGaY0jhI.js → text-limit-LGMPhFuC.js} +40 -34
  65. package/dist/chunks/{theme-classes-Tv7q7ToE.js → theme-classes-DAQuEqdP.js} +1 -1
  66. package/dist/chunks/{turnstile-DJakPzQD.js → turnstile-n9DNyPxi.js} +3 -3
  67. package/dist/chunks/{upload-manager-W-QDgxKD.js → upload-manager-BbiUosZq.js} +410 -350
  68. package/dist/chunks/{utils-Vqp8i_RM.js → utils-DpUBPadZ.js} +20 -14
  69. package/dist/css/formie-base.css +104 -1
  70. package/dist/css/theme/_messages.css +2 -0
  71. package/dist/css/theme/_tokens.css +31 -25
  72. package/dist/css/theme/forms/_form.css +5 -1
  73. package/dist/index.d.ts +5 -4
  74. package/dist/index.d.ts.map +1 -1
  75. package/dist/index.js +1778 -1427
  76. package/dist/js/contracts/client.d.ts +5 -3
  77. package/dist/js/contracts/client.d.ts.map +1 -1
  78. package/dist/js/contracts/common.d.ts +2 -2
  79. package/dist/js/contracts/common.d.ts.map +1 -1
  80. package/dist/js/contracts/modules.d.ts +37 -12
  81. package/dist/js/contracts/modules.d.ts.map +1 -1
  82. package/dist/js/contracts/schema.d.ts +20 -38
  83. package/dist/js/contracts/schema.d.ts.map +1 -1
  84. package/dist/js/contracts/theme.d.ts +4 -1
  85. package/dist/js/contracts/theme.d.ts.map +1 -1
  86. package/dist/js/core/client-rendered-modules.d.ts +17 -0
  87. package/dist/js/core/client-rendered-modules.d.ts.map +1 -0
  88. package/dist/js/core/create-formie-client.d.ts.map +1 -1
  89. package/dist/js/core/field-error-aria.d.ts +23 -0
  90. package/dist/js/core/field-error-aria.d.ts.map +1 -0
  91. package/dist/js/core/hydrate-modules.d.ts +10 -8
  92. package/dist/js/core/hydrate-modules.d.ts.map +1 -1
  93. package/dist/js/core/submit-result-state.d.ts.map +1 -1
  94. package/dist/js/core/submit-result-ui.d.ts.map +1 -1
  95. package/dist/js/core/validation-focus.d.ts.map +1 -1
  96. package/dist/js/modules/address/address-finder.d.ts +1 -1
  97. package/dist/js/modules/address/address-finder.d.ts.map +1 -1
  98. package/dist/js/modules/address/factories.d.ts +3 -3
  99. package/dist/js/modules/address/factories.d.ts.map +1 -1
  100. package/dist/js/modules/address/google-address.d.ts +2 -1
  101. package/dist/js/modules/address/google-address.d.ts.map +1 -1
  102. package/dist/js/modules/address/index.d.ts +2 -2
  103. package/dist/js/modules/address/index.d.ts.map +1 -1
  104. package/dist/js/modules/address/loqate.d.ts +1 -1
  105. package/dist/js/modules/address/loqate.d.ts.map +1 -1
  106. package/dist/js/modules/address/place-kit.d.ts +1 -1
  107. package/dist/js/modules/address/place-kit.d.ts.map +1 -1
  108. package/dist/js/modules/captchas/captcha-eu.d.ts +1 -1
  109. package/dist/js/modules/captchas/captcha-eu.d.ts.map +1 -1
  110. package/dist/js/modules/captchas/factories.d.ts +11 -11
  111. package/dist/js/modules/captchas/factories.d.ts.map +1 -1
  112. package/dist/js/modules/captchas/friendly-captcha-v1.d.ts +1 -1
  113. package/dist/js/modules/captchas/friendly-captcha-v1.d.ts.map +1 -1
  114. package/dist/js/modules/captchas/friendly-captcha-v2.d.ts +1 -1
  115. package/dist/js/modules/captchas/friendly-captcha-v2.d.ts.map +1 -1
  116. package/dist/js/modules/captchas/hcaptcha.d.ts +1 -1
  117. package/dist/js/modules/captchas/hcaptcha.d.ts.map +1 -1
  118. package/dist/js/modules/captchas/index.d.ts +2 -2
  119. package/dist/js/modules/captchas/index.d.ts.map +1 -1
  120. package/dist/js/modules/captchas/recaptcha-enterprise.d.ts +1 -1
  121. package/dist/js/modules/captchas/recaptcha-enterprise.d.ts.map +1 -1
  122. package/dist/js/modules/captchas/recaptcha-v2-checkbox.d.ts +1 -1
  123. package/dist/js/modules/captchas/recaptcha-v2-checkbox.d.ts.map +1 -1
  124. package/dist/js/modules/captchas/recaptcha-v2-invisible.d.ts +1 -1
  125. package/dist/js/modules/captchas/recaptcha-v2-invisible.d.ts.map +1 -1
  126. package/dist/js/modules/captchas/recaptcha-v3.d.ts +1 -1
  127. package/dist/js/modules/captchas/recaptcha-v3.d.ts.map +1 -1
  128. package/dist/js/modules/captchas/snaptcha.d.ts +1 -1
  129. package/dist/js/modules/captchas/snaptcha.d.ts.map +1 -1
  130. package/dist/js/modules/captchas/turnstile.d.ts +1 -1
  131. package/dist/js/modules/captchas/turnstile.d.ts.map +1 -1
  132. package/dist/js/modules/fields/address-country.d.ts +2 -2
  133. package/dist/js/modules/fields/address-country.d.ts.map +1 -1
  134. package/dist/js/modules/fields/address-state.d.ts +2 -2
  135. package/dist/js/modules/fields/address-state.d.ts.map +1 -1
  136. package/dist/js/modules/fields/calculations.d.ts +2 -2
  137. package/dist/js/modules/fields/calculations.d.ts.map +1 -1
  138. package/dist/js/modules/fields/checkbox-radio.d.ts +2 -2
  139. package/dist/js/modules/fields/checkbox-radio.d.ts.map +1 -1
  140. package/dist/js/modules/fields/combobox.d.ts +2 -2
  141. package/dist/js/modules/fields/combobox.d.ts.map +1 -1
  142. package/dist/js/modules/fields/conditions/config.d.ts.map +1 -1
  143. package/dist/js/modules/fields/conditions/effects.d.ts +1 -0
  144. package/dist/js/modules/fields/conditions/effects.d.ts.map +1 -1
  145. package/dist/js/modules/fields/conditions/evaluator.d.ts +4 -1
  146. package/dist/js/modules/fields/conditions/evaluator.d.ts.map +1 -1
  147. package/dist/js/modules/fields/conditions/references.d.ts.map +1 -1
  148. package/dist/js/modules/fields/conditions/submission-context.d.ts +15 -0
  149. package/dist/js/modules/fields/conditions/submission-context.d.ts.map +1 -0
  150. package/dist/js/modules/fields/conditions/types.d.ts +3 -1
  151. package/dist/js/modules/fields/conditions/types.d.ts.map +1 -1
  152. package/dist/js/modules/fields/conditions/values.d.ts +1 -1
  153. package/dist/js/modules/fields/conditions/values.d.ts.map +1 -1
  154. package/dist/js/modules/fields/conditions.d.ts +2 -2
  155. package/dist/js/modules/fields/conditions.d.ts.map +1 -1
  156. package/dist/js/modules/fields/custom-google-maps.d.ts +2 -2
  157. package/dist/js/modules/fields/custom-google-maps.d.ts.map +1 -1
  158. package/dist/js/modules/fields/custom-link.d.ts +2 -2
  159. package/dist/js/modules/fields/custom-link.d.ts.map +1 -1
  160. package/dist/js/modules/fields/custom-maps.d.ts +2 -2
  161. package/dist/js/modules/fields/custom-maps.d.ts.map +1 -1
  162. package/dist/js/modules/fields/date-picker.d.ts +2 -2
  163. package/dist/js/modules/fields/date-picker.d.ts.map +1 -1
  164. package/dist/js/modules/fields/file-upload.d.ts +2 -2
  165. package/dist/js/modules/fields/file-upload.d.ts.map +1 -1
  166. package/dist/js/modules/fields/hidden.d.ts +2 -2
  167. package/dist/js/modules/fields/hidden.d.ts.map +1 -1
  168. package/dist/js/modules/fields/index.d.ts +2 -2
  169. package/dist/js/modules/fields/index.d.ts.map +1 -1
  170. package/dist/js/modules/fields/password-validation.d.ts +2 -2
  171. package/dist/js/modules/fields/password-validation.d.ts.map +1 -1
  172. package/dist/js/modules/fields/phone-country.d.ts +2 -2
  173. package/dist/js/modules/fields/phone-country.d.ts.map +1 -1
  174. package/dist/js/modules/fields/repeater.d.ts +2 -2
  175. package/dist/js/modules/fields/repeater.d.ts.map +1 -1
  176. package/dist/js/modules/fields/rich-text.d.ts +2 -2
  177. package/dist/js/modules/fields/rich-text.d.ts.map +1 -1
  178. package/dist/js/modules/fields/shared.d.ts +1 -0
  179. package/dist/js/modules/fields/shared.d.ts.map +1 -1
  180. package/dist/js/modules/fields/signature.d.ts +2 -2
  181. package/dist/js/modules/fields/signature.d.ts.map +1 -1
  182. package/dist/js/modules/fields/summary.d.ts +2 -2
  183. package/dist/js/modules/fields/summary.d.ts.map +1 -1
  184. package/dist/js/modules/fields/survey-likert.d.ts +2 -2
  185. package/dist/js/modules/fields/survey-likert.d.ts.map +1 -1
  186. package/dist/js/modules/fields/survey-rank.d.ts +2 -2
  187. package/dist/js/modules/fields/survey-rank.d.ts.map +1 -1
  188. package/dist/js/modules/fields/survey-rating.d.ts +2 -2
  189. package/dist/js/modules/fields/survey-rating.d.ts.map +1 -1
  190. package/dist/js/modules/fields/table.d.ts +2 -2
  191. package/dist/js/modules/fields/table.d.ts.map +1 -1
  192. package/dist/js/modules/fields/text-limit.d.ts +2 -2
  193. package/dist/js/modules/fields/text-limit.d.ts.map +1 -1
  194. package/dist/js/modules/fields/upload-manager.d.ts +2 -2
  195. package/dist/js/modules/fields/upload-manager.d.ts.map +1 -1
  196. package/dist/js/modules/loader.d.ts +10 -4
  197. package/dist/js/modules/loader.d.ts.map +1 -1
  198. package/dist/js/modules/payments/bpoint.d.ts +1 -1
  199. package/dist/js/modules/payments/bpoint.d.ts.map +1 -1
  200. package/dist/js/modules/payments/eway.d.ts +1 -1
  201. package/dist/js/modules/payments/eway.d.ts.map +1 -1
  202. package/dist/js/modules/payments/factories.d.ts +7 -7
  203. package/dist/js/modules/payments/factories.d.ts.map +1 -1
  204. package/dist/js/modules/payments/go-cardless.d.ts +1 -1
  205. package/dist/js/modules/payments/go-cardless.d.ts.map +1 -1
  206. package/dist/js/modules/payments/index.d.ts +2 -2
  207. package/dist/js/modules/payments/index.d.ts.map +1 -1
  208. package/dist/js/modules/payments/mollie.d.ts +1 -1
  209. package/dist/js/modules/payments/mollie.d.ts.map +1 -1
  210. package/dist/js/modules/payments/moneris.d.ts +1 -1
  211. package/dist/js/modules/payments/moneris.d.ts.map +1 -1
  212. package/dist/js/modules/payments/opayo.d.ts +1 -1
  213. package/dist/js/modules/payments/opayo.d.ts.map +1 -1
  214. package/dist/js/modules/payments/paddle.d.ts +1 -1
  215. package/dist/js/modules/payments/paddle.d.ts.map +1 -1
  216. package/dist/js/modules/payments/paypal.d.ts +1 -1
  217. package/dist/js/modules/payments/paypal.d.ts.map +1 -1
  218. package/dist/js/modules/payments/payway.d.ts +1 -1
  219. package/dist/js/modules/payments/payway.d.ts.map +1 -1
  220. package/dist/js/modules/payments/square.d.ts +1 -1
  221. package/dist/js/modules/payments/square.d.ts.map +1 -1
  222. package/dist/js/modules/payments/stripe.d.ts +1 -1
  223. package/dist/js/modules/payments/stripe.d.ts.map +1 -1
  224. package/dist/js/modules/payments/utils.d.ts +6 -0
  225. package/dist/js/modules/payments/utils.d.ts.map +1 -1
  226. package/dist/js/modules/registry.d.ts +6 -4
  227. package/dist/js/modules/registry.d.ts.map +1 -1
  228. package/dist/js/submit/pipeline.d.ts.map +1 -1
  229. package/dist/js/theme/browser-theme-state.generated.d.ts +24 -0
  230. package/dist/js/theme/browser-theme-state.generated.d.ts.map +1 -0
  231. package/dist/js/theme/theme-classes.d.ts +3 -3
  232. package/dist/js/theme/theme-classes.d.ts.map +1 -1
  233. package/dist/js/transport/forms-api.d.ts +5 -3
  234. package/dist/js/transport/forms-api.d.ts.map +1 -1
  235. package/dist/js/utils/country-from-ip.d.ts +2 -2
  236. package/dist/js/utils/country-from-ip.d.ts.map +1 -1
  237. package/dist/js/utils/csrf.d.ts +17 -0
  238. package/dist/js/utils/csrf.d.ts.map +1 -0
  239. package/dist/js/utils/field-references.parser.d.ts +1 -0
  240. package/dist/js/utils/field-references.parser.d.ts.map +1 -1
  241. package/dist/js/utils/field-references.resolver.d.ts.map +1 -1
  242. package/dist/js/utils/field-references.types.d.ts +1 -0
  243. package/dist/js/utils/field-references.types.d.ts.map +1 -1
  244. package/dist/js/utils/http.d.ts +3 -1
  245. package/dist/js/utils/http.d.ts.map +1 -1
  246. package/dist/js/utils/request-profile.d.ts +4 -0
  247. package/dist/js/utils/request-profile.d.ts.map +1 -0
  248. package/dist/js/utils/unload-warning.d.ts.map +1 -1
  249. package/dist/js/validation/rules/email.d.ts.map +1 -1
  250. package/dist/js/validation/rules/match.d.ts.map +1 -1
  251. package/dist/js/validation/rules/number.d.ts.map +1 -1
  252. package/dist/js/validation/rules/required.d.ts.map +1 -1
  253. package/dist/js/validation/rules/shared.d.ts.map +1 -1
  254. package/dist/js/validation/rules/url.d.ts.map +1 -1
  255. package/dist/js/validation/skip.d.ts +7 -0
  256. package/dist/js/validation/skip.d.ts.map +1 -0
  257. package/dist/js/validation/submit-readiness.d.ts.map +1 -1
  258. package/dist/js/validation/validator.d.ts.map +1 -1
  259. package/package.json +43 -12
  260. package/src/css/formie-base.css +104 -1
  261. package/src/css/theme/_messages.css +2 -0
  262. package/src/css/theme/_tokens.css +31 -25
  263. package/src/css/theme/forms/_form.css +5 -1
  264. package/src/index.ts +13 -8
  265. package/src/js/contracts/client.ts +5 -3
  266. package/src/js/contracts/common.ts +5 -6
  267. package/src/js/contracts/modules.ts +41 -12
  268. package/src/js/contracts/schema.ts +21 -43
  269. package/src/js/contracts/theme.ts +6 -1
  270. package/src/js/core/client-rendered-modules.ts +69 -0
  271. package/src/js/core/create-formie-client.ts +116 -77
  272. package/src/js/core/field-error-aria.ts +93 -0
  273. package/src/js/core/hydrate-modules.ts +54 -29
  274. package/src/js/core/submit-result-state.ts +34 -45
  275. package/src/js/core/submit-result-ui.ts +21 -65
  276. package/src/js/core/validation-focus.ts +20 -20
  277. package/src/js/modules/address/address-finder.ts +1 -1
  278. package/src/js/modules/address/factories.ts +15 -13
  279. package/src/js/modules/address/google-address.ts +10 -6
  280. package/src/js/modules/address/index.ts +2 -2
  281. package/src/js/modules/address/loqate.ts +1 -1
  282. package/src/js/modules/address/place-kit.ts +1 -1
  283. package/src/js/modules/captchas/captcha-eu.ts +2 -2
  284. package/src/js/modules/captchas/factories.ts +66 -42
  285. package/src/js/modules/captchas/friendly-captcha-v1.ts +12 -2
  286. package/src/js/modules/captchas/friendly-captcha-v2.ts +4 -2
  287. package/src/js/modules/captchas/hcaptcha.ts +5 -5
  288. package/src/js/modules/captchas/index.ts +2 -2
  289. package/src/js/modules/captchas/recaptcha-enterprise.ts +2 -2
  290. package/src/js/modules/captchas/recaptcha-v2-checkbox.ts +3 -3
  291. package/src/js/modules/captchas/recaptcha-v2-invisible.ts +2 -2
  292. package/src/js/modules/captchas/recaptcha-v3.ts +2 -2
  293. package/src/js/modules/captchas/snaptcha.ts +1 -1
  294. package/src/js/modules/captchas/turnstile.ts +3 -3
  295. package/src/js/modules/fields/address-country.ts +6 -4
  296. package/src/js/modules/fields/address-state.ts +20 -12
  297. package/src/js/modules/fields/calculations.ts +5 -3
  298. package/src/js/modules/fields/checkbox-radio.ts +24 -42
  299. package/src/js/modules/fields/combobox.ts +25 -9
  300. package/src/js/modules/fields/conditions/config.ts +17 -20
  301. package/src/js/modules/fields/conditions/effects.ts +23 -26
  302. package/src/js/modules/fields/conditions/evaluator.ts +21 -29
  303. package/src/js/modules/fields/conditions/references.ts +16 -5
  304. package/src/js/modules/fields/conditions/submission-context.ts +80 -0
  305. package/src/js/modules/fields/conditions/types.ts +3 -1
  306. package/src/js/modules/fields/conditions/values.ts +31 -6
  307. package/src/js/modules/fields/conditions.ts +59 -18
  308. package/src/js/modules/fields/custom-google-maps.ts +5 -3
  309. package/src/js/modules/fields/custom-link.ts +5 -3
  310. package/src/js/modules/fields/custom-maps.ts +5 -3
  311. package/src/js/modules/fields/date-picker.ts +34 -4
  312. package/src/js/modules/fields/file-upload.ts +19 -10
  313. package/src/js/modules/fields/hidden.ts +5 -3
  314. package/src/js/modules/fields/index.ts +2 -2
  315. package/src/js/modules/fields/password-validation.ts +5 -3
  316. package/src/js/modules/fields/phone-country.ts +33 -6
  317. package/src/js/modules/fields/repeater.ts +5 -3
  318. package/src/js/modules/fields/rich-text.ts +20 -4
  319. package/src/js/modules/fields/shared.ts +13 -0
  320. package/src/js/modules/fields/signature.ts +24 -4
  321. package/src/js/modules/fields/summary.ts +8 -20
  322. package/src/js/modules/fields/survey-likert.ts +5 -3
  323. package/src/js/modules/fields/survey-rank.ts +21 -3
  324. package/src/js/modules/fields/survey-rating.ts +17 -3
  325. package/src/js/modules/fields/table.ts +5 -3
  326. package/src/js/modules/fields/text-limit.ts +5 -3
  327. package/src/js/modules/fields/upload-manager.ts +190 -49
  328. package/src/js/modules/loader.ts +345 -281
  329. package/src/js/modules/payments/bpoint.ts +2 -2
  330. package/src/js/modules/payments/eway.ts +2 -2
  331. package/src/js/modules/payments/factories.ts +53 -52
  332. package/src/js/modules/payments/go-cardless.ts +1 -1
  333. package/src/js/modules/payments/index.ts +2 -2
  334. package/src/js/modules/payments/mollie.ts +1 -1
  335. package/src/js/modules/payments/moneris.ts +2 -2
  336. package/src/js/modules/payments/opayo.ts +21 -8
  337. package/src/js/modules/payments/paddle.ts +10 -6
  338. package/src/js/modules/payments/payment.ts +22 -18
  339. package/src/js/modules/payments/paypal.ts +1 -1
  340. package/src/js/modules/payments/payway.ts +2 -2
  341. package/src/js/modules/payments/square.ts +2 -2
  342. package/src/js/modules/payments/stripe.ts +5 -5
  343. package/src/js/modules/payments/utils.ts +14 -0
  344. package/src/js/modules/registry.ts +19 -11
  345. package/src/js/submit/pipeline.ts +10 -11
  346. package/src/js/theme/browser-theme-state.generated.ts +25 -0
  347. package/src/js/theme/theme-classes.ts +3 -3
  348. package/src/js/transport/forms-api.ts +66 -67
  349. package/src/js/utils/country-from-ip.ts +14 -9
  350. package/src/js/utils/csrf.ts +136 -0
  351. package/src/js/utils/field-references.parser.ts +13 -113
  352. package/src/js/utils/field-references.resolver.ts +27 -64
  353. package/src/js/utils/field-references.row-scope.ts +1 -1
  354. package/src/js/utils/field-references.types.ts +1 -0
  355. package/src/js/utils/http.ts +5 -5
  356. package/src/js/utils/request-profile.ts +10 -0
  357. package/src/js/utils/unload-warning.ts +12 -4
  358. package/src/js/validation/rules/email.ts +3 -5
  359. package/src/js/validation/rules/match.ts +2 -1
  360. package/src/js/validation/rules/minmax.ts +4 -43
  361. package/src/js/validation/rules/number.ts +3 -47
  362. package/src/js/validation/rules/pattern.ts +3 -8
  363. package/src/js/validation/rules/required.ts +2 -1
  364. package/src/js/validation/rules/shared.ts +5 -1
  365. package/src/js/validation/rules/url.ts +3 -10
  366. package/src/js/validation/skip.ts +9 -0
  367. package/src/js/validation/submit-readiness.ts +9 -2
  368. package/src/js/validation/validator.ts +35 -59
  369. package/dist/chunks/calculations-Dv3hYb8_.js +0 -299
  370. package/dist/chunks/conditions-CPH1snCx.js +0 -424
  371. package/dist/chunks/country-from-ip-BwxKaBuJ.js +0 -26
  372. package/dist/chunks/field-references.resolver-CHwn0G0L.js +0 -145
  373. package/dist/chunks/friendly-captcha-v1-C_2reOXr.js +0 -31
  374. package/dist/chunks/google-address-BH3Zhi06.js +0 -161
  375. package/dist/chunks/http-D-JExro7.js +0 -27
  376. package/dist/chunks/opayo-CR0DtsLa.js +0 -179
  377. package/dist/chunks/rich-text-Bg_--4TG.js +0 -349
  378. package/dist/js/modules/fields/conditions/transforms.d.ts +0 -3
  379. package/dist/js/modules/fields/conditions/transforms.d.ts.map +0 -1
  380. package/src/js/modules/fields/conditions/transforms.ts +0 -206
  381. package/src/js/modules/payments/stub-payment-module.ts +0 -87
@@ -2,8 +2,8 @@ import flatpickr from 'flatpickr';
2
2
  import * as flatpickrLocales from 'flatpickr/dist/l10n/index.js';
3
3
  import flatpickrCss from 'flatpickr/dist/flatpickr.css?inline';
4
4
 
5
- import type { FormieModuleDefinition } from '#contracts/modules';
6
- import { dispatchFieldEvent, getModuleFieldContainers } from '#modules/fields/shared';
5
+ import type { BrowserModuleDefinition } from '#contracts/modules';
6
+ import { bindConditionalClear, dispatchFieldEvent, getModuleFieldContainers } from '#modules/fields/shared';
7
7
  import { ensureModuleStyles } from '#modules/styles';
8
8
  import { createDebug } from '#utils/debug';
9
9
 
@@ -30,6 +30,8 @@ type DatePickerOptions = {
30
30
 
31
31
  type FlatpickrInstanceLike = {
32
32
  destroy: () => void;
33
+ selectedDates: Date[];
34
+ setDate: (dates: Date[], triggerChange?: boolean) => void;
33
35
  };
34
36
 
35
37
  type FlatpickrInput = HTMLInputElement & {
@@ -43,6 +45,7 @@ type FlatpickrChangeInstance = {
43
45
 
44
46
  function attributesPlugin() {
45
47
  return (instance: { input: HTMLInputElement; altInput?: HTMLInputElement | undefined; loadedPlugins: string[] }) => {
48
+ const originalAttributes = new Map<string, string>();
46
49
  return {
47
50
  onReady: () => {
48
51
  if (!instance.altInput) {
@@ -60,6 +63,7 @@ function attributesPlugin() {
60
63
 
61
64
  const value = instance.input.getAttribute(attribute);
62
65
  if (value !== null) {
66
+ originalAttributes.set(attribute, value);
63
67
  instance.altInput?.setAttribute(attribute, value);
64
68
  }
65
69
 
@@ -68,6 +72,15 @@ function attributesPlugin() {
68
72
 
69
73
  instance.loadedPlugins.push('formie-attributes');
70
74
  },
75
+ onDestroy: () => {
76
+ // Conditional fields and page navigation can mount this input again.
77
+ // Restore the markers and labels moved onto the temporary alt input.
78
+ originalAttributes.forEach((value, attribute) => {
79
+ if (!instance.input.hasAttribute(attribute)) {
80
+ instance.input.setAttribute(attribute, value);
81
+ }
82
+ });
83
+ },
71
84
  };
72
85
  };
73
86
  }
@@ -309,6 +322,19 @@ function initDatePicker(input: FlatpickrInput, options: DatePickerOptions): () =
309
322
 
310
323
  const instance = flatpickr(input, mergedOptions) as FlatpickrInstanceLike;
311
324
  input._formieFlatpickr = instance;
325
+ const initialDates = instance.selectedDates.map((date) => new Date(date.getTime()));
326
+ const form = input.form;
327
+ const onReset = (event: Event) => {
328
+ // Flatpickr uses hidden transport inputs, whose values survive native reset.
329
+ // Restore the picker and its range inputs together after the native controls.
330
+ queueMicrotask(() => {
331
+ if (!event.defaultPrevented) {
332
+ instance.setDate(initialDates, true);
333
+ }
334
+ });
335
+ };
336
+ form?.addEventListener('reset', onReset);
337
+ const unbindConditionalClear = bindConditionalClear(input, () => instance.setDate([], true));
312
338
  debug.log('Initialized.', {
313
339
  inputName: input.name,
314
340
  isRange,
@@ -320,6 +346,8 @@ function initDatePicker(input: FlatpickrInput, options: DatePickerOptions): () =
320
346
  });
321
347
 
322
348
  return () => {
349
+ unbindConditionalClear();
350
+ form?.removeEventListener('reset', onReset);
323
351
  instance.destroy();
324
352
  delete input._formieFlatpickr;
325
353
  debug.log('Destroyed.', {
@@ -328,8 +356,10 @@ function initDatePicker(input: FlatpickrInput, options: DatePickerOptions): () =
328
356
  };
329
357
  }
330
358
 
331
- export const datePickerModule: FormieModuleDefinition = {
332
- id: MODULE_ID,
359
+ export const datePickerModule: BrowserModuleDefinition = {
360
+ moduleId: `formie:${MODULE_ID}`,
361
+ version: 2,
362
+ surfaces: ['server-rendered', 'client-rendered', 'cp-edit'],
333
363
  kind: 'field',
334
364
  match: (ctx) => {
335
365
  return !!ctx.target.querySelector(INPUT_SELECTOR);
@@ -1,6 +1,6 @@
1
1
  import fileUploadCss from '#theme-css/fields/_file.css?inline';
2
2
 
3
- import type { FormieModuleDefinition } from '#contracts/modules';
3
+ import type { BrowserModuleDefinition } from '#contracts/modules';
4
4
  import { dispatchFieldEvent, releaseFormValidators, retainFormValidators } from '#modules/fields/shared';
5
5
  import { ensureModuleStyles } from '#modules/styles';
6
6
  import { getFieldModuleEventName, getFileUploadEventName, getFormStateEventName } from '#utils/event-names';
@@ -13,6 +13,7 @@ const FILE_UPLOAD_KEY_ATTR = 'data-formie-file-upload-key';
13
13
  const HYDRATE_ENDPOINT_ATTR = 'data-formie-file-upload-hydrate-endpoint';
14
14
  const HIDDEN_INPUT_ANCHOR_ATTR = 'data-formie-file-upload-anchor';
15
15
  const HIDDEN_INPUT_VALUE_ATTR = 'data-formie-file-upload-asset-id';
16
+ const HIDDEN_INPUT_ENTRY_ATTR = 'data-formie-file-upload-entry';
16
17
  const FILE_VALIDATORS = [
17
18
  'fileLimit',
18
19
  'fileSizeMinLimit',
@@ -93,7 +94,8 @@ function getUploadedAssetInputs(field: HTMLElement, input: HTMLInputElement): HT
93
94
  const assetInputName = getUploadedAssetInputName(input);
94
95
 
95
96
  return getHiddenInputs(field).filter((hiddenInput) => {
96
- return hiddenInput.name === assetInputName && hiddenInput.value.trim() !== '';
97
+ return hiddenInput.hasAttribute(HIDDEN_INPUT_VALUE_ATTR)
98
+ || (hiddenInput.name === assetInputName && hiddenInput.value.trim() !== '');
97
99
  });
98
100
  }
99
101
 
@@ -186,7 +188,7 @@ function readSummaryItems(summaryRoot: HTMLElement | null): UploadedAsset[] {
186
188
  function readUploadedAssetsFromHiddenInputs(field: HTMLElement, input: HTMLInputElement): UploadedAsset[] {
187
189
  return getUploadedAssetInputs(field, input).map((hiddenInput) => {
188
190
  return {
189
- assetId: toPositiveInt(hiddenInput.value),
191
+ assetId: toPositiveInt(hiddenInput.getAttribute(HIDDEN_INPUT_VALUE_ATTR)) ?? toPositiveInt(hiddenInput.value),
190
192
  filename: '',
191
193
  };
192
194
  }).filter((asset) => {
@@ -349,21 +351,25 @@ function updateUploadedAssetInputs(field: HTMLElement, input: HTMLInputElement,
349
351
  let insertionPoint: HTMLInputElement = anchor;
350
352
  // The upload event returns persisted asset ids; convert those back into the
351
353
  // hidden-input shape the backend expects on subsequent submit/save actions.
352
- const anchorName = getUploadedAssetInputName(input);
353
- getUploadedAssetInputs(field, input).forEach((hiddenInput) => {
354
+ const baseName = getFileValueName(input);
355
+ getHiddenInputs(field).filter((hiddenInput) => {
356
+ return hiddenInput.hasAttribute(HIDDEN_INPUT_ENTRY_ATTR)
357
+ || (hiddenInput.name === `${baseName}[]` && hiddenInput.value.trim() !== '');
358
+ }).forEach((hiddenInput) => {
354
359
  hiddenInput.remove();
355
360
  });
356
361
 
357
- uploadedAssets.forEach((asset) => {
362
+ uploadedAssets.forEach((asset, index) => {
358
363
  if (!asset.assetId) {
359
364
  return;
360
365
  }
361
366
 
362
367
  const hiddenInput = document.createElement('input');
363
368
  hiddenInput.type = 'hidden';
364
- hiddenInput.name = anchorName;
369
+ hiddenInput.name = `${baseName}[${index}][assetId]`;
365
370
  hiddenInput.value = String(asset.assetId);
366
- hiddenInput.setAttribute(HIDDEN_INPUT_VALUE_ATTR, 'true');
371
+ hiddenInput.setAttribute(HIDDEN_INPUT_ENTRY_ATTR, 'true');
372
+ hiddenInput.setAttribute(HIDDEN_INPUT_VALUE_ATTR, String(asset.assetId));
367
373
  insertionPoint.insertAdjacentElement('afterend', hiddenInput);
368
374
  insertionPoint = hiddenInput;
369
375
  });
@@ -425,6 +431,7 @@ async function hydrateUploadedAssets(field: HTMLElement, input: HTMLInputElement
425
431
 
426
432
  const hydrateEndpoint = input.getAttribute(HYDRATE_ENDPOINT_ATTR)?.trim() || '/actions/formie/file-upload/hydrate';
427
433
  const response = await requestJson<FileUploadHydrateResponse>(hydrateEndpoint, {
434
+ profile: field.closest('form')?.dataset.formieRequestProfile as import('@verbb/formie-core').BrowserRequestOptions['profile'],
428
435
  method: 'POST',
429
436
  body: buildHydrateFormData(field, input, assetIds),
430
437
  });
@@ -657,8 +664,10 @@ function bindFileUploadInput(field: HTMLElement, input: HTMLInputElement, form:
657
664
  };
658
665
  }
659
666
 
660
- export const fileUploadModule: FormieModuleDefinition = {
661
- id: MODULE_ID,
667
+ export const fileUploadModule: BrowserModuleDefinition = {
668
+ moduleId: `formie:${MODULE_ID}`,
669
+ version: 2,
670
+ surfaces: ['server-rendered', 'client-rendered', 'cp-edit'],
662
671
  kind: 'field',
663
672
  match: (ctx) => {
664
673
  return !!ctx.target.querySelector(INPUT_SELECTOR);
@@ -1,4 +1,4 @@
1
- import type { FormieModuleDefinition } from '#contracts/modules';
1
+ import type { BrowserModuleDefinition } from '#contracts/modules';
2
2
  import { getModuleFieldContainers } from '#modules/fields/shared';
3
3
 
4
4
  const INPUT_SELECTOR = 'input[data-formie-hidden-input]';
@@ -22,8 +22,10 @@ function getCookieValue(name: string): string | null {
22
22
  return null;
23
23
  }
24
24
 
25
- export const hiddenModule: FormieModuleDefinition = {
26
- id: 'hidden',
25
+ export const hiddenModule: BrowserModuleDefinition = {
26
+ moduleId: 'formie:hidden',
27
+ version: 2,
28
+ surfaces: ['server-rendered', 'client-rendered', 'cp-edit'],
27
29
  kind: 'field',
28
30
  match: (ctx) => {
29
31
  return !!ctx.target.querySelector(INPUT_SELECTOR);
@@ -1,6 +1,6 @@
1
- import type { FormieModuleDefinition } from '#contracts/modules';
1
+ import type { BrowserModuleDefinition } from '#contracts/modules';
2
2
 
3
- export const builtinFieldModuleLoaders: Record<string, () => Promise<FormieModuleDefinition>> = {
3
+ export const builtinFieldModuleLoaders: Record<string, () => Promise<BrowserModuleDefinition>> = {
4
4
  // Keep the builtin map flat and explicit so manifest ids remain the source of
5
5
  // truth for lazy-loading first-party field enhancements.
6
6
  'calculations': () => import('#modules/fields/calculations').then((module) => module.calculationsModule),
@@ -1,6 +1,6 @@
1
1
  import { getTextLimitMetrics } from '@verbb/formie-core';
2
2
 
3
- import type { FormieModuleDefinition } from '#contracts/modules';
3
+ import type { BrowserModuleDefinition } from '#contracts/modules';
4
4
  import { getModuleFieldTarget, releaseFormValidators, retainFormValidators } from '#modules/fields/shared';
5
5
 
6
6
  const INPUT_SELECTOR = 'input[data-formie-password-input]';
@@ -104,8 +104,10 @@ function unregisterValidators(form: HTMLFormElement | null): void {
104
104
  releaseFormValidators(form, VALIDATOR_SCOPE, PASSWORD_VALIDATORS);
105
105
  }
106
106
 
107
- export const passwordValidationModule: FormieModuleDefinition = {
108
- id: 'password-validation',
107
+ export const passwordValidationModule: BrowserModuleDefinition = {
108
+ moduleId: 'formie:password-validation',
109
+ version: 2,
110
+ surfaces: ['server-rendered', 'client-rendered', 'cp-edit'],
109
111
  kind: 'field',
110
112
  match: (ctx) => {
111
113
  return !!ctx.target.querySelector(`${INPUT_SELECTOR}[data-formie-password-min-length], ${INPUT_SELECTOR}[data-formie-password-require-uppercase], ${INPUT_SELECTOR}[data-formie-password-require-lowercase], ${INPUT_SELECTOR}[data-formie-password-require-special-character]`);
@@ -1,7 +1,7 @@
1
1
  import intlTelInput from 'intl-tel-input';
2
2
  import intlTelInputCss from 'intl-tel-input/styles?inline';
3
3
 
4
- import type { FormieModuleDefinition } from '#contracts/modules';
4
+ import type { BrowserModuleDefinition } from '#contracts/modules';
5
5
  import { dispatchFieldEvent, getModuleFieldContainers, releaseFormValidators, retainFormValidators } from '#modules/fields/shared';
6
6
  import { ensureModuleStyles } from '#modules/styles';
7
7
  import { createGeoIpLookup } from '#utils/country-from-ip';
@@ -81,7 +81,7 @@ function unregisterValidators(form: HTMLFormElement | null): void {
81
81
  releaseFormValidators(form, VALIDATOR_SCOPE, [PHONE_COUNTRY_VALIDATOR]);
82
82
  }
83
83
 
84
- function buildOptions(options: PhoneCountryOptions): Record<string, unknown> {
84
+ function buildOptions(options: PhoneCountryOptions, form: HTMLFormElement | null): Record<string, unknown> {
85
85
  const intlOptions: Record<string, unknown> = {
86
86
  allowDropdown: true,
87
87
  nationalMode: false,
@@ -116,7 +116,7 @@ function buildOptions(options: PhoneCountryOptions): Record<string, unknown> {
116
116
  intlOptions.initialCountry = options.countryDefaultValue.toLowerCase();
117
117
  } else if (options.countryPreselectFromIp) {
118
118
  intlOptions.initialCountry = 'auto';
119
- intlOptions.geoIpLookup = createGeoIpLookup(options.countryFromIpAction);
119
+ intlOptions.geoIpLookup = createGeoIpLookup(options.countryFromIpAction, form);
120
120
  }
121
121
 
122
122
  if (Array.isArray(intlOptions.onlyCountries) && typeof intlOptions.initialCountry === 'string') {
@@ -130,7 +130,7 @@ function buildOptions(options: PhoneCountryOptions): Record<string, unknown> {
130
130
  }
131
131
 
132
132
  function initPhoneField(phoneInput: PhoneInput, countryInput: HTMLInputElement, options: PhoneCountryOptions): () => void {
133
- const intlOptions = buildOptions(options);
133
+ const intlOptions = buildOptions(options, phoneInput.closest('form'));
134
134
 
135
135
  dispatchFieldEvent(phoneInput, MODULE_ID, 'before-init', {
136
136
  phoneCountry: phoneInput,
@@ -163,6 +163,30 @@ function initPhoneField(phoneInput: PhoneInput, countryInput: HTMLInputElement,
163
163
  phoneInput.addEventListener('countrychange', syncCountry);
164
164
  phoneInput.addEventListener('blur', syncCountry);
165
165
  syncCountry();
166
+
167
+ // Keep the country dropdown button in sync when the tel input is enabled/disabled after
168
+ // init (multi-page page-hidden, or conditions). intl-tel-input disables the button to match
169
+ // a disabled input at init, but won't re-enable it when `disabled` is later removed.
170
+ const syncCountryButton = () => {
171
+ const button = phoneInput.closest('.iti')?.querySelector('.iti__selected-country');
172
+
173
+ if (!(button instanceof HTMLElement)) {
174
+ return;
175
+ }
176
+
177
+ if (phoneInput.disabled) {
178
+ button.setAttribute('disabled', 'true');
179
+ } else {
180
+ button.removeAttribute('disabled');
181
+ }
182
+ };
183
+
184
+ syncCountryButton();
185
+ const countryButtonObserver = new MutationObserver(() => {
186
+ syncCountryButton();
187
+ });
188
+ countryButtonObserver.observe(phoneInput, { attributes: true, attributeFilter: ['disabled'] });
189
+
166
190
  debug.log('Initialized.', {
167
191
  inputName: phoneInput.name,
168
192
  restrictedCountries: phoneInput.restrictedCountries,
@@ -177,6 +201,7 @@ function initPhoneField(phoneInput: PhoneInput, countryInput: HTMLInputElement,
177
201
  return () => {
178
202
  phoneInput.removeEventListener('countrychange', syncCountry);
179
203
  phoneInput.removeEventListener('blur', syncCountry);
204
+ countryButtonObserver.disconnect();
180
205
  validator.destroy();
181
206
  delete phoneInput.allowedCountries;
182
207
  delete phoneInput.validator;
@@ -188,8 +213,10 @@ function initPhoneField(phoneInput: PhoneInput, countryInput: HTMLInputElement,
188
213
  };
189
214
  }
190
215
 
191
- export const phoneCountryModule: FormieModuleDefinition = {
192
- id: MODULE_ID,
216
+ export const phoneCountryModule: BrowserModuleDefinition = {
217
+ moduleId: `formie:${MODULE_ID}`,
218
+ version: 2,
219
+ surfaces: ['server-rendered', 'client-rendered', 'cp-edit'],
193
220
  kind: 'field',
194
221
  match: (ctx) => {
195
222
  return !!ctx.target.querySelector(PHONE_SELECTOR);
@@ -1,6 +1,6 @@
1
1
  import repeaterCss from '#theme-css/fields/_repeater.css?inline';
2
2
 
3
- import type { FormieModuleDefinition } from '#contracts/modules';
3
+ import type { BrowserModuleDefinition } from '#contracts/modules';
4
4
  import { dispatchFieldEvent, getTemplateSource, getTemplateSourceHtml } from '#modules/fields/shared';
5
5
  import { ensureModuleStyles } from '#modules/styles';
6
6
  import { sleep } from '#utils/async';
@@ -188,8 +188,10 @@ function bindRepeaterField(field: HTMLElement): () => void {
188
188
  };
189
189
  }
190
190
 
191
- export const repeaterModule: FormieModuleDefinition = {
192
- id: MODULE_ID,
191
+ export const repeaterModule: BrowserModuleDefinition = {
192
+ moduleId: `formie:${MODULE_ID}`,
193
+ version: 2,
194
+ surfaces: ['server-rendered', 'client-rendered', 'cp-edit'],
193
195
  kind: 'field',
194
196
  match: (ctx) => {
195
197
  return ctx.target instanceof HTMLElement && (
@@ -21,7 +21,7 @@ import strikethroughIcon from '#icons/rich-text/strikethrough.svg?raw';
21
21
  import ulistIcon from '#icons/rich-text/ulist.svg?raw';
22
22
  import underlineIcon from '#icons/rich-text/underline.svg?raw';
23
23
 
24
- import type { FormieModuleDefinition } from '#contracts/modules';
24
+ import type { BrowserModuleDefinition } from '#contracts/modules';
25
25
  import { dispatchFieldEvent, getModuleFieldContainers } from '#modules/fields/shared';
26
26
  import { ensureModuleStyles } from '#modules/styles';
27
27
 
@@ -141,7 +141,9 @@ function initRichTextField(container: HTMLElement, input: RichTextInput, options
141
141
  actions: getActions(options.buttons),
142
142
  onChange: (html: string) => {
143
143
  const emptyParagraph = '<p><br></p>';
144
- input.value = input.placeholder && html === emptyParagraph ? '' : html;
144
+ // Treat Pell's empty document as blank so required validation matches
145
+ // a never-touched textarea (and so clearing the editor can fail required).
146
+ input.value = (!html || html === emptyParagraph) ? '' : html;
145
147
  // Bubble both generic input and a namespaced rich-text change hook.
146
148
  input.dispatchEvent(new Event('input', { bubbles: true }));
147
149
  dispatchFieldEvent(input, MODULE_ID, 'populate', {
@@ -166,6 +168,17 @@ function initRichTextField(container: HTMLElement, input: RichTextInput, options
166
168
  input.richText = editor;
167
169
  editor.content.innerHTML = input.value || '';
168
170
 
171
+ const form = input.form;
172
+ const onReset = (event: Event) => {
173
+ // Wait for the textarea to regain its default value before updating Pell.
174
+ queueMicrotask(() => {
175
+ if (!event.defaultPrevented) {
176
+ editor.content.innerHTML = input.value || '';
177
+ }
178
+ });
179
+ };
180
+ form?.addEventListener('reset', onReset);
181
+
169
182
  if (input.placeholder) {
170
183
  editor.content.setAttribute('data-placeholder', input.placeholder);
171
184
  }
@@ -175,13 +188,16 @@ function initRichTextField(container: HTMLElement, input: RichTextInput, options
175
188
  });
176
189
 
177
190
  return () => {
191
+ form?.removeEventListener('reset', onReset);
178
192
  container.innerHTML = '';
179
193
  delete input.richText;
180
194
  };
181
195
  }
182
196
 
183
- export const richTextModule: FormieModuleDefinition = {
184
- id: MODULE_ID,
197
+ export const richTextModule: BrowserModuleDefinition = {
198
+ moduleId: `formie:${MODULE_ID}`,
199
+ version: 2,
200
+ surfaces: ['server-rendered', 'client-rendered', 'cp-edit'],
185
201
  kind: 'field',
186
202
  match: (ctx) => {
187
203
  return ctx.target instanceof HTMLElement && hasRichTextField(ctx.target);
@@ -17,6 +17,19 @@ const fallbackCssEscape = (value: string): string => {
17
17
  };
18
18
  const validatorRegistrations = new WeakMap<HTMLFormElement, Map<string, number>>();
19
19
 
20
+ // Conditions clear ordinary controls directly. Enhanced controls also need to
21
+ // clear their hidden transport values before their modules are unmounted.
22
+ export function bindConditionalClear(input: HTMLElement, clear: () => void): () => void {
23
+ const root = input.getRootNode();
24
+ const handler = (event: Event) => {
25
+ if (event.target instanceof Element && event.target.contains(input)) {
26
+ clear();
27
+ }
28
+ };
29
+ root.addEventListener('formie:field:clear', handler);
30
+ return () => root.removeEventListener('formie:field:clear', handler);
31
+ }
32
+
20
33
  export function escapeSelectorValue(value: string): string {
21
34
  if (typeof window.CSS?.escape === 'function') {
22
35
  return window.CSS.escape(value);
@@ -1,8 +1,8 @@
1
1
  import SignaturePad from 'signature_pad';
2
2
  import signatureCss from '#theme-css/fields/_signature.css?inline';
3
3
 
4
- import type { FormieModuleDefinition } from '#contracts/modules';
5
- import { dispatchFieldEvent, getModuleFieldContainers } from '#modules/fields/shared';
4
+ import type { BrowserModuleDefinition } from '#contracts/modules';
5
+ import { bindConditionalClear, dispatchFieldEvent, getModuleFieldContainers } from '#modules/fields/shared';
6
6
  import { ensureModuleStyles } from '#modules/styles';
7
7
 
8
8
  const INPUT_SELECTOR = 'input[data-formie-signature-input]';
@@ -165,6 +165,8 @@ function initSignatureField(
165
165
  clearButton: HTMLElement | null,
166
166
  options: SignatureOptions,
167
167
  ): () => void {
168
+ const initialValue = input.value;
169
+ const form = input.form;
168
170
  const messages = getSignatureMessages(field);
169
171
 
170
172
  if (!supportsCanvas()) {
@@ -349,6 +351,20 @@ function initSignatureField(
349
351
  syncInputValue('');
350
352
  };
351
353
 
354
+ const onReset = (event: Event) => {
355
+ // Hidden inputs do not restore an earlier value through native reset.
356
+ // Reset both the submitted signature and the pad to their initial state.
357
+ queueMicrotask(() => {
358
+ if (!event.defaultPrevented) {
359
+ signaturePad.clear();
360
+ syncInputValue(initialValue);
361
+ void restoreSignatureValue(signaturePad, canvas, initialValue);
362
+ }
363
+ });
364
+ };
365
+ form?.addEventListener('reset', onReset);
366
+
367
+ const unbindConditionalClear = bindConditionalClear(input, clearSignature);
352
368
  signaturePad.addEventListener('endStroke', syncValue);
353
369
  window.addEventListener('resize', resizeHandler);
354
370
  root.addEventListener('formie:page:navigate:after', pageNavigateHandler as EventListener);
@@ -365,6 +381,8 @@ function initSignatureField(
365
381
 
366
382
  return () => {
367
383
  clearSizeRetry();
384
+ unbindConditionalClear();
385
+ form?.removeEventListener('reset', onReset);
368
386
  signaturePad.removeEventListener('endStroke', syncValue);
369
387
  window.removeEventListener('resize', resizeHandler);
370
388
  root.removeEventListener('formie:page:navigate:after', pageNavigateHandler as EventListener);
@@ -378,8 +396,10 @@ function initSignatureField(
378
396
  };
379
397
  }
380
398
 
381
- export const signatureModule: FormieModuleDefinition = {
382
- id: MODULE_ID,
399
+ export const signatureModule: BrowserModuleDefinition = {
400
+ moduleId: `formie:${MODULE_ID}`,
401
+ version: 2,
402
+ surfaces: ['server-rendered', 'client-rendered', 'cp-edit'],
383
403
  kind: 'field',
384
404
  match: (ctx) => {
385
405
  return !!ctx.target.querySelector(CANVAS_SELECTOR);
@@ -1,6 +1,6 @@
1
1
  import summaryCss from '#theme-css/fields/_summary.css?inline';
2
2
 
3
- import type { FormieModuleDefinition } from '#contracts/modules';
3
+ import type { BrowserModuleDefinition } from '#contracts/modules';
4
4
  import { dispatchFieldEvent, getModuleFieldContainers } from '#modules/fields/shared';
5
5
  import { ensureModuleStyles } from '#modules/styles';
6
6
  import { toggleThemeClasses } from '#theme/theme-classes';
@@ -11,8 +11,6 @@ import { requestText } from '#utils/http';
11
11
  const BLOCKS_SELECTOR = '[data-formie-summary-blocks]';
12
12
  const CONTAINER_SELECTOR = '[data-formie-summary-container]';
13
13
  const SUMMARY_ACTION = 'formie/fields/get-summary-html';
14
- const THEME_CONFIG_ATTR = 'data-formie-theme-config';
15
- const FRONTEND_THEME_ATTR = 'data-formie-frontend-theme';
16
14
  const MODULE_ID = 'summary';
17
15
  const debug = createDebug('fields', 'summary');
18
16
 
@@ -20,8 +18,6 @@ ensureModuleStyles(MODULE_ID, [summaryCss]);
20
18
 
21
19
  type SummaryRequestState = {
22
20
  accessToken: string | null;
23
- themeConfig: string | null;
24
- frontendTheme: string | null;
25
21
  };
26
22
 
27
23
  function getSummaryRequestUrl(): string {
@@ -31,14 +27,12 @@ function getSummaryRequestUrl(): string {
31
27
  return url.toString();
32
28
  }
33
29
 
34
- function getSummaryRequestState(field: HTMLElement, form: HTMLFormElement): SummaryRequestState {
30
+ function getSummaryRequestState(field: HTMLElement): SummaryRequestState {
35
31
  const summaryTokenInput = field.querySelector('[data-formie-summary-token]') as HTMLInputElement | null;
36
32
  const accessToken = summaryTokenInput?.value?.trim() || null;
37
33
 
38
34
  return {
39
35
  accessToken,
40
- themeConfig: form.getAttribute(THEME_CONFIG_ATTR)?.trim() || null,
41
- frontendTheme: form.getAttribute(FRONTEND_THEME_ATTR)?.trim() || null,
42
36
  };
43
37
  }
44
38
 
@@ -53,14 +47,6 @@ async function requestSummaryHtml(form: HTMLFormElement, state: SummaryRequestSt
53
47
  formData.set('action', SUMMARY_ACTION);
54
48
  formData.set('accessToken', state.accessToken);
55
49
 
56
- if (state.themeConfig) {
57
- formData.set('themeConfig', state.themeConfig);
58
- }
59
-
60
- if (state.frontendTheme) {
61
- formData.set('frontendTheme', state.frontendTheme);
62
- }
63
-
64
50
  return requestText(getSummaryRequestUrl(), {
65
51
  method: 'POST',
66
52
  body: formData,
@@ -115,7 +101,7 @@ function initSummaryField(field: HTMLElement, root: Element): () => void {
115
101
  toggleThemeClasses(blocks, form, 'loading', false);
116
102
  };
117
103
 
118
- const initialState = getSummaryRequestState(field, form);
104
+ const initialState = getSummaryRequestState(field);
119
105
  setLoadingState(!!initialState.accessToken);
120
106
 
121
107
  const queueFetch = (): void => {
@@ -128,7 +114,7 @@ function initSummaryField(field: HTMLElement, root: Element): () => void {
128
114
  };
129
115
 
130
116
  const fetchSummary = debounce(async() => {
131
- const state = getSummaryRequestState(field, form);
117
+ const state = getSummaryRequestState(field);
132
118
 
133
119
  if (!getBlocks() || !state.accessToken) {
134
120
  debug.warn('Missing state for fetch.', state);
@@ -256,8 +242,10 @@ function initSummaryField(field: HTMLElement, root: Element): () => void {
256
242
  };
257
243
  }
258
244
 
259
- export const summaryModule: FormieModuleDefinition = {
260
- id: MODULE_ID,
245
+ export const summaryModule: BrowserModuleDefinition = {
246
+ moduleId: `formie:${MODULE_ID}`,
247
+ version: 2,
248
+ surfaces: ['server-rendered', 'client-rendered', 'cp-edit'],
261
249
  kind: 'field',
262
250
  match: (ctx) => {
263
251
  return !!ctx.target.querySelector(BLOCKS_SELECTOR);
@@ -1,6 +1,6 @@
1
1
  import surveyPresentationsCss from '#theme-css/fields/_survey-presentations.css?inline';
2
2
 
3
- import type { FormieModuleDefinition } from '#contracts/modules';
3
+ import type { BrowserModuleDefinition } from '#contracts/modules';
4
4
  import { ensureModuleStyles } from '#modules/styles';
5
5
  import { createDebug } from '#utils/debug';
6
6
 
@@ -10,8 +10,10 @@ const debug = createDebug('fields', 'survey-likert');
10
10
 
11
11
  ensureModuleStyles(MODULE_ID, [surveyPresentationsCss]);
12
12
 
13
- export const surveyLikertModule: FormieModuleDefinition = {
14
- id: MODULE_ID,
13
+ export const surveyLikertModule: BrowserModuleDefinition = {
14
+ moduleId: `formie:${MODULE_ID}`,
15
+ version: 2,
16
+ surfaces: ['server-rendered', 'client-rendered', 'cp-edit'],
15
17
  kind: 'field',
16
18
  match: (ctx) => {
17
19
  return ctx.target instanceof HTMLElement && (
@@ -1,6 +1,6 @@
1
1
  import surveyPresentationsCss from '#theme-css/fields/_survey-presentations.css?inline';
2
2
 
3
- import type { FormieModuleDefinition } from '#contracts/modules';
3
+ import type { BrowserModuleDefinition } from '#contracts/modules';
4
4
  import { dispatchFieldEvent } from '#modules/fields/shared';
5
5
  import { ensureModuleStyles } from '#modules/styles';
6
6
  import { createDebug } from '#utils/debug';
@@ -183,6 +183,8 @@ function bindRankField(field: HTMLElement): () => void {
183
183
  return () => {};
184
184
  }
185
185
 
186
+ const initialItems = getRankItems(list);
187
+ const form = field.closest('form');
186
188
  let draggedItem: HTMLElement | null = null;
187
189
  let placeholder: HTMLElement | null = null;
188
190
  let ghostStyleSnapshot: GhostStyleSnapshot | null = null;
@@ -325,9 +327,23 @@ function bindRankField(field: HTMLElement): () => void {
325
327
  });
326
328
  });
327
329
 
330
+ const onReset = (event: Event) => {
331
+ queueMicrotask(() => {
332
+ if (!event.defaultPrevented) {
333
+ document.removeEventListener('pointermove', onPointerMove);
334
+ document.removeEventListener('pointerup', onPointerUp);
335
+ document.removeEventListener('pointercancel', onPointerUp);
336
+ finishDrag();
337
+ initialItems.forEach((item) => list.appendChild(item));
338
+ syncRankInputs(list);
339
+ }
340
+ });
341
+ };
342
+ form?.addEventListener('reset', onReset);
328
343
  syncRankInputs(list);
329
344
 
330
345
  return () => {
346
+ form?.removeEventListener('reset', onReset);
331
347
  document.removeEventListener('pointermove', onPointerMove);
332
348
  document.removeEventListener('pointerup', onPointerUp);
333
349
  document.removeEventListener('pointercancel', onPointerUp);
@@ -338,8 +354,10 @@ function bindRankField(field: HTMLElement): () => void {
338
354
  };
339
355
  }
340
356
 
341
- export const surveyRankModule: FormieModuleDefinition = {
342
- id: MODULE_ID,
357
+ export const surveyRankModule: BrowserModuleDefinition = {
358
+ moduleId: `formie:${MODULE_ID}`,
359
+ version: 2,
360
+ surfaces: ['server-rendered', 'client-rendered', 'cp-edit'],
343
361
  kind: 'field',
344
362
  match: (ctx) => {
345
363
  return ctx.target instanceof HTMLElement && (