@verbb/formie-browser 1.0.0 → 1.0.2

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 (120) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/chunks/address-finder-CQW81kY0.js +37 -0
  3. package/dist/chunks/bpoint-D8OjLmsn.js +26 -0
  4. package/dist/chunks/calculations-BqZsENCq.js +147 -0
  5. package/dist/chunks/captcha-eu-DIa6aUWz.js +34 -0
  6. package/dist/chunks/checkbox-radio-BI-UjgMF.js +136 -0
  7. package/dist/chunks/conditions-BVl6jTYo.js +433 -0
  8. package/dist/chunks/date-picker-69TgvErA.js +4994 -0
  9. package/dist/chunks/eway-1GPxH6DU.js +74 -0
  10. package/dist/chunks/file-upload-BDZZftgL.js +281 -0
  11. package/dist/chunks/friendly-captcha-v1-DA2QPKA3.js +33 -0
  12. package/dist/chunks/friendly-captcha-v2-BorOWiz_.js +38 -0
  13. package/dist/chunks/go-cardless-DwBgERcA.js +24 -0
  14. package/dist/chunks/google-address-BcTBncyS.js +162 -0
  15. package/dist/chunks/hcaptcha-BchdVCqq.js +56 -0
  16. package/dist/chunks/hidden-D8RqSPt7.js +31 -0
  17. package/dist/chunks/index-BEsfee-D.js +1839 -0
  18. package/dist/chunks/index-BP7Unm5Y.js +863 -0
  19. package/dist/chunks/index-C1ZOKiAi.js +4229 -0
  20. package/dist/chunks/loqate-nXuTX7In.js +55 -0
  21. package/dist/chunks/mollie-qdCynQCd.js +24 -0
  22. package/dist/chunks/moneris-BNEA-laO.js +101 -0
  23. package/dist/chunks/opayo-BJtXOkuK.js +122 -0
  24. package/dist/chunks/paddle-D72Pa8kr.js +60 -0
  25. package/dist/chunks/paypal-Cqt2bned.js +100 -0
  26. package/dist/chunks/payway-BjCqsc0H.js +56 -0
  27. package/dist/chunks/phone-country-K9pYAlzM.js +3765 -0
  28. package/dist/chunks/place-kit-Dg6f_UoM.js +42 -0
  29. package/dist/chunks/placekit-autocomplete.esm-LAwfbPZl.js +1299 -0
  30. package/dist/chunks/recaptcha-enterprise--VYAeeqz.js +71 -0
  31. package/dist/chunks/recaptcha-shared-PSIEEEe1.js +15 -0
  32. package/dist/chunks/recaptcha-v2-checkbox-atBNe5ml.js +41 -0
  33. package/dist/chunks/recaptcha-v2-invisible-DnBufNPT.js +59 -0
  34. package/dist/chunks/recaptcha-v3-CF6O8rDj.js +28 -0
  35. package/dist/chunks/repeater-CB7Yojvx.js +124 -0
  36. package/dist/chunks/rich-text-nAV_SQZo.js +304 -0
  37. package/dist/chunks/scripts-BkAAux0i.js +36 -0
  38. package/dist/chunks/sdk-3SicTWby.js +1559 -0
  39. package/dist/chunks/shared-DGqeMvcJ.js +80 -0
  40. package/dist/chunks/signature-BT6CsQ6n.js +550 -0
  41. package/dist/chunks/snaptcha-C7qQo02f.js +8 -0
  42. package/dist/chunks/square-C5AH3trb.js +46 -0
  43. package/dist/chunks/stripe-EJK0RyUv.js +202 -0
  44. package/dist/chunks/styles-C3aqgtek.js +21 -0
  45. package/dist/chunks/summary-DC_ipXCU.js +126 -0
  46. package/dist/chunks/table-BEAI99qo.js +95 -0
  47. package/dist/chunks/text-limit-Blgq5G-G.js +135 -0
  48. package/dist/chunks/turnstile-_uCRwnU-.js +59 -0
  49. package/dist/chunks/utils-BntI3W4S.js +6149 -0
  50. package/dist/index.js +39 -3205
  51. package/package.json +5 -5
  52. package/src/js/modules/fields/file-upload.ts +1 -1
  53. package/src/js/modules/fields/repeater.ts +1 -1
  54. package/src/js/modules/fields/rich-text.ts +2 -2
  55. package/src/js/modules/fields/signature.ts +1 -1
  56. package/src/js/modules/fields/summary.ts +1 -1
  57. package/src/js/modules/fields/table.ts +1 -1
  58. package/src/js/modules/fields/text-limit.ts +1 -1
  59. package/src/js/modules/payments/paypal.ts +1 -1
  60. package/src/js/modules/payments/payway.ts +1 -1
  61. package/src/js/modules/payments/stripe.ts +1 -1
  62. package/dist/chunks/address-finder-DfMCiW89.js +0 -47
  63. package/dist/chunks/api-CbqEMQT5.js +0 -181
  64. package/dist/chunks/api-DE7LfK-R.js +0 -960
  65. package/dist/chunks/api-DOfDzYC_.js +0 -538
  66. package/dist/chunks/async-B3DUf1GZ.js +0 -26
  67. package/dist/chunks/bpoint-Ciy3yY9Q.js +0 -34
  68. package/dist/chunks/calculations-CkYAqO_-.js +0 -197
  69. package/dist/chunks/captcha-eu-DnOWhMwr.js +0 -43
  70. package/dist/chunks/checkbox-radio-0x7Tc0br.js +0 -197
  71. package/dist/chunks/chunk-K6L4z4UQ.js +0 -24
  72. package/dist/chunks/conditions-4fXKhEJS.js +0 -609
  73. package/dist/chunks/date-picker-B6iZkjHS.js +0 -6204
  74. package/dist/chunks/debug-KnZeKYBI.js +0 -39
  75. package/dist/chunks/dist-D09GnXMW.js +0 -2663
  76. package/dist/chunks/event-names-DamGPtXR.js +0 -51
  77. package/dist/chunks/eway-DEAYcwT0.js +0 -86
  78. package/dist/chunks/field-references.keys-BpBZ_quS.js +0 -24
  79. package/dist/chunks/field-references.resolver-Ba6xhiJC.js +0 -183
  80. package/dist/chunks/file-upload-Bh63PQSE.js +0 -430
  81. package/dist/chunks/friendly-captcha-v1-CqO4WVre.js +0 -40
  82. package/dist/chunks/friendly-captcha-v2-CyykcJcM.js +0 -47
  83. package/dist/chunks/friendly-challenge-Dg8XkStd.js +0 -1101
  84. package/dist/chunks/go-cardless-CuND59rR.js +0 -26
  85. package/dist/chunks/google-address--uR8WDSm.js +0 -208
  86. package/dist/chunks/hcaptcha-CmaFUesv.js +0 -72
  87. package/dist/chunks/hidden-CYnZYple.js +0 -36
  88. package/dist/chunks/http-18nn97DZ.js +0 -29
  89. package/dist/chunks/i18n-vUh-KGiH.js +0 -55
  90. package/dist/chunks/loqate-BICNJlVK.js +0 -97
  91. package/dist/chunks/mollie-DwlsgHZ1.js +0 -26
  92. package/dist/chunks/moneris-B_IFZFTx.js +0 -159
  93. package/dist/chunks/opayo-U2x_TOII.js +0 -192
  94. package/dist/chunks/paddle-BqXFrc79.js +0 -75
  95. package/dist/chunks/paypal-Cn_DYGDb.js +0 -121
  96. package/dist/chunks/payway-Rnq796eC.js +0 -75
  97. package/dist/chunks/phone-country-B6Me4lK0.js +0 -3317
  98. package/dist/chunks/place-kit-ldUl-u9w.js +0 -56
  99. package/dist/chunks/placekit-autocomplete.esm-D-lGeaZl.js +0 -1771
  100. package/dist/chunks/recaptcha-enterprise-DPJNyv1X.js +0 -72
  101. package/dist/chunks/recaptcha-shared-DTI4qWVR.js +0 -22
  102. package/dist/chunks/recaptcha-v2-checkbox-zFjpvJ5c.js +0 -49
  103. package/dist/chunks/recaptcha-v2-invisible-CnYtkNvz.js +0 -62
  104. package/dist/chunks/recaptcha-v3-EAlWhnkX.js +0 -33
  105. package/dist/chunks/repeater-CXD1eLSn.js +0 -151
  106. package/dist/chunks/rich-text-DkmZRhGj.js +0 -442
  107. package/dist/chunks/scripts-BGD_iU_6.js +0 -41
  108. package/dist/chunks/sdk-B7u9fTlP.js +0 -2103
  109. package/dist/chunks/shared-DC6_1u8X.js +0 -85
  110. package/dist/chunks/signature-E9KyYXS1.js +0 -765
  111. package/dist/chunks/snaptcha-CCDunGeb.js +0 -8
  112. package/dist/chunks/square-BLqK51rS.js +0 -61
  113. package/dist/chunks/stripe-B8gHpZNC.js +0 -273
  114. package/dist/chunks/styles-BIh6g7V_.js +0 -22
  115. package/dist/chunks/summary-EcNE0cvg.js +0 -191
  116. package/dist/chunks/table-yxEDL6kA.js +0 -124
  117. package/dist/chunks/text-limit-D0H_Ca2c.js +0 -179
  118. package/dist/chunks/theme-classes-vSHpdCUO.js +0 -59
  119. package/dist/chunks/turnstile-DP0bdR7T.js +0 -68
  120. package/dist/chunks/utils-ByrEVYrJ.js +0 -49584
@@ -1,72 +0,0 @@
1
- import { t as defineCaptchaModule } from "./api-DOfDzYC_.js";
2
- import { t as loadRecaptchaGlobal } from "./recaptcha-shared-DTI4qWVR.js";
3
- //#region src/js/modules/captchas/recaptcha-enterprise.ts
4
- var recaptchaEnterpriseModule = defineCaptchaModule({
5
- id: "recaptcha-enterprise",
6
- defaultPlaceholderSelector: "[data-recaptcha-placeholder]",
7
- defaultTokenFieldNames: ["g-recaptcha-response"],
8
- load: ({ options }) => {
9
- return loadRecaptchaGlobal(options.provider, true, options.provider.enterpriseType === "score" || options.provider.enterpriseType === "policy" ? options.provider.siteKey || void 0 : void 0);
10
- },
11
- mount: ({ api, container, provider, services }) => {
12
- const enterpriseApi = api.enterprise || api;
13
- return new Promise((resolve) => {
14
- enterpriseApi.ready(() => {
15
- if (provider.enterpriseType !== "checkbox") {
16
- resolve(provider.siteKey || `recaptcha-enterprise-${provider.enterpriseType || "score"}`);
17
- return;
18
- }
19
- resolve(enterpriseApi.render(container, {
20
- sitekey: provider.siteKey || "",
21
- theme: provider.theme || "light",
22
- badge: provider.badge || "bottomright",
23
- size: provider.size || "normal",
24
- action: provider.action || "submit",
25
- callback: (token) => {
26
- if (typeof token === "string" && token.trim() !== "") services.tokens.write(token.trim());
27
- services.errors.clear();
28
- },
29
- "expired-callback": () => {
30
- services.tokens.clear();
31
- services.errors.clear();
32
- },
33
- "error-callback": () => {
34
- services.tokens.clear();
35
- }
36
- }));
37
- });
38
- });
39
- },
40
- screen: async ({ api, widget, provider, placeholder, services, stageCtx }) => {
41
- const enterpriseApi = api.enterprise || api;
42
- if (provider.enterpriseType === "checkbox") {
43
- if (services.tokens.has()) return;
44
- const message = services.errors.getDefaultMessage();
45
- services.errors.show(message, placeholder);
46
- stageCtx.abort(message);
47
- return;
48
- }
49
- if (services.tokens.has()) return;
50
- if (provider.enterpriseType === "score" || provider.enterpriseType === "policy") {
51
- const token = await enterpriseApi.execute(provider.siteKey || "", { action: provider.action || "submit" });
52
- if (typeof token === "string" && token.trim() !== "") services.tokens.write(token.trim());
53
- } else enterpriseApi.execute(widget);
54
- if (!await services.tokens.wait(12e4)) {
55
- const message = services.errors.getDefaultMessage();
56
- services.errors.show(message, placeholder);
57
- stageCtx.abort(message);
58
- }
59
- },
60
- reset: ({ api, widget, provider, services }) => {
61
- const enterpriseApi = api.enterprise || api;
62
- if (provider.enterpriseType === "checkbox") enterpriseApi.reset(widget);
63
- services.tokens.clear();
64
- },
65
- unmount: ({ api, widget, provider, services }) => {
66
- const enterpriseApi = api.enterprise || api;
67
- if (provider.enterpriseType === "checkbox") enterpriseApi.reset(widget);
68
- services.tokens.clear();
69
- }
70
- });
71
- //#endregion
72
- export { recaptchaEnterpriseModule };
@@ -1,22 +0,0 @@
1
- import { a as CAPTCHA_PROVIDER_LOAD_TIMEOUT_MS, r as getScriptAttributes } from "./api-DOfDzYC_.js";
2
- import { r as loadScriptAndEnsureGlobal } from "./scripts-BGD_iU_6.js";
3
- //#region src/js/modules/captchas/recaptcha-shared.ts
4
- async function loadRecaptchaGlobal(options, enterprise = false, renderValue) {
5
- const language = typeof options.language === "string" && options.language.trim() !== "" ? options.language.trim() : "en";
6
- const { async, defer } = getScriptAttributes(options.loadingMethod);
7
- const host = enterprise ? "https://www.google.com/recaptcha/enterprise.js" : "https://www.recaptcha.net/recaptcha/api.js";
8
- const render = typeof renderValue === "string" && renderValue.trim() !== "" ? renderValue.trim() : "explicit";
9
- const src = new URL(host);
10
- src.searchParams.set("render", render);
11
- src.searchParams.set("hl", language);
12
- if (render !== "explicit" && typeof options.badge === "string" && options.badge.trim() !== "") src.searchParams.set("badge", options.badge.trim());
13
- return loadScriptAndEnsureGlobal("grecaptcha", {
14
- id: enterprise ? "FORMIE_RECAPTCHA_ENTERPRISE_SCRIPT" : "FORMIE_RECAPTCHA_SCRIPT",
15
- src: src.toString(),
16
- async,
17
- defer,
18
- timeoutMs: CAPTCHA_PROVIDER_LOAD_TIMEOUT_MS
19
- });
20
- }
21
- //#endregion
22
- export { loadRecaptchaGlobal as t };
@@ -1,49 +0,0 @@
1
- import { t as defineCaptchaModule } from "./api-DOfDzYC_.js";
2
- import { t as loadRecaptchaGlobal } from "./recaptcha-shared-DTI4qWVR.js";
3
- //#region src/js/modules/captchas/recaptcha-v2-checkbox.ts
4
- var recaptchaV2CheckboxModule = defineCaptchaModule({
5
- id: "recaptcha-v2-checkbox",
6
- defaultPlaceholderSelector: "[data-recaptcha-placeholder]",
7
- defaultTokenFieldNames: ["g-recaptcha-response"],
8
- load: ({ options }) => {
9
- return loadRecaptchaGlobal(options.provider);
10
- },
11
- mount: ({ api, container, provider, services }) => {
12
- return new Promise((resolve) => {
13
- api.ready(() => {
14
- resolve(api.render(container, {
15
- sitekey: provider.siteKey || "",
16
- theme: provider.theme || "light",
17
- size: provider.size || "normal",
18
- callback: (token) => {
19
- if (typeof token === "string" && token.trim() !== "") services.tokens.write(token.trim());
20
- services.errors.clear();
21
- },
22
- "expired-callback": () => {
23
- services.tokens.clear();
24
- services.errors.clear();
25
- },
26
- "error-callback": () => {
27
- services.tokens.clear();
28
- }
29
- }));
30
- });
31
- });
32
- },
33
- screen: ({ placeholder, services, stageCtx }) => {
34
- if (services.tokens.has()) return;
35
- const message = services.errors.getDefaultMessage();
36
- services.errors.show(message, placeholder);
37
- stageCtx.abort(message);
38
- },
39
- reset: ({ api, widget, services }) => {
40
- api.reset(widget);
41
- services.tokens.clear();
42
- },
43
- unmount: ({ api, widget, services }) => {
44
- api.reset(widget);
45
- services.tokens.clear();
46
- }
47
- });
48
- //#endregion
49
- export { recaptchaV2CheckboxModule };
@@ -1,62 +0,0 @@
1
- import { t as defineCaptchaModule } from "./api-DOfDzYC_.js";
2
- import { t as loadRecaptchaGlobal } from "./recaptcha-shared-DTI4qWVR.js";
3
- //#region src/js/modules/captchas/recaptcha-v2-invisible.ts
4
- async function waitForRecaptchaResponse(api, widgetId, timeoutMs = 1e3) {
5
- const deadline = Date.now() + timeoutMs;
6
- while (Date.now() < deadline) {
7
- const response = typeof api.getResponse === "function" ? api.getResponse(widgetId) : "";
8
- if (typeof response === "string" && response.trim() !== "") return response.trim();
9
- await new Promise((resolve) => {
10
- window.setTimeout(resolve, 100);
11
- });
12
- }
13
- }
14
- var recaptchaV2InvisibleModule = defineCaptchaModule({
15
- id: "recaptcha-v2-invisible",
16
- defaultPlaceholderSelector: "[data-recaptcha-placeholder]",
17
- defaultTokenFieldNames: ["g-recaptcha-response"],
18
- load: ({ options }) => {
19
- return loadRecaptchaGlobal(options.provider);
20
- },
21
- mount: ({ api, container, provider, services }) => {
22
- return new Promise((resolve) => {
23
- api.ready(() => {
24
- const widgetId = api.render(container, {
25
- sitekey: provider.siteKey || "",
26
- badge: provider.badge || "bottomright",
27
- size: "invisible",
28
- callback: (token) => {
29
- const response = typeof token === "string" && token.trim() !== "" ? token.trim() : typeof api.getResponse === "function" ? api.getResponse(widgetId) : "";
30
- if (response) services.tokens.write(response);
31
- services.errors.clear();
32
- },
33
- "expired-callback": () => {
34
- services.tokens.clear();
35
- services.errors.clear();
36
- },
37
- "error-callback": () => {
38
- services.tokens.clear();
39
- }
40
- });
41
- resolve({ id: widgetId });
42
- });
43
- });
44
- },
45
- screen: async ({ api, widget, placeholder, services, stageCtx }) => {
46
- if (services.tokens.has()) return;
47
- api.execute(widget.id);
48
- const token = await waitForRecaptchaResponse(api, widget.id);
49
- if (typeof token === "string" && token.trim() !== "") services.tokens.write(token.trim());
50
- if (!await services.tokens.wait(12e4)) {
51
- const message = services.errors.getDefaultMessage();
52
- services.errors.show(message, placeholder);
53
- stageCtx.abort(message);
54
- }
55
- },
56
- unmount: ({ api, widget, services }) => {
57
- api.reset(widget.id);
58
- services.tokens.clear();
59
- }
60
- });
61
- //#endregion
62
- export { recaptchaV2InvisibleModule };
@@ -1,33 +0,0 @@
1
- import { t as defineCaptchaModule } from "./api-DOfDzYC_.js";
2
- import { t as loadRecaptchaGlobal } from "./recaptcha-shared-DTI4qWVR.js";
3
- //#region src/js/modules/captchas/recaptcha-v3.ts
4
- var recaptchaV3Module = defineCaptchaModule({
5
- id: "recaptcha-v3",
6
- defaultPlaceholderSelector: "[data-recaptcha-placeholder]",
7
- defaultTokenFieldNames: ["g-recaptcha-response"],
8
- load: ({ options }) => {
9
- return loadRecaptchaGlobal(options.provider, false, options.provider.siteKey || void 0);
10
- },
11
- mount: ({ api, provider }) => {
12
- return new Promise((resolve) => {
13
- api.ready(() => {
14
- resolve(provider.siteKey || "recaptcha-v3");
15
- });
16
- });
17
- },
18
- screen: async ({ api, provider, placeholder, services, stageCtx }) => {
19
- if (services.tokens.has()) return;
20
- const token = await api.execute(provider.siteKey || "", { action: provider.action || "submit" });
21
- if (typeof token === "string" && token.trim() !== "") services.tokens.write(token.trim());
22
- if (!await services.tokens.wait(12e4)) {
23
- const message = services.errors.getDefaultMessage();
24
- services.errors.show(message, placeholder);
25
- stageCtx.abort(message);
26
- }
27
- },
28
- unmount: ({ services }) => {
29
- services.tokens.clear();
30
- }
31
- });
32
- //#endregion
33
- export { recaptchaV3Module };
@@ -1,151 +0,0 @@
1
- import { t as createDebug } from "./debug-KnZeKYBI.js";
2
- import { n as sleep } from "./async-B3DUf1GZ.js";
3
- import { t as ensureModuleStyles } from "./styles-BIh6g7V_.js";
4
- import { a as getTemplateSource, o as getTemplateSourceHtml, t as dispatchFieldEvent } from "./shared-DC6_1u8X.js";
5
- //#region src/css/theme/fields/_repeater.css?inline
6
- var _repeater_default = "@layer formie-theme{.formie-repeater-container{gap:var(--formie-space-4);display:grid}.formie-repeater-item-wrapper{gap:var(--formie-space-4);padding:var(--formie-space-4);border:var(--formie-border-width) solid var(--formie-color-border);border-radius:var(--formie-radius-md);transition:border-color .15s,box-shadow .15s,background-color .15s;display:grid;position:relative}.formie-repeater-item-wrapper:focus-within{border-color:var(--formie-focus-ring-border-color);box-shadow:var(--formie-shadow-focus)}.formie-field-has-error .formie-repeater-item-wrapper{border-color:var(--formie-color-danger)}.formie-field-has-error .formie-repeater-item-wrapper:focus-within{box-shadow:var(--formie-shadow-danger-focus)}.formie-repeater-item-wrapper>.formie-repeater-remove-button{top:var(--formie-repeater-remove-button-top);right:var(--formie-repeater-remove-button-right);transform:var(--formie-repeater-remove-button-transform);font-size:0;line-height:0;position:absolute}.formie-button.formie-repeater-add-button{width:auto;max-width:100%;padding-left:var(--formie-repeater-add-button-padding-left);justify-content:center;justify-self:start;align-items:center;display:inline-flex;position:relative}.formie-button.formie-repeater-add-button:before{content:\"\";width:var(--formie-repeater-add-button-width);height:var(--formie-repeater-add-button-height);left:var(--formie-repeater-add-button-left);-webkit-mask-image:var(--formie-repeater-add-button-icon-mask);-webkit-mask-image:var(--formie-repeater-add-button-icon-mask);mask-image:var(--formie-repeater-add-button-icon-mask);background-color:currentColor;display:block;position:absolute;top:50%;transform:translateY(-50%);-webkit-mask-position:50%;mask-position:50%;-webkit-mask-size:contain;mask-size:contain;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}}";
7
- //#endregion
8
- //#region src/js/modules/fields/repeater.ts
9
- var FIELD_SELECTOR = "[data-formie-repeater-field-layout]";
10
- var CONTAINER_SELECTOR = "[data-formie-repeater-container]";
11
- var ROW_SELECTOR = "[data-formie-repeater-item]";
12
- var ADD_SELECTOR = "[data-formie-repeater-add]";
13
- var REMOVE_SELECTOR = "[data-formie-repeater-remove]";
14
- var TEMPLATE_ID_ATTR = "data-formie-template-id";
15
- var MODULE_ID = "repeater";
16
- var debug = createDebug("fields", "repeater");
17
- ensureModuleStyles(MODULE_ID, [_repeater_default]);
18
- function getTemplate(field, templateId) {
19
- return getTemplateSource(field, templateId);
20
- }
21
- function buildRowFromTemplate(templateHtml, rowId) {
22
- const wrapper = document.createElement("div");
23
- wrapper.innerHTML = templateHtml.replaceAll("__ROW__", String(rowId)).trim();
24
- return wrapper.firstElementChild instanceof HTMLElement ? wrapper.firstElementChild : null;
25
- }
26
- function getRowCount(field) {
27
- return field.querySelectorAll(ROW_SELECTOR).length;
28
- }
29
- function syncAddButton(addButton, rowCount) {
30
- if (!addButton) return;
31
- const maxRows = parseInt(addButton.getAttribute("data-formie-max-rows") || "", 10);
32
- if (maxRows > 0 && rowCount >= maxRows) {
33
- addButton.disabled = true;
34
- return;
35
- }
36
- addButton.disabled = false;
37
- }
38
- function bindRepeaterField(field) {
39
- const container = field.matches(CONTAINER_SELECTOR) ? field : field.querySelector(CONTAINER_SELECTOR);
40
- const addButton = field.querySelector(ADD_SELECTOR);
41
- if (!(container instanceof HTMLElement)) {
42
- debug.warn("Missing repeater container; skipping field.");
43
- return () => {};
44
- }
45
- const removeHandlers = /* @__PURE__ */ new Map();
46
- let rowCounter = Array.from(field.querySelectorAll(ROW_SELECTOR)).reduce((max, row) => {
47
- const current = parseInt(row.getAttribute("data-formie-repeater-item-id") || "", 10);
48
- return Number.isNaN(current) ? max : Math.max(max, current + 1);
49
- }, 0);
50
- const bindRemoveButtons = () => {
51
- field.querySelectorAll(REMOVE_SELECTOR).forEach((button) => {
52
- if (!(button instanceof HTMLElement) || removeHandlers.has(button)) return;
53
- const handler = (event) => {
54
- event.preventDefault();
55
- const row = button.closest(ROW_SELECTOR);
56
- if (!(row instanceof HTMLElement)) return;
57
- const minRows = parseInt((addButton instanceof HTMLButtonElement ? addButton.getAttribute("data-formie-min-rows") : "") || "", 10);
58
- if (minRows > 0 && getRowCount(field) <= minRows) return;
59
- row.remove();
60
- syncAddButton(addButton instanceof HTMLButtonElement ? addButton : null, getRowCount(field));
61
- debug.log("Row removed.", { rowCount: getRowCount(field) });
62
- dispatchFieldEvent(field, MODULE_ID, "remove", {
63
- repeater: field,
64
- row
65
- });
66
- };
67
- button.addEventListener("click", handler);
68
- removeHandlers.set(button, handler);
69
- });
70
- };
71
- const addRow = async () => {
72
- if (!(addButton instanceof HTMLButtonElement)) return;
73
- const handle = addButton.getAttribute("data-formie-repeater-add");
74
- if (!handle) {
75
- debug.warn("Add handle missing.");
76
- return;
77
- }
78
- const templateId = addButton.getAttribute(TEMPLATE_ID_ATTR) || field.getAttribute(TEMPLATE_ID_ATTR);
79
- const maxRows = parseInt(addButton.getAttribute("data-formie-max-rows") || "", 10);
80
- if (maxRows > 0 && getRowCount(field) >= maxRows) return;
81
- const template = getTemplate(field, templateId);
82
- if (!template) {
83
- debug.warn("Template not found for add action.", { handle });
84
- return;
85
- }
86
- const row = buildRowFromTemplate(getTemplateSourceHtml(template), rowCounter++);
87
- if (!row) {
88
- debug.warn("Failed to build row from template.");
89
- return;
90
- }
91
- container.appendChild(row);
92
- await sleep(50);
93
- bindRemoveButtons();
94
- syncAddButton(addButton, getRowCount(field));
95
- debug.log("Row appended.", { rowCount: getRowCount(field) });
96
- dispatchFieldEvent(field, MODULE_ID, "append", {
97
- repeater: field,
98
- row
99
- });
100
- dispatchFieldEvent(field, MODULE_ID, "init-row", {
101
- repeater: field,
102
- row
103
- });
104
- };
105
- const addHandler = (event) => {
106
- event.preventDefault();
107
- addRow();
108
- };
109
- if (addButton instanceof HTMLButtonElement) addButton.addEventListener("click", addHandler);
110
- bindRemoveButtons();
111
- syncAddButton(addButton instanceof HTMLButtonElement ? addButton : null, getRowCount(field));
112
- if (addButton instanceof HTMLButtonElement && getRowCount(field) === 0) {
113
- const minRows = parseInt(addButton.getAttribute("data-formie-min-rows") || "", 10);
114
- for (let index = 0; index < minRows; index += 1) addRow();
115
- }
116
- dispatchFieldEvent(field, MODULE_ID, "init", { repeater: field });
117
- debug.log("Field initialized.", { rowCount: getRowCount(field) });
118
- return () => {
119
- if (addButton instanceof HTMLButtonElement) addButton.removeEventListener("click", addHandler);
120
- removeHandlers.forEach((handler, button) => {
121
- button.removeEventListener("click", handler);
122
- });
123
- };
124
- }
125
- var repeaterModule = {
126
- id: MODULE_ID,
127
- kind: "field",
128
- match: (ctx) => {
129
- return ctx.target instanceof HTMLElement && (ctx.target.matches(FIELD_SELECTOR) || !!ctx.target.querySelector(FIELD_SELECTOR));
130
- },
131
- setup: async (ctx) => {
132
- if (!(ctx.target instanceof HTMLElement)) return;
133
- const fields = ctx.target.matches(FIELD_SELECTOR) ? [ctx.target] : Array.from(ctx.target.querySelectorAll(FIELD_SELECTOR)).filter((field) => {
134
- return field instanceof HTMLElement;
135
- });
136
- const destroyBindings = fields.map((field) => {
137
- return bindRepeaterField(field);
138
- });
139
- debug.log("Module setup.", { fieldCount: fields.length });
140
- await ctx.emit("formie:module:repeater:init", { count: fields.length });
141
- return { destroy: () => {
142
- destroyBindings.forEach((destroyBinding) => {
143
- destroyBinding();
144
- });
145
- debug.log("Module destroy.", { fieldCount: fields.length });
146
- ctx.emit("formie:module:repeater:destroy", {});
147
- } };
148
- }
149
- };
150
- //#endregion
151
- export { repeaterModule };