@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.
- package/CHANGELOG.md +50 -0
- package/dist/chunks/{address-country-Rx6GQTND.js → address-country-Dn71jroa.js} +10 -4
- package/dist/chunks/{address-finder-k7_BXaRe.js → address-finder-O49uDRoR.js} +2 -2
- package/dist/chunks/{address-state-BwE01m2_.js → address-state-ByYatUur.js} +154 -143
- package/dist/chunks/{api-DqpfkZWL.js → api-D6kJ7kXZ.js} +183 -179
- package/dist/chunks/{api-BUb6P-xu.js → api-DYYsVIub.js} +77 -47
- package/dist/chunks/{api-sPqGbOww.js → api-ghNr2uxX.js} +15 -9
- package/dist/chunks/{bpoint-Dlq34XH1.js → bpoint-D0RKFM4F.js} +3 -3
- package/dist/chunks/calculations-YEoVCG2q.js +310 -0
- package/dist/chunks/{captcha-eu-CGm8Lbrj.js → captcha-eu-DERJbXnH.js} +5 -4
- package/dist/chunks/{checkbox-radio-BY2aTCOG.js → checkbox-radio-gsm8QPJg.js} +74 -75
- package/dist/chunks/{combobox-C0EuExSI.js → combobox-CWNdx4Fk.js} +290 -279
- package/dist/chunks/conditions-DqNHLTbN.js +464 -0
- package/dist/chunks/country-from-ip-DDj_mFki.js +29 -0
- package/dist/chunks/csrf-DxHg_ZYt.js +61 -0
- package/dist/chunks/{custom-google-maps-BsaSirEZ.js → custom-google-maps-C4l2S3GO.js} +9 -3
- package/dist/chunks/{custom-link-CJ1-FjEM.js → custom-link-CLazgKYH.js} +8 -2
- package/dist/chunks/{custom-maps-DYW_pBid.js → custom-maps-DqcAlD0v.js} +10 -4
- package/dist/chunks/{date-picker-F9BUBDSW.js → date-picker-RUnevF7l.js} +455 -432
- package/dist/chunks/{dist-D6i-VNgM.js → dist-ZLeW0zZ3.js} +1281 -453
- package/dist/chunks/{eway-D9_m8ooj.js → eway-or6dtjoT.js} +3 -3
- package/dist/chunks/field-references.resolver-Ca8MguFv.js +104 -0
- package/dist/chunks/{file-upload-rqfZNqlH.js → file-upload-Bm-TXyNB.js} +104 -96
- package/dist/chunks/friendly-captcha-v1-GFqCt1Mh.js +34 -0
- package/dist/chunks/{friendly-captcha-v2-CLSAbkqx.js → friendly-captcha-v2-WoW246JG.js} +6 -5
- package/dist/chunks/{friendly-challenge-8uPatWqk.js → friendly-challenge-DPG9MJb1.js} +111 -102
- package/dist/chunks/{go-cardless-DAT3ZaQf.js → go-cardless-DzJ-0FKg.js} +2 -2
- package/dist/chunks/google-address-C1P1nTDM.js +163 -0
- package/dist/chunks/{hcaptcha-CGLAmgjO.js → hcaptcha-D0T8aIHz.js} +3 -3
- package/dist/chunks/{hidden-D7_Ch-QN.js → hidden-BZhXnNPe.js} +8 -2
- package/dist/chunks/http-C2QdHuWO.js +27 -0
- package/dist/chunks/{leaflet-src-j-lHNmhR.js → leaflet-src-DE6rv6M-.js} +42 -46
- package/dist/chunks/{loqate-CJPzBmSm.js → loqate-DD1S7PY9.js} +2 -2
- package/dist/chunks/{mollie-Bibhl67p.js → mollie-DG8Ju83x.js} +2 -2
- package/dist/chunks/{moneris-H2wSqk9h.js → moneris-C8m3Fvqu.js} +3 -3
- package/dist/chunks/opayo-B3EvrVxw.js +188 -0
- package/dist/chunks/{paddle-DkvIxQdG.js → paddle-BIYR9Um3.js} +3 -3
- package/dist/chunks/{password-validation-D06uH9va.js → password-validation-C8_uO_c_.js} +18 -12
- package/dist/chunks/{paypal-CQpAF7Ua.js → paypal-B_yxIo2d.js} +7 -5
- package/dist/chunks/{payway-CwDkC7YZ.js → payway-CeOzS0sL.js} +3 -3
- package/dist/chunks/{phone-country-D3ayr60L.js → phone-country-bAqje17P.js} +80 -63
- package/dist/chunks/{place-kit-BGHklIZ-.js → place-kit-BE5gi3vo.js} +3 -3
- package/dist/chunks/{placekit-autocomplete.esm-DWVabQlq.js → placekit-autocomplete.esm-CZZERYur.js} +11 -15
- package/dist/chunks/{recaptcha-enterprise-XPId5-bS.js → recaptcha-enterprise-CruXddZq.js} +4 -4
- package/dist/chunks/{recaptcha-shared-CLYJvojk.js → recaptcha-shared-AQRMDMme.js} +1 -1
- package/dist/chunks/{recaptcha-v2-checkbox-Cy-0PEPc.js → recaptcha-v2-checkbox-CCnJYCnG.js} +4 -4
- package/dist/chunks/{recaptcha-v2-invisible-BwRH540O.js → recaptcha-v2-invisible-BuVqRRYn.js} +4 -4
- package/dist/chunks/{recaptcha-v3-No4Ykrhk.js → recaptcha-v3-CloqhO2A.js} +4 -4
- package/dist/chunks/{repeater-BVnPUqTj.js → repeater-DwE27jI1.js} +25 -19
- package/dist/chunks/request-profile-DhwkeCpS.js +10 -0
- package/dist/chunks/rich-text-uV4o_pGk.js +361 -0
- package/dist/chunks/{chunk-3b4jIN3o.js → rolldown-runtime-DtPi1Y-2.js} +2 -2
- package/dist/chunks/{sdk-BhHAYgga.js → sdk-lkwSvlpM.js} +282 -234
- package/dist/chunks/{shared-Bx9s0i0P.js → shared-OKhSay59.js} +27 -21
- package/dist/chunks/{signature-IOhuicje.js → signature-7cldFbqj.js} +138 -112
- package/dist/chunks/{snaptcha-DKx98oon.js → snaptcha-C04kNGYQ.js} +2 -2
- package/dist/chunks/{square-DwdcOI1G.js → square-DEzxv9D9.js} +8 -6
- package/dist/chunks/{stripe-DaoG2FT1.js → stripe-CVPQGDz3.js} +10 -11
- package/dist/chunks/{summary-Dks0gXS3.js → summary-BF_8mrXI.js} +47 -45
- package/dist/chunks/{survey-likert-DkE6bR7B.js → survey-likert-fk1hUPff.js} +7 -1
- package/dist/chunks/{survey-rank-DN6x4IZM.js → survey-rank-BsLGl2LX.js} +37 -25
- package/dist/chunks/{survey-rating-BnsNL9U5.js → survey-rating-DVS6e6fM.js} +17 -5
- package/dist/chunks/{table-CAjCJHrL.js → table-DnIBdeKF.js} +21 -15
- package/dist/chunks/{text-limit-BGaY0jhI.js → text-limit-LGMPhFuC.js} +40 -34
- package/dist/chunks/{theme-classes-Tv7q7ToE.js → theme-classes-DAQuEqdP.js} +1 -1
- package/dist/chunks/{turnstile-DJakPzQD.js → turnstile-n9DNyPxi.js} +3 -3
- package/dist/chunks/{upload-manager-W-QDgxKD.js → upload-manager-BbiUosZq.js} +410 -350
- package/dist/chunks/{utils-Vqp8i_RM.js → utils-DpUBPadZ.js} +20 -14
- package/dist/css/formie-base.css +104 -1
- package/dist/css/theme/_messages.css +2 -0
- package/dist/css/theme/_tokens.css +31 -25
- package/dist/css/theme/forms/_form.css +5 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1778 -1427
- package/dist/js/contracts/client.d.ts +5 -3
- package/dist/js/contracts/client.d.ts.map +1 -1
- package/dist/js/contracts/common.d.ts +2 -2
- package/dist/js/contracts/common.d.ts.map +1 -1
- package/dist/js/contracts/modules.d.ts +37 -12
- package/dist/js/contracts/modules.d.ts.map +1 -1
- package/dist/js/contracts/schema.d.ts +20 -38
- package/dist/js/contracts/schema.d.ts.map +1 -1
- package/dist/js/contracts/theme.d.ts +4 -1
- package/dist/js/contracts/theme.d.ts.map +1 -1
- package/dist/js/core/client-rendered-modules.d.ts +17 -0
- package/dist/js/core/client-rendered-modules.d.ts.map +1 -0
- package/dist/js/core/create-formie-client.d.ts.map +1 -1
- package/dist/js/core/field-error-aria.d.ts +23 -0
- package/dist/js/core/field-error-aria.d.ts.map +1 -0
- package/dist/js/core/hydrate-modules.d.ts +10 -8
- package/dist/js/core/hydrate-modules.d.ts.map +1 -1
- package/dist/js/core/submit-result-state.d.ts.map +1 -1
- package/dist/js/core/submit-result-ui.d.ts.map +1 -1
- package/dist/js/core/validation-focus.d.ts.map +1 -1
- package/dist/js/modules/address/address-finder.d.ts +1 -1
- package/dist/js/modules/address/address-finder.d.ts.map +1 -1
- package/dist/js/modules/address/factories.d.ts +3 -3
- package/dist/js/modules/address/factories.d.ts.map +1 -1
- package/dist/js/modules/address/google-address.d.ts +2 -1
- package/dist/js/modules/address/google-address.d.ts.map +1 -1
- package/dist/js/modules/address/index.d.ts +2 -2
- package/dist/js/modules/address/index.d.ts.map +1 -1
- package/dist/js/modules/address/loqate.d.ts +1 -1
- package/dist/js/modules/address/loqate.d.ts.map +1 -1
- package/dist/js/modules/address/place-kit.d.ts +1 -1
- package/dist/js/modules/address/place-kit.d.ts.map +1 -1
- package/dist/js/modules/captchas/captcha-eu.d.ts +1 -1
- package/dist/js/modules/captchas/captcha-eu.d.ts.map +1 -1
- package/dist/js/modules/captchas/factories.d.ts +11 -11
- package/dist/js/modules/captchas/factories.d.ts.map +1 -1
- package/dist/js/modules/captchas/friendly-captcha-v1.d.ts +1 -1
- package/dist/js/modules/captchas/friendly-captcha-v1.d.ts.map +1 -1
- package/dist/js/modules/captchas/friendly-captcha-v2.d.ts +1 -1
- package/dist/js/modules/captchas/friendly-captcha-v2.d.ts.map +1 -1
- package/dist/js/modules/captchas/hcaptcha.d.ts +1 -1
- package/dist/js/modules/captchas/hcaptcha.d.ts.map +1 -1
- package/dist/js/modules/captchas/index.d.ts +2 -2
- package/dist/js/modules/captchas/index.d.ts.map +1 -1
- package/dist/js/modules/captchas/recaptcha-enterprise.d.ts +1 -1
- package/dist/js/modules/captchas/recaptcha-enterprise.d.ts.map +1 -1
- package/dist/js/modules/captchas/recaptcha-v2-checkbox.d.ts +1 -1
- package/dist/js/modules/captchas/recaptcha-v2-checkbox.d.ts.map +1 -1
- package/dist/js/modules/captchas/recaptcha-v2-invisible.d.ts +1 -1
- package/dist/js/modules/captchas/recaptcha-v2-invisible.d.ts.map +1 -1
- package/dist/js/modules/captchas/recaptcha-v3.d.ts +1 -1
- package/dist/js/modules/captchas/recaptcha-v3.d.ts.map +1 -1
- package/dist/js/modules/captchas/snaptcha.d.ts +1 -1
- package/dist/js/modules/captchas/snaptcha.d.ts.map +1 -1
- package/dist/js/modules/captchas/turnstile.d.ts +1 -1
- package/dist/js/modules/captchas/turnstile.d.ts.map +1 -1
- package/dist/js/modules/fields/address-country.d.ts +2 -2
- package/dist/js/modules/fields/address-country.d.ts.map +1 -1
- package/dist/js/modules/fields/address-state.d.ts +2 -2
- package/dist/js/modules/fields/address-state.d.ts.map +1 -1
- package/dist/js/modules/fields/calculations.d.ts +2 -2
- package/dist/js/modules/fields/calculations.d.ts.map +1 -1
- package/dist/js/modules/fields/checkbox-radio.d.ts +2 -2
- package/dist/js/modules/fields/checkbox-radio.d.ts.map +1 -1
- package/dist/js/modules/fields/combobox.d.ts +2 -2
- package/dist/js/modules/fields/combobox.d.ts.map +1 -1
- package/dist/js/modules/fields/conditions/config.d.ts.map +1 -1
- package/dist/js/modules/fields/conditions/effects.d.ts +1 -0
- package/dist/js/modules/fields/conditions/effects.d.ts.map +1 -1
- package/dist/js/modules/fields/conditions/evaluator.d.ts +4 -1
- package/dist/js/modules/fields/conditions/evaluator.d.ts.map +1 -1
- package/dist/js/modules/fields/conditions/references.d.ts.map +1 -1
- package/dist/js/modules/fields/conditions/submission-context.d.ts +15 -0
- package/dist/js/modules/fields/conditions/submission-context.d.ts.map +1 -0
- package/dist/js/modules/fields/conditions/types.d.ts +3 -1
- package/dist/js/modules/fields/conditions/types.d.ts.map +1 -1
- package/dist/js/modules/fields/conditions/values.d.ts +1 -1
- package/dist/js/modules/fields/conditions/values.d.ts.map +1 -1
- package/dist/js/modules/fields/conditions.d.ts +2 -2
- package/dist/js/modules/fields/conditions.d.ts.map +1 -1
- package/dist/js/modules/fields/custom-google-maps.d.ts +2 -2
- package/dist/js/modules/fields/custom-google-maps.d.ts.map +1 -1
- package/dist/js/modules/fields/custom-link.d.ts +2 -2
- package/dist/js/modules/fields/custom-link.d.ts.map +1 -1
- package/dist/js/modules/fields/custom-maps.d.ts +2 -2
- package/dist/js/modules/fields/custom-maps.d.ts.map +1 -1
- package/dist/js/modules/fields/date-picker.d.ts +2 -2
- package/dist/js/modules/fields/date-picker.d.ts.map +1 -1
- package/dist/js/modules/fields/file-upload.d.ts +2 -2
- package/dist/js/modules/fields/file-upload.d.ts.map +1 -1
- package/dist/js/modules/fields/hidden.d.ts +2 -2
- package/dist/js/modules/fields/hidden.d.ts.map +1 -1
- package/dist/js/modules/fields/index.d.ts +2 -2
- package/dist/js/modules/fields/index.d.ts.map +1 -1
- package/dist/js/modules/fields/password-validation.d.ts +2 -2
- package/dist/js/modules/fields/password-validation.d.ts.map +1 -1
- package/dist/js/modules/fields/phone-country.d.ts +2 -2
- package/dist/js/modules/fields/phone-country.d.ts.map +1 -1
- package/dist/js/modules/fields/repeater.d.ts +2 -2
- package/dist/js/modules/fields/repeater.d.ts.map +1 -1
- package/dist/js/modules/fields/rich-text.d.ts +2 -2
- package/dist/js/modules/fields/rich-text.d.ts.map +1 -1
- package/dist/js/modules/fields/shared.d.ts +1 -0
- package/dist/js/modules/fields/shared.d.ts.map +1 -1
- package/dist/js/modules/fields/signature.d.ts +2 -2
- package/dist/js/modules/fields/signature.d.ts.map +1 -1
- package/dist/js/modules/fields/summary.d.ts +2 -2
- package/dist/js/modules/fields/summary.d.ts.map +1 -1
- package/dist/js/modules/fields/survey-likert.d.ts +2 -2
- package/dist/js/modules/fields/survey-likert.d.ts.map +1 -1
- package/dist/js/modules/fields/survey-rank.d.ts +2 -2
- package/dist/js/modules/fields/survey-rank.d.ts.map +1 -1
- package/dist/js/modules/fields/survey-rating.d.ts +2 -2
- package/dist/js/modules/fields/survey-rating.d.ts.map +1 -1
- package/dist/js/modules/fields/table.d.ts +2 -2
- package/dist/js/modules/fields/table.d.ts.map +1 -1
- package/dist/js/modules/fields/text-limit.d.ts +2 -2
- package/dist/js/modules/fields/text-limit.d.ts.map +1 -1
- package/dist/js/modules/fields/upload-manager.d.ts +2 -2
- package/dist/js/modules/fields/upload-manager.d.ts.map +1 -1
- package/dist/js/modules/loader.d.ts +10 -4
- package/dist/js/modules/loader.d.ts.map +1 -1
- package/dist/js/modules/payments/bpoint.d.ts +1 -1
- package/dist/js/modules/payments/bpoint.d.ts.map +1 -1
- package/dist/js/modules/payments/eway.d.ts +1 -1
- package/dist/js/modules/payments/eway.d.ts.map +1 -1
- package/dist/js/modules/payments/factories.d.ts +7 -7
- package/dist/js/modules/payments/factories.d.ts.map +1 -1
- package/dist/js/modules/payments/go-cardless.d.ts +1 -1
- package/dist/js/modules/payments/go-cardless.d.ts.map +1 -1
- package/dist/js/modules/payments/index.d.ts +2 -2
- package/dist/js/modules/payments/index.d.ts.map +1 -1
- package/dist/js/modules/payments/mollie.d.ts +1 -1
- package/dist/js/modules/payments/mollie.d.ts.map +1 -1
- package/dist/js/modules/payments/moneris.d.ts +1 -1
- package/dist/js/modules/payments/moneris.d.ts.map +1 -1
- package/dist/js/modules/payments/opayo.d.ts +1 -1
- package/dist/js/modules/payments/opayo.d.ts.map +1 -1
- package/dist/js/modules/payments/paddle.d.ts +1 -1
- package/dist/js/modules/payments/paddle.d.ts.map +1 -1
- package/dist/js/modules/payments/paypal.d.ts +1 -1
- package/dist/js/modules/payments/paypal.d.ts.map +1 -1
- package/dist/js/modules/payments/payway.d.ts +1 -1
- package/dist/js/modules/payments/payway.d.ts.map +1 -1
- package/dist/js/modules/payments/square.d.ts +1 -1
- package/dist/js/modules/payments/square.d.ts.map +1 -1
- package/dist/js/modules/payments/stripe.d.ts +1 -1
- package/dist/js/modules/payments/stripe.d.ts.map +1 -1
- package/dist/js/modules/payments/utils.d.ts +6 -0
- package/dist/js/modules/payments/utils.d.ts.map +1 -1
- package/dist/js/modules/registry.d.ts +6 -4
- package/dist/js/modules/registry.d.ts.map +1 -1
- package/dist/js/submit/pipeline.d.ts.map +1 -1
- package/dist/js/theme/browser-theme-state.generated.d.ts +24 -0
- package/dist/js/theme/browser-theme-state.generated.d.ts.map +1 -0
- package/dist/js/theme/theme-classes.d.ts +3 -3
- package/dist/js/theme/theme-classes.d.ts.map +1 -1
- package/dist/js/transport/forms-api.d.ts +5 -3
- package/dist/js/transport/forms-api.d.ts.map +1 -1
- package/dist/js/utils/country-from-ip.d.ts +2 -2
- package/dist/js/utils/country-from-ip.d.ts.map +1 -1
- package/dist/js/utils/csrf.d.ts +17 -0
- package/dist/js/utils/csrf.d.ts.map +1 -0
- package/dist/js/utils/field-references.parser.d.ts +1 -0
- package/dist/js/utils/field-references.parser.d.ts.map +1 -1
- package/dist/js/utils/field-references.resolver.d.ts.map +1 -1
- package/dist/js/utils/field-references.types.d.ts +1 -0
- package/dist/js/utils/field-references.types.d.ts.map +1 -1
- package/dist/js/utils/http.d.ts +3 -1
- package/dist/js/utils/http.d.ts.map +1 -1
- package/dist/js/utils/request-profile.d.ts +4 -0
- package/dist/js/utils/request-profile.d.ts.map +1 -0
- package/dist/js/utils/unload-warning.d.ts.map +1 -1
- package/dist/js/validation/rules/email.d.ts.map +1 -1
- package/dist/js/validation/rules/match.d.ts.map +1 -1
- package/dist/js/validation/rules/number.d.ts.map +1 -1
- package/dist/js/validation/rules/required.d.ts.map +1 -1
- package/dist/js/validation/rules/shared.d.ts.map +1 -1
- package/dist/js/validation/rules/url.d.ts.map +1 -1
- package/dist/js/validation/skip.d.ts +7 -0
- package/dist/js/validation/skip.d.ts.map +1 -0
- package/dist/js/validation/submit-readiness.d.ts.map +1 -1
- package/dist/js/validation/validator.d.ts.map +1 -1
- package/package.json +43 -12
- package/src/css/formie-base.css +104 -1
- package/src/css/theme/_messages.css +2 -0
- package/src/css/theme/_tokens.css +31 -25
- package/src/css/theme/forms/_form.css +5 -1
- package/src/index.ts +13 -8
- package/src/js/contracts/client.ts +5 -3
- package/src/js/contracts/common.ts +5 -6
- package/src/js/contracts/modules.ts +41 -12
- package/src/js/contracts/schema.ts +21 -43
- package/src/js/contracts/theme.ts +6 -1
- package/src/js/core/client-rendered-modules.ts +69 -0
- package/src/js/core/create-formie-client.ts +116 -77
- package/src/js/core/field-error-aria.ts +93 -0
- package/src/js/core/hydrate-modules.ts +54 -29
- package/src/js/core/submit-result-state.ts +34 -45
- package/src/js/core/submit-result-ui.ts +21 -65
- package/src/js/core/validation-focus.ts +20 -20
- package/src/js/modules/address/address-finder.ts +1 -1
- package/src/js/modules/address/factories.ts +15 -13
- package/src/js/modules/address/google-address.ts +10 -6
- package/src/js/modules/address/index.ts +2 -2
- package/src/js/modules/address/loqate.ts +1 -1
- package/src/js/modules/address/place-kit.ts +1 -1
- package/src/js/modules/captchas/captcha-eu.ts +2 -2
- package/src/js/modules/captchas/factories.ts +66 -42
- package/src/js/modules/captchas/friendly-captcha-v1.ts +12 -2
- package/src/js/modules/captchas/friendly-captcha-v2.ts +4 -2
- package/src/js/modules/captchas/hcaptcha.ts +5 -5
- package/src/js/modules/captchas/index.ts +2 -2
- package/src/js/modules/captchas/recaptcha-enterprise.ts +2 -2
- package/src/js/modules/captchas/recaptcha-v2-checkbox.ts +3 -3
- package/src/js/modules/captchas/recaptcha-v2-invisible.ts +2 -2
- package/src/js/modules/captchas/recaptcha-v3.ts +2 -2
- package/src/js/modules/captchas/snaptcha.ts +1 -1
- package/src/js/modules/captchas/turnstile.ts +3 -3
- package/src/js/modules/fields/address-country.ts +6 -4
- package/src/js/modules/fields/address-state.ts +20 -12
- package/src/js/modules/fields/calculations.ts +5 -3
- package/src/js/modules/fields/checkbox-radio.ts +24 -42
- package/src/js/modules/fields/combobox.ts +25 -9
- package/src/js/modules/fields/conditions/config.ts +17 -20
- package/src/js/modules/fields/conditions/effects.ts +23 -26
- package/src/js/modules/fields/conditions/evaluator.ts +21 -29
- package/src/js/modules/fields/conditions/references.ts +16 -5
- package/src/js/modules/fields/conditions/submission-context.ts +80 -0
- package/src/js/modules/fields/conditions/types.ts +3 -1
- package/src/js/modules/fields/conditions/values.ts +31 -6
- package/src/js/modules/fields/conditions.ts +59 -18
- package/src/js/modules/fields/custom-google-maps.ts +5 -3
- package/src/js/modules/fields/custom-link.ts +5 -3
- package/src/js/modules/fields/custom-maps.ts +5 -3
- package/src/js/modules/fields/date-picker.ts +34 -4
- package/src/js/modules/fields/file-upload.ts +19 -10
- package/src/js/modules/fields/hidden.ts +5 -3
- package/src/js/modules/fields/index.ts +2 -2
- package/src/js/modules/fields/password-validation.ts +5 -3
- package/src/js/modules/fields/phone-country.ts +33 -6
- package/src/js/modules/fields/repeater.ts +5 -3
- package/src/js/modules/fields/rich-text.ts +20 -4
- package/src/js/modules/fields/shared.ts +13 -0
- package/src/js/modules/fields/signature.ts +24 -4
- package/src/js/modules/fields/summary.ts +8 -20
- package/src/js/modules/fields/survey-likert.ts +5 -3
- package/src/js/modules/fields/survey-rank.ts +21 -3
- package/src/js/modules/fields/survey-rating.ts +17 -3
- package/src/js/modules/fields/table.ts +5 -3
- package/src/js/modules/fields/text-limit.ts +5 -3
- package/src/js/modules/fields/upload-manager.ts +190 -49
- package/src/js/modules/loader.ts +345 -281
- package/src/js/modules/payments/bpoint.ts +2 -2
- package/src/js/modules/payments/eway.ts +2 -2
- package/src/js/modules/payments/factories.ts +53 -52
- package/src/js/modules/payments/go-cardless.ts +1 -1
- package/src/js/modules/payments/index.ts +2 -2
- package/src/js/modules/payments/mollie.ts +1 -1
- package/src/js/modules/payments/moneris.ts +2 -2
- package/src/js/modules/payments/opayo.ts +21 -8
- package/src/js/modules/payments/paddle.ts +10 -6
- package/src/js/modules/payments/payment.ts +22 -18
- package/src/js/modules/payments/paypal.ts +1 -1
- package/src/js/modules/payments/payway.ts +2 -2
- package/src/js/modules/payments/square.ts +2 -2
- package/src/js/modules/payments/stripe.ts +5 -5
- package/src/js/modules/payments/utils.ts +14 -0
- package/src/js/modules/registry.ts +19 -11
- package/src/js/submit/pipeline.ts +10 -11
- package/src/js/theme/browser-theme-state.generated.ts +25 -0
- package/src/js/theme/theme-classes.ts +3 -3
- package/src/js/transport/forms-api.ts +66 -67
- package/src/js/utils/country-from-ip.ts +14 -9
- package/src/js/utils/csrf.ts +136 -0
- package/src/js/utils/field-references.parser.ts +13 -113
- package/src/js/utils/field-references.resolver.ts +27 -64
- package/src/js/utils/field-references.row-scope.ts +1 -1
- package/src/js/utils/field-references.types.ts +1 -0
- package/src/js/utils/http.ts +5 -5
- package/src/js/utils/request-profile.ts +10 -0
- package/src/js/utils/unload-warning.ts +12 -4
- package/src/js/validation/rules/email.ts +3 -5
- package/src/js/validation/rules/match.ts +2 -1
- package/src/js/validation/rules/minmax.ts +4 -43
- package/src/js/validation/rules/number.ts +3 -47
- package/src/js/validation/rules/pattern.ts +3 -8
- package/src/js/validation/rules/required.ts +2 -1
- package/src/js/validation/rules/shared.ts +5 -1
- package/src/js/validation/rules/url.ts +3 -10
- package/src/js/validation/skip.ts +9 -0
- package/src/js/validation/submit-readiness.ts +9 -2
- package/src/js/validation/validator.ts +35 -59
- package/dist/chunks/calculations-Dv3hYb8_.js +0 -299
- package/dist/chunks/conditions-CPH1snCx.js +0 -424
- package/dist/chunks/country-from-ip-BwxKaBuJ.js +0 -26
- package/dist/chunks/field-references.resolver-CHwn0G0L.js +0 -145
- package/dist/chunks/friendly-captcha-v1-C_2reOXr.js +0 -31
- package/dist/chunks/google-address-BH3Zhi06.js +0 -161
- package/dist/chunks/http-D-JExro7.js +0 -27
- package/dist/chunks/opayo-CR0DtsLa.js +0 -179
- package/dist/chunks/rich-text-Bg_--4TG.js +0 -349
- package/dist/js/modules/fields/conditions/transforms.d.ts +0 -3
- package/dist/js/modules/fields/conditions/transforms.d.ts.map +0 -1
- package/src/js/modules/fields/conditions/transforms.ts +0 -206
- 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 {
|
|
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:
|
|
332
|
-
|
|
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 {
|
|
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.
|
|
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
|
|
353
|
-
|
|
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 =
|
|
369
|
+
hiddenInput.name = `${baseName}[${index}][assetId]`;
|
|
365
370
|
hiddenInput.value = String(asset.assetId);
|
|
366
|
-
hiddenInput.setAttribute(
|
|
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:
|
|
661
|
-
|
|
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 {
|
|
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:
|
|
26
|
-
|
|
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 {
|
|
1
|
+
import type { BrowserModuleDefinition } from '#contracts/modules';
|
|
2
2
|
|
|
3
|
-
export const builtinFieldModuleLoaders: Record<string, () => Promise<
|
|
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 {
|
|
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:
|
|
108
|
-
|
|
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 {
|
|
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:
|
|
192
|
-
|
|
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 {
|
|
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:
|
|
192
|
-
|
|
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 {
|
|
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
|
-
|
|
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:
|
|
184
|
-
|
|
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 {
|
|
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:
|
|
382
|
-
|
|
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 {
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
260
|
-
|
|
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 {
|
|
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:
|
|
14
|
-
|
|
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 {
|
|
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:
|
|
342
|
-
|
|
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 && (
|