@10x-media/form-builder 0.1.0-beta.0 → 0.1.0-beta.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 (406) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/README.md +45 -1402
  3. package/dist/actions/buildActionBlocks.js +19 -0
  4. package/dist/actions/buildActionBlocks.js.map +1 -0
  5. package/dist/actions/builtin/confirmation.js +49 -0
  6. package/dist/actions/builtin/confirmation.js.map +1 -0
  7. package/dist/actions/builtin/emailTeam.js +46 -0
  8. package/dist/actions/builtin/emailTeam.js.map +1 -0
  9. package/dist/actions/builtin/index.d.ts +7 -0
  10. package/dist/actions/builtin/index.js +13 -0
  11. package/dist/actions/builtin/index.js.map +1 -0
  12. package/dist/actions/builtin/signedWebhook.js +49 -0
  13. package/dist/actions/builtin/signedWebhook.js.map +1 -0
  14. package/dist/actions/defineAction.d.ts +36 -0
  15. package/dist/actions/defineAction.js +6 -0
  16. package/dist/actions/defineAction.js.map +1 -0
  17. package/dist/actions/dispatch.js +48 -0
  18. package/dist/actions/dispatch.js.map +1 -0
  19. package/dist/actions/registry.d.ts +16 -0
  20. package/dist/actions/registry.js +16 -0
  21. package/dist/actions/registry.js.map +1 -0
  22. package/dist/actions/runActions.d.ts +9 -0
  23. package/dist/actions/runActions.js +34 -0
  24. package/dist/actions/runActions.js.map +1 -0
  25. package/dist/actions/sign.d.ts +7 -0
  26. package/dist/actions/sign.js +9 -0
  27. package/dist/actions/sign.js.map +1 -0
  28. package/dist/actions/task.js +82 -0
  29. package/dist/actions/task.js.map +1 -0
  30. package/dist/aggregation/aggregateResponses.d.ts +31 -0
  31. package/dist/aggregation/aggregateResponses.js +86 -0
  32. package/dist/aggregation/aggregateResponses.js.map +1 -0
  33. package/dist/aggregation/aggregateRows.d.ts +10 -0
  34. package/dist/aggregation/aggregateRows.js +64 -0
  35. package/dist/aggregation/aggregateRows.js.map +1 -0
  36. package/dist/aggregation/resolveResultsRequest.d.ts +32 -0
  37. package/dist/aggregation/resolveResultsRequest.js +56 -0
  38. package/dist/aggregation/resolveResultsRequest.js.map +1 -0
  39. package/dist/aggregation/types.d.ts +39 -0
  40. package/dist/calc/computeCalcFields.d.ts +15 -0
  41. package/dist/calc/computeCalcFields.js +27 -0
  42. package/dist/calc/computeCalcFields.js.map +1 -0
  43. package/dist/calc/evaluate.d.ts +8 -0
  44. package/dist/calc/evaluate.js +59 -0
  45. package/dist/calc/evaluate.js.map +1 -0
  46. package/dist/calc/normalizeCalc.d.ts +8 -0
  47. package/dist/calc/normalizeCalc.js +100 -0
  48. package/dist/calc/normalizeCalc.js.map +1 -0
  49. package/dist/calc/types.d.ts +28 -0
  50. package/dist/client/ConditionBuilder.js +121 -0
  51. package/dist/client/ConditionBuilder.js.map +1 -0
  52. package/dist/client/ConditionRow.js +150 -0
  53. package/dist/client/ConditionRow.js.map +1 -0
  54. package/dist/client/FlowBuilder.d.ts +15 -0
  55. package/dist/client/FlowBuilder.js +408 -0
  56. package/dist/client/FlowBuilder.js.map +1 -0
  57. package/dist/client/FormConditionField.d.ts +21 -0
  58. package/dist/client/FormConditionField.js +33 -0
  59. package/dist/client/FormConditionField.js.map +1 -0
  60. package/dist/client/synthesizeClientField.js +46 -0
  61. package/dist/client/synthesizeClientField.js.map +1 -0
  62. package/dist/collections/formSubmissions.js +157 -0
  63. package/dist/collections/formSubmissions.js.map +1 -0
  64. package/dist/collections/forms.js +198 -0
  65. package/dist/collections/forms.js.map +1 -0
  66. package/dist/collections/uploads.d.ts +30 -0
  67. package/dist/collections/uploads.js +55 -0
  68. package/dist/collections/uploads.js.map +1 -0
  69. package/dist/conditions/conditionType.js +14 -0
  70. package/dist/conditions/conditionType.js.map +1 -0
  71. package/dist/conditions/evaluate.d.ts +17 -0
  72. package/dist/conditions/evaluate.js +94 -0
  73. package/dist/conditions/evaluate.js.map +1 -0
  74. package/dist/conditions/fieldTypes.d.ts +9 -0
  75. package/dist/{fieldTypes-CzhhJXjg.js → conditions/fieldTypes.js} +2 -2
  76. package/dist/conditions/fieldTypes.js.map +1 -0
  77. package/dist/conditions/normalizeConditions.js +47 -0
  78. package/dist/conditions/normalizeConditions.js.map +1 -0
  79. package/dist/conditions/types.d.ts +8 -0
  80. package/dist/consent/buildConsentSourceConfig.js +49 -0
  81. package/dist/consent/buildConsentSourceConfig.js.map +1 -0
  82. package/dist/consent/builtin/index.d.ts +7 -0
  83. package/dist/consent/builtin/index.js +11 -0
  84. package/dist/consent/builtin/index.js.map +1 -0
  85. package/dist/consent/builtin/pageReference.js +75 -0
  86. package/dist/consent/builtin/pageReference.js.map +1 -0
  87. package/dist/consent/builtin/static.js +44 -0
  88. package/dist/consent/builtin/static.js.map +1 -0
  89. package/dist/consent/captureConsent.d.ts +28 -0
  90. package/dist/consent/captureConsent.js +26 -0
  91. package/dist/consent/captureConsent.js.map +1 -0
  92. package/dist/consent/defineConsentSource.d.ts +35 -0
  93. package/dist/consent/defineConsentSource.js +6 -0
  94. package/dist/consent/defineConsentSource.js.map +1 -0
  95. package/dist/consent/registry.d.ts +16 -0
  96. package/dist/consent/registry.js +16 -0
  97. package/dist/consent/registry.js.map +1 -0
  98. package/dist/consent/resolveConsentLinks.d.ts +19 -0
  99. package/dist/consent/resolveConsentLinks.js +26 -0
  100. package/dist/consent/resolveConsentLinks.js.map +1 -0
  101. package/dist/consent/resolvePublishedVersionRef.d.ts +17 -0
  102. package/dist/consent/resolvePublishedVersionRef.js +27 -0
  103. package/dist/consent/resolvePublishedVersionRef.js.map +1 -0
  104. package/dist/events/noopSink.js +6 -0
  105. package/dist/events/noopSink.js.map +1 -0
  106. package/dist/events/resolveEventSink.js +8 -0
  107. package/dist/events/resolveEventSink.js.map +1 -0
  108. package/dist/events/types.d.ts +31 -0
  109. package/dist/exports/client.d.ts +3 -21
  110. package/dist/exports/client.js +3 -319
  111. package/dist/exports/i18n.d.ts +3 -138
  112. package/dist/exports/i18n.js +2 -2
  113. package/dist/exports/react.d.ts +45 -550
  114. package/dist/exports/react.js +39 -1563
  115. package/dist/exports/rsc.d.ts +2 -16
  116. package/dist/exports/rsc.js +1 -54
  117. package/dist/exports/types.d.ts +28 -5
  118. package/dist/fields/buildFieldBlocks.js +60 -0
  119. package/dist/fields/buildFieldBlocks.js.map +1 -0
  120. package/dist/fields/builtin/calculation.js +24 -0
  121. package/dist/fields/builtin/calculation.js.map +1 -0
  122. package/dist/fields/builtin/checkbox.js +13 -0
  123. package/dist/fields/builtin/checkbox.js.map +1 -0
  124. package/dist/fields/builtin/consent.js +32 -0
  125. package/dist/fields/builtin/consent.js.map +1 -0
  126. package/dist/fields/builtin/email.js +18 -0
  127. package/dist/fields/builtin/email.js.map +1 -0
  128. package/dist/fields/builtin/file.js +40 -0
  129. package/dist/fields/builtin/file.js.map +1 -0
  130. package/dist/fields/builtin/index.js +27 -0
  131. package/dist/fields/builtin/index.js.map +1 -0
  132. package/dist/fields/builtin/number.js +17 -0
  133. package/dist/fields/builtin/number.js.map +1 -0
  134. package/dist/fields/builtin/repeater.js +44 -0
  135. package/dist/fields/builtin/repeater.js.map +1 -0
  136. package/dist/fields/builtin/select.js +44 -0
  137. package/dist/fields/builtin/select.js.map +1 -0
  138. package/dist/fields/builtin/text.js +13 -0
  139. package/dist/fields/builtin/text.js.map +1 -0
  140. package/dist/fields/builtin/textarea.js +13 -0
  141. package/dist/fields/builtin/textarea.js.map +1 -0
  142. package/dist/fields/defineFormField.d.ts +13 -0
  143. package/dist/fields/defineFormField.js +12 -0
  144. package/dist/fields/defineFormField.js.map +1 -0
  145. package/dist/fields/registry.d.ts +10 -0
  146. package/dist/fields/registry.js +24 -0
  147. package/dist/fields/registry.js.map +1 -0
  148. package/dist/fields/sharedConfig.js +89 -0
  149. package/dist/fields/sharedConfig.js.map +1 -0
  150. package/dist/fields/types.d.ts +89 -0
  151. package/dist/flow/engine.d.ts +17 -0
  152. package/dist/flow/engine.js +24 -0
  153. package/dist/flow/engine.js.map +1 -0
  154. package/dist/flow/normalizeFlow.js +35 -0
  155. package/dist/flow/normalizeFlow.js.map +1 -0
  156. package/dist/{types-DsJ_6kGJ.d.ts → flow/types.d.ts} +2 -2
  157. package/dist/index.d.ts +93 -4
  158. package/dist/index.js +43 -1890
  159. package/dist/index.js.map +1 -1
  160. package/dist/plugin/access.js +12 -0
  161. package/dist/plugin/access.js.map +1 -0
  162. package/dist/plugin/collectionOverrides.d.ts +22 -0
  163. package/dist/plugin/registerCollections.js +68 -0
  164. package/dist/plugin/registerCollections.js.map +1 -0
  165. package/dist/plugin/registerTranslations.js +19 -0
  166. package/dist/plugin/registerTranslations.js.map +1 -0
  167. package/dist/prefill/valuesFromSearchParams.d.ts +18 -0
  168. package/dist/prefill/valuesFromSearchParams.js +45 -0
  169. package/dist/prefill/valuesFromSearchParams.js.map +1 -0
  170. package/dist/presentations/defaults.d.ts +33 -0
  171. package/dist/presentations/defaults.js +35 -0
  172. package/dist/presentations/defaults.js.map +1 -0
  173. package/dist/presentations/registry.d.ts +15 -0
  174. package/dist/presentations/registry.js +15 -0
  175. package/dist/presentations/registry.js.map +1 -0
  176. package/dist/presentations/types.d.ts +18 -0
  177. package/dist/react/Form.d.ts +110 -0
  178. package/dist/react/Form.js +499 -0
  179. package/dist/react/Form.js.map +1 -0
  180. package/dist/react/FormContext.d.ts +16 -0
  181. package/dist/react/FormContext.js +14 -0
  182. package/dist/react/FormContext.js.map +1 -0
  183. package/dist/react/FormLayout.d.ts +20 -0
  184. package/dist/react/FormLayout.js +14 -0
  185. package/dist/react/FormLayout.js.map +1 -0
  186. package/dist/react/FormResults.d.ts +25 -0
  187. package/dist/react/FormResults.js +85 -0
  188. package/dist/react/FormResults.js.map +1 -0
  189. package/dist/react/Honeypot.d.ts +22 -0
  190. package/dist/react/Honeypot.js +38 -0
  191. package/dist/react/Honeypot.js.map +1 -0
  192. package/dist/react/Poll.d.ts +32 -0
  193. package/dist/react/Poll.js +77 -0
  194. package/dist/react/Poll.js.map +1 -0
  195. package/dist/react/cn.d.ts +6 -0
  196. package/dist/react/cn.js +8 -0
  197. package/dist/react/cn.js.map +1 -0
  198. package/dist/react/contract.d.ts +32 -0
  199. package/dist/react/contract.js +7 -0
  200. package/dist/react/contract.js.map +1 -0
  201. package/dist/react/events.js +14 -0
  202. package/dist/react/events.js.map +1 -0
  203. package/dist/react/fetchResults.d.ts +25 -0
  204. package/dist/react/fetchResults.js +31 -0
  205. package/dist/react/fetchResults.js.map +1 -0
  206. package/dist/react/presentation/Backdrop.d.ts +18 -0
  207. package/dist/react/presentation/Backdrop.js +14 -0
  208. package/dist/react/presentation/Backdrop.js.map +1 -0
  209. package/dist/react/presentation/DialogSurface.d.ts +35 -0
  210. package/dist/react/presentation/DialogSurface.js +56 -0
  211. package/dist/react/presentation/DialogSurface.js.map +1 -0
  212. package/dist/react/presentation/presentations.d.ts +7 -0
  213. package/dist/react/presentation/presentations.js +32 -0
  214. package/dist/react/presentation/presentations.js.map +1 -0
  215. package/dist/react/presentation/registry.d.ts +11 -0
  216. package/dist/react/presentation/registry.js +12 -0
  217. package/dist/react/presentation/registry.js.map +1 -0
  218. package/dist/react/presentation/types.d.ts +19 -0
  219. package/dist/react/presentation/useDismiss.d.ts +19 -0
  220. package/dist/react/presentation/useDismiss.js +33 -0
  221. package/dist/react/presentation/useDismiss.js.map +1 -0
  222. package/dist/react/presentation/useFocusTrap.d.ts +8 -0
  223. package/dist/react/presentation/useFocusTrap.js +35 -0
  224. package/dist/react/presentation/useFocusTrap.js.map +1 -0
  225. package/dist/react/presentation/useScrollLock.d.ts +6 -0
  226. package/dist/react/presentation/useScrollLock.js +18 -0
  227. package/dist/react/presentation/useScrollLock.js.map +1 -0
  228. package/dist/react/primitives/Checkbox.d.ts +26 -0
  229. package/dist/react/primitives/Checkbox.js +20 -0
  230. package/dist/react/primitives/Checkbox.js.map +1 -0
  231. package/dist/react/primitives/FieldShell.d.ts +31 -0
  232. package/dist/react/primitives/FieldShell.js +51 -0
  233. package/dist/react/primitives/FieldShell.js.map +1 -0
  234. package/dist/react/primitives/Input.d.ts +30 -0
  235. package/dist/react/primitives/Input.js +21 -0
  236. package/dist/react/primitives/Input.js.map +1 -0
  237. package/dist/react/primitives/Select.d.ts +34 -0
  238. package/dist/react/primitives/Select.js +26 -0
  239. package/dist/react/primitives/Select.js.map +1 -0
  240. package/dist/react/primitives/Textarea.d.ts +28 -0
  241. package/dist/react/primitives/Textarea.js +20 -0
  242. package/dist/react/primitives/Textarea.js.map +1 -0
  243. package/dist/react/recall.js +20 -0
  244. package/dist/react/recall.js.map +1 -0
  245. package/dist/react/registry.d.ts +16 -0
  246. package/dist/react/registry.js +16 -0
  247. package/dist/react/registry.js.map +1 -0
  248. package/dist/react/renderers/calculation.js +30 -0
  249. package/dist/react/renderers/calculation.js.map +1 -0
  250. package/dist/react/renderers/checkbox.js +35 -0
  251. package/dist/react/renderers/checkbox.js.map +1 -0
  252. package/dist/react/renderers/consent.js +54 -0
  253. package/dist/react/renderers/consent.js.map +1 -0
  254. package/dist/react/renderers/email.js +37 -0
  255. package/dist/react/renderers/email.js.map +1 -0
  256. package/dist/react/renderers/file.js +92 -0
  257. package/dist/react/renderers/file.js.map +1 -0
  258. package/dist/react/renderers/index.d.ts +8 -0
  259. package/dist/react/renderers/index.js +28 -0
  260. package/dist/react/renderers/index.js.map +1 -0
  261. package/dist/react/renderers/number.js +40 -0
  262. package/dist/react/renderers/number.js.map +1 -0
  263. package/dist/react/renderers/repeater.js +113 -0
  264. package/dist/react/renderers/repeater.js.map +1 -0
  265. package/dist/react/renderers/select.js +38 -0
  266. package/dist/react/renderers/select.js.map +1 -0
  267. package/dist/react/renderers/text.js +37 -0
  268. package/dist/react/renderers/text.js.map +1 -0
  269. package/dist/react/renderers/textarea.js +36 -0
  270. package/dist/react/renderers/textarea.js.map +1 -0
  271. package/dist/react/resolveForm.js +16 -0
  272. package/dist/react/resolveForm.js.map +1 -0
  273. package/dist/react/state.d.ts +15 -0
  274. package/dist/react/state.js +70 -0
  275. package/dist/react/state.js.map +1 -0
  276. package/dist/react/submitForm.d.ts +31 -0
  277. package/dist/react/submitForm.js +58 -0
  278. package/dist/react/submitForm.js.map +1 -0
  279. package/dist/react/toFormDocument.d.ts +24 -0
  280. package/dist/react/toFormDocument.js +22 -0
  281. package/dist/react/toFormDocument.js.map +1 -0
  282. package/dist/react/uploadFile.d.ts +23 -0
  283. package/dist/react/uploadFile.js +39 -0
  284. package/dist/react/uploadFile.js.map +1 -0
  285. package/dist/react/useField.d.ts +14 -0
  286. package/dist/react/useField.js +49 -0
  287. package/dist/react/useField.js.map +1 -0
  288. package/dist/react/useFormState.d.ts +8 -0
  289. package/dist/react/useFormState.js +9 -0
  290. package/dist/react/useFormState.js.map +1 -0
  291. package/dist/react/useFormStep.d.ts +8 -0
  292. package/dist/react/useFormStep.js +9 -0
  293. package/dist/react/useFormStep.js.map +1 -0
  294. package/dist/react/validateField.js +30 -0
  295. package/dist/react/validateField.js.map +1 -0
  296. package/dist/recall/interpolate.d.ts +10 -0
  297. package/dist/recall/interpolate.js +16 -0
  298. package/dist/recall/interpolate.js.map +1 -0
  299. package/dist/recall/resolver.d.ts +22 -0
  300. package/dist/recall/resolver.js +36 -0
  301. package/dist/recall/resolver.js.map +1 -0
  302. package/dist/spam/captcha.d.ts +12 -0
  303. package/dist/spam/captcha.js +11 -0
  304. package/dist/spam/captcha.js.map +1 -0
  305. package/dist/spam/constants.d.ts +12 -0
  306. package/dist/spam/constants.js +15 -0
  307. package/dist/spam/constants.js.map +1 -0
  308. package/dist/spam/identify.d.ts +12 -0
  309. package/dist/spam/identify.js +20 -0
  310. package/dist/spam/identify.js.map +1 -0
  311. package/dist/spam/rateLimiter.d.ts +18 -0
  312. package/dist/spam/rateLimiter.js +41 -0
  313. package/dist/spam/rateLimiter.js.map +1 -0
  314. package/dist/spam/reserved.js +30 -0
  315. package/dist/spam/reserved.js.map +1 -0
  316. package/dist/spam/resolveSpam.d.ts +12 -0
  317. package/dist/spam/resolveSpam.js +42 -0
  318. package/dist/spam/resolveSpam.js.map +1 -0
  319. package/dist/spam/spamGuard.js +68 -0
  320. package/dist/spam/spamGuard.js.map +1 -0
  321. package/dist/spam/types.d.ts +73 -0
  322. package/dist/spam/uploadHooks.js +33 -0
  323. package/dist/spam/uploadHooks.js.map +1 -0
  324. package/dist/submissions/SubmissionAnswers.d.ts +14 -0
  325. package/dist/submissions/SubmissionAnswers.js +133 -0
  326. package/dist/submissions/SubmissionAnswers.js.map +1 -0
  327. package/dist/submissions/SubmissionAnswersClient.js +142 -0
  328. package/dist/submissions/SubmissionAnswersClient.js.map +1 -0
  329. package/dist/submissions/runSubmission.js +257 -0
  330. package/dist/submissions/runSubmission.js.map +1 -0
  331. package/dist/submissions/types.d.ts +34 -0
  332. package/dist/submissions/validateSubmission.js +59 -0
  333. package/dist/submissions/validateSubmission.js.map +1 -0
  334. package/dist/translations/en.d.ts +12 -0
  335. package/dist/{translations-edMqq_2e.js → translations/en.js} +29 -23
  336. package/dist/translations/en.js.map +1 -0
  337. package/dist/translations/index.d.ts +14 -0
  338. package/dist/translations/index.js +26 -0
  339. package/dist/translations/index.js.map +1 -0
  340. package/dist/translations/keys.d.ts +157 -0
  341. package/dist/{keys-N5xGiUsh.js → translations/keys.js} +28 -3
  342. package/dist/translations/keys.js.map +1 -0
  343. package/dist/translations/makeTranslate.d.ts +11 -0
  344. package/dist/translations/makeTranslate.js +11 -0
  345. package/dist/translations/makeTranslate.js.map +1 -0
  346. package/dist/translations/server.js +25 -0
  347. package/dist/translations/server.js.map +1 -0
  348. package/dist/translations/useTranslation.js +12 -0
  349. package/dist/translations/useTranslation.js.map +1 -0
  350. package/dist/uploads/captureFileRef.d.ts +27 -0
  351. package/dist/uploads/captureFileRef.js +34 -0
  352. package/dist/uploads/captureFileRef.js.map +1 -0
  353. package/dist/uploads/resolveFileRef.d.ts +26 -0
  354. package/dist/uploads/resolveFileRef.js +44 -0
  355. package/dist/uploads/resolveFileRef.js.map +1 -0
  356. package/dist/uploads/types.d.ts +20 -0
  357. package/dist/validation/buildRuleBlocks.js +46 -0
  358. package/dist/validation/buildRuleBlocks.js.map +1 -0
  359. package/dist/validation/builtin/email.js +19 -0
  360. package/dist/validation/builtin/email.js.map +1 -0
  361. package/dist/validation/builtin/index.js +27 -0
  362. package/dist/validation/builtin/index.js.map +1 -0
  363. package/dist/validation/builtin/matchesField.js +20 -0
  364. package/dist/validation/builtin/matchesField.js.map +1 -0
  365. package/dist/validation/builtin/max.js +21 -0
  366. package/dist/validation/builtin/max.js.map +1 -0
  367. package/dist/validation/builtin/maxLength.js +26 -0
  368. package/dist/validation/builtin/maxLength.js.map +1 -0
  369. package/dist/validation/builtin/min.js +21 -0
  370. package/dist/validation/builtin/min.js.map +1 -0
  371. package/dist/validation/builtin/minLength.js +26 -0
  372. package/dist/validation/builtin/minLength.js.map +1 -0
  373. package/dist/validation/builtin/notAlreadySubmitted.js +32 -0
  374. package/dist/validation/builtin/notAlreadySubmitted.js.map +1 -0
  375. package/dist/validation/builtin/oneOf.js +34 -0
  376. package/dist/validation/builtin/oneOf.js.map +1 -0
  377. package/dist/validation/builtin/pattern.js +41 -0
  378. package/dist/validation/builtin/pattern.js.map +1 -0
  379. package/dist/validation/builtin/url.js +22 -0
  380. package/dist/validation/builtin/url.js.map +1 -0
  381. package/dist/validation/defineValidationRule.d.ts +12 -0
  382. package/dist/validation/defineValidationRule.js +11 -0
  383. package/dist/validation/defineValidationRule.js.map +1 -0
  384. package/dist/validation/message.js +14 -0
  385. package/dist/validation/message.js.map +1 -0
  386. package/dist/validation/registry.d.ts +10 -0
  387. package/dist/validation/registry.js +20 -0
  388. package/dist/validation/registry.js.map +1 -0
  389. package/dist/validation/runValidation.js +111 -0
  390. package/dist/validation/runValidation.js.map +1 -0
  391. package/dist/validation/types.d.ts +76 -0
  392. package/package.json +8 -5
  393. package/styles/form-builder.css +201 -11
  394. package/dist/constants-B-BUfetP.d.ts +0 -288
  395. package/dist/exports/client.js.map +0 -1
  396. package/dist/exports/react.js.map +0 -1
  397. package/dist/exports/rsc.js.map +0 -1
  398. package/dist/fieldTypes-B8jkNRob.d.ts +0 -188
  399. package/dist/fieldTypes-CzhhJXjg.js.map +0 -1
  400. package/dist/index-DfFYGbVF.d.ts +0 -481
  401. package/dist/keys-N5xGiUsh.js.map +0 -1
  402. package/dist/registry-CoCyhtvB.js +0 -282
  403. package/dist/registry-CoCyhtvB.js.map +0 -1
  404. package/dist/resolver-OeQyVH2N.js +0 -665
  405. package/dist/resolver-OeQyVH2N.js.map +0 -1
  406. package/dist/translations-edMqq_2e.js.map +0 -1
@@ -0,0 +1,499 @@
1
+ "use client";
2
+ import { interpolate } from "../recall/interpolate.js";
3
+ import { noopEventSink } from "../events/noopSink.js";
4
+ import { CAPTCHA_TOKEN_KEY } from "../spam/constants.js";
5
+ import { defaultPresentationDescriptors } from "../presentations/defaults.js";
6
+ import { calcExpressionOf, computeCalcFields } from "../calc/computeCalcFields.js";
7
+ import { evaluateCondition } from "../conditions/evaluate.js";
8
+ import { en } from "../translations/en.js";
9
+ import { buildRecallResolver } from "../recall/resolver.js";
10
+ import { firstStepId, isTerminalStepId, resolveNextStepId, stepFieldNames } from "../flow/engine.js";
11
+ import { cn } from "./cn.js";
12
+ import { makeTranslate } from "../translations/makeTranslate.js";
13
+ import { emitFormEvent } from "./events.js";
14
+ import { FormContext } from "./FormContext.js";
15
+ import { FormLayout, widthProps } from "./FormLayout.js";
16
+ import { Honeypot } from "./Honeypot.js";
17
+ import { defaultPresentations } from "./presentation/presentations.js";
18
+ import { resolvePresentations } from "./presentation/registry.js";
19
+ import { applyRecall } from "./recall.js";
20
+ import { resolveRenderers } from "./registry.js";
21
+ import { useField } from "./useField.js";
22
+ import { defaultRenderers } from "./renderers/index.js";
23
+ import { buildFieldTypeRegistry, buildValidationRuleRegistry, visibleFields } from "./resolveForm.js";
24
+ import { formReducer, initialFormState } from "./state.js";
25
+ import { submitForm } from "./submitForm.js";
26
+ import { validateFieldValue } from "./validateField.js";
27
+ import { createElement, useCallback, useEffect, useId, useMemo, useReducer, useRef, useState } from "react";
28
+ import { jsx, jsxs } from "react/jsx-runtime";
29
+ //#region src/react/Form.tsx
30
+ const isEmpty = (value) => value == null || value === "" || Array.isArray(value) && value.length === 0;
31
+ const FIELD_WIDTHS = new Set([
32
+ "full",
33
+ "half",
34
+ "third",
35
+ "twoThirds"
36
+ ]);
37
+ const FieldHost = ({ field, renderer, locale, t }) => {
38
+ const id = useId();
39
+ const { value, errors, warnings, setValue, onBlur } = useField(field.name);
40
+ return createElement(renderer, {
41
+ field,
42
+ id,
43
+ name: field.name,
44
+ value,
45
+ onChange: setValue,
46
+ onBlur,
47
+ errors,
48
+ warnings,
49
+ required: Boolean(field.required),
50
+ locale,
51
+ t
52
+ });
53
+ };
54
+ /** Hosts a derived (calc) field: read-only, value supplied from `effectiveValues`, never bound via `useField`. */
55
+ const CalcFieldHost = ({ field, renderer, value, locale, t }) => {
56
+ return createElement(renderer, {
57
+ field,
58
+ id: useId(),
59
+ name: field.name,
60
+ value,
61
+ onChange: () => {},
62
+ onBlur: () => {},
63
+ errors: [],
64
+ warnings: [],
65
+ required: false,
66
+ disabled: true,
67
+ locale,
68
+ t
69
+ });
70
+ };
71
+ /** The headless form controller: state, progressive client validation, conditional visibility, submission, events. */
72
+ const Form = ({ form, fieldTypes, rules, renderers, apiRoute, onSubmit, onSuccess, onError, events, t, locale = "en", layout, submitLabel = "Submit", nextLabel = "Next", backLabel = "Back", closeLabel = "Close", successMessage = "Thank you.", presentation, presentations, onClose, title, initialValues, honeypot, captchaToken, children, className, renderSubmit, renderNext, renderBack, submitButtonClassName, nextButtonClassName, backButtonClassName }) => {
73
+ const honeypotName = honeypot === false ? null : honeypot?.name ?? "website";
74
+ const honeypotRef = useRef(null);
75
+ const registry = useMemo(() => buildFieldTypeRegistry(fieldTypes), [fieldTypes]);
76
+ const ruleRegistry = useMemo(() => buildValidationRuleRegistry(rules), [rules]);
77
+ const rendererRegistry = useMemo(() => resolveRenderers(defaultRenderers, renderers), [renderers]);
78
+ const presentationRegistry = useMemo(() => resolvePresentations(defaultPresentations, presentations), [presentations]);
79
+ const activePresentation = typeof presentation === "object" ? presentation : presentationRegistry.get(presentation ?? form.defaultPresentation ?? "page") ?? presentationRegistry.get("page") ?? defaultPresentationDescriptors.page;
80
+ const fieldsByName = useMemo(() => new Map(form.fields.map((field) => [field.name, field])), [form.fields]);
81
+ const translate = useMemo(() => t ?? makeTranslate(en), [t]);
82
+ const sinkRef = useRef(noopEventSink);
83
+ sinkRef.current = events ?? noopEventSink;
84
+ const formIdRef = useRef("");
85
+ formIdRef.current = String(form.id);
86
+ const [state, rawDispatch] = useReducer(formReducer, form.fields, (fields) => initialFormState({
87
+ ...Object.fromEntries(fields.map((field) => [field.name, void 0])),
88
+ ...initialValues ?? {}
89
+ }));
90
+ const effectiveValues = useMemo(() => computeCalcFields(form.fields, state.values), [form.fields, state.values]);
91
+ const recall = useMemo(() => buildRecallResolver({
92
+ fields: form.fields,
93
+ values: effectiveValues,
94
+ registry,
95
+ locale,
96
+ t: translate
97
+ }), [
98
+ form.fields,
99
+ effectiveValues,
100
+ registry,
101
+ locale,
102
+ translate
103
+ ]);
104
+ const flow = form.flow && form.flow.steps.length >= 2 ? form.flow : void 0;
105
+ const [currentStepId, setCurrentStepId] = useState(() => flow ? firstStepId(flow) : void 0);
106
+ const [history, setHistory] = useState([]);
107
+ const startedRef = useRef(false);
108
+ const submittedRef = useRef(false);
109
+ const submittingRef = useRef(false);
110
+ const flowRef = useRef(flow);
111
+ flowRef.current = flow;
112
+ const dispatch = useCallback((action) => {
113
+ if (action.type === "SET_VALUE" && !startedRef.current) {
114
+ startedRef.current = true;
115
+ emitFormEvent(sinkRef.current, formIdRef.current, { type: "form.started" });
116
+ }
117
+ rawDispatch(action);
118
+ }, []);
119
+ const validateField = useCallback((name, value) => {
120
+ const field = fieldsByName.get(name);
121
+ if (!field) return;
122
+ const answers = {
123
+ ...effectiveValues,
124
+ [name]: value
125
+ };
126
+ if (!evaluateCondition(field.validateWhen, answers)) {
127
+ rawDispatch({
128
+ type: "SET_FIELD_ISSUES",
129
+ name,
130
+ errors: [],
131
+ warnings: []
132
+ });
133
+ return;
134
+ }
135
+ validateFieldValue({
136
+ field,
137
+ value,
138
+ registry,
139
+ ruleRegistry,
140
+ answers,
141
+ locale,
142
+ t: translate
143
+ }).then(({ errors, warnings }) => {
144
+ rawDispatch({
145
+ type: "SET_FIELD_ISSUES",
146
+ name,
147
+ errors,
148
+ warnings
149
+ });
150
+ const [firstError] = errors;
151
+ if (firstError !== void 0) emitFormEvent(sinkRef.current, formIdRef.current, {
152
+ type: "field.errored",
153
+ field: name,
154
+ message: firstError
155
+ });
156
+ });
157
+ }, [
158
+ fieldsByName,
159
+ effectiveValues,
160
+ registry,
161
+ ruleRegistry,
162
+ locale,
163
+ translate
164
+ ]);
165
+ const visible = visibleFields(form.fields, effectiveValues);
166
+ const stepVisible = (flow && currentStepId ? stepFieldNames(flow, currentStepId) : []).map((name) => visible.find((field) => field.name === name)).filter((field) => Boolean(field));
167
+ const goNext = async () => {
168
+ if (!flow || !currentStepId) return;
169
+ const results = await Promise.all(stepVisible.filter((field) => !calcExpressionOf(field)).filter((field) => evaluateCondition(field.validateWhen, effectiveValues)).map(async (field) => ({
170
+ field,
171
+ ...await validateFieldValue({
172
+ field,
173
+ value: effectiveValues[field.name],
174
+ registry,
175
+ ruleRegistry,
176
+ answers: effectiveValues,
177
+ locale,
178
+ t: translate
179
+ })
180
+ })));
181
+ let hasError = false;
182
+ for (const result of results) {
183
+ rawDispatch({
184
+ type: "TOUCH",
185
+ name: result.field.name
186
+ });
187
+ rawDispatch({
188
+ type: "SET_FIELD_ISSUES",
189
+ name: result.field.name,
190
+ errors: result.errors,
191
+ warnings: result.warnings
192
+ });
193
+ if (result.errors.length > 0) hasError = true;
194
+ }
195
+ if (hasError) return;
196
+ const next = resolveNextStepId(flow, currentStepId, state.values);
197
+ if (!next) return;
198
+ emitFormEvent(sinkRef.current, formIdRef.current, {
199
+ type: "step.completed",
200
+ stepId: currentStepId
201
+ });
202
+ setHistory((prev) => [...prev, currentStepId]);
203
+ setCurrentStepId(next);
204
+ emitFormEvent(sinkRef.current, formIdRef.current, {
205
+ type: "step.viewed",
206
+ stepId: next
207
+ });
208
+ };
209
+ const goBack = () => {
210
+ const prev = history[history.length - 1];
211
+ if (prev === void 0) return;
212
+ setHistory((entries) => entries.slice(0, -1));
213
+ setCurrentStepId(prev);
214
+ emitFormEvent(sinkRef.current, formIdRef.current, {
215
+ type: "step.viewed",
216
+ stepId: prev
217
+ });
218
+ };
219
+ useEffect(() => {
220
+ emitFormEvent(sinkRef.current, formIdRef.current, { type: "form.viewed" });
221
+ const mountFlow = flowRef.current;
222
+ if (mountFlow) {
223
+ const first = firstStepId(mountFlow);
224
+ if (first) emitFormEvent(sinkRef.current, formIdRef.current, {
225
+ type: "step.viewed",
226
+ stepId: first
227
+ });
228
+ }
229
+ return () => {
230
+ if (!submittedRef.current && !submittingRef.current) emitFormEvent(sinkRef.current, formIdRef.current, { type: "form.abandoned" });
231
+ };
232
+ }, []);
233
+ const handleClose = useCallback(() => {
234
+ onClose?.();
235
+ }, [onClose]);
236
+ const handleSubmit = async (event) => {
237
+ event.preventDefault();
238
+ if (submittingRef.current) return;
239
+ submittingRef.current = true;
240
+ const visible = visibleFields(form.fields, effectiveValues);
241
+ const results = await Promise.all(visible.filter((field) => !calcExpressionOf(field)).filter((field) => evaluateCondition(field.validateWhen, effectiveValues)).map(async (field) => ({
242
+ field,
243
+ ...await validateFieldValue({
244
+ field,
245
+ value: effectiveValues[field.name],
246
+ registry,
247
+ ruleRegistry,
248
+ answers: effectiveValues,
249
+ locale,
250
+ t: translate
251
+ })
252
+ })));
253
+ const errors = {};
254
+ const warnings = {};
255
+ for (const result of results) {
256
+ if (result.errors.length > 0) {
257
+ errors[result.field.name] = result.errors;
258
+ const [firstError] = result.errors;
259
+ if (firstError !== void 0) emitFormEvent(sinkRef.current, formIdRef.current, {
260
+ type: "field.errored",
261
+ field: result.field.name,
262
+ message: firstError
263
+ });
264
+ }
265
+ if (result.warnings.length > 0) warnings[result.field.name] = result.warnings;
266
+ }
267
+ for (const field of visible.filter((f) => f.blockType === "repeater")) {
268
+ const rows = Array.isArray(effectiveValues[field.name]) ? effectiveValues[field.name] : [];
269
+ const subFields = Array.isArray(field.subFields) ? field.subFields : [];
270
+ for (let rowIndex = 0; rowIndex < rows.length; rowIndex++) {
271
+ const row = rows[rowIndex] ?? {};
272
+ for (const subField of subFields) {
273
+ if (!evaluateCondition(subField.visibleWhen, row)) continue;
274
+ if (!evaluateCondition(subField.validateWhen, row)) continue;
275
+ const subResult = await validateFieldValue({
276
+ field: subField,
277
+ value: row[subField.name],
278
+ registry,
279
+ ruleRegistry,
280
+ answers: row,
281
+ locale,
282
+ t: translate
283
+ });
284
+ const compositeKey = `${field.name}[${rowIndex}].${subField.name}`;
285
+ if (subResult.errors.length > 0) errors[compositeKey] = subResult.errors;
286
+ if (subResult.warnings.length > 0) warnings[compositeKey] = subResult.warnings;
287
+ }
288
+ }
289
+ }
290
+ rawDispatch({
291
+ type: "SET_ALL_ISSUES",
292
+ errors,
293
+ warnings
294
+ });
295
+ if (Object.keys(errors).length > 0) {
296
+ submittingRef.current = false;
297
+ return;
298
+ }
299
+ rawDispatch({ type: "SUBMIT_START" });
300
+ const values = visible.filter((field) => !isEmpty(effectiveValues[field.name])).map((field) => ({
301
+ field: field.name,
302
+ value: effectiveValues[field.name]
303
+ }));
304
+ if (honeypotName) {
305
+ const decoy = honeypotRef.current?.value ?? "";
306
+ if (decoy !== "") values.push({
307
+ field: honeypotName,
308
+ value: decoy
309
+ });
310
+ }
311
+ if (captchaToken) values.push({
312
+ field: CAPTCHA_TOKEN_KEY,
313
+ value: captchaToken
314
+ });
315
+ const result = onSubmit ? await onSubmit({
316
+ formId: form.id,
317
+ values
318
+ }) : await submitForm({
319
+ formId: form.id,
320
+ values,
321
+ apiRoute
322
+ });
323
+ submittingRef.current = false;
324
+ if (result.ok) {
325
+ submittedRef.current = true;
326
+ rawDispatch({ type: "SUBMIT_SUCCESS" });
327
+ emitFormEvent(sinkRef.current, formIdRef.current, {
328
+ type: "submission.created",
329
+ submissionId: result.submissionId
330
+ });
331
+ onSuccess?.(result.submissionId);
332
+ if (activePresentation.dismissOnSuccess) handleClose();
333
+ } else {
334
+ if (result.fieldErrors) rawDispatch({
335
+ type: "SET_ALL_ISSUES",
336
+ errors: result.fieldErrors,
337
+ warnings: {}
338
+ });
339
+ const message = result.message ?? "Submission failed";
340
+ rawDispatch({
341
+ type: "SUBMIT_ERROR",
342
+ message
343
+ });
344
+ onError?.(message);
345
+ }
346
+ };
347
+ const step = flow ? {
348
+ flow,
349
+ currentStepId,
350
+ stepIndex: flow.steps.findIndex((s) => s.id === currentStepId),
351
+ stepCount: flow.steps.length,
352
+ isFirst: history.length === 0,
353
+ isTerminal: currentStepId ? isTerminalStepId(flow, currentStepId, state.values) : true,
354
+ goNext: () => {
355
+ goNext();
356
+ },
357
+ goBack
358
+ } : {
359
+ stepIndex: 0,
360
+ stepCount: 1,
361
+ isFirst: true,
362
+ isTerminal: true,
363
+ goNext: () => {},
364
+ goBack: () => {}
365
+ };
366
+ const contextValue = {
367
+ state,
368
+ dispatch,
369
+ validateField,
370
+ locale,
371
+ step,
372
+ rendererRegistry
373
+ };
374
+ const PresentationWrapper = activePresentation.Wrapper;
375
+ const wrap = (content) => PresentationWrapper ? /* @__PURE__ */ jsx(PresentationWrapper, {
376
+ presentation: activePresentation,
377
+ open: true,
378
+ onClose: handleClose,
379
+ title,
380
+ closeLabel,
381
+ children: content
382
+ }) : content;
383
+ if (children !== void 0) return /* @__PURE__ */ jsx(FormContext.Provider, {
384
+ value: contextValue,
385
+ children: wrap(/* @__PURE__ */ jsxs("form", {
386
+ className: cn("fb-form-root", className),
387
+ noValidate: true,
388
+ onSubmit: handleSubmit,
389
+ "data-fb-presentation": activePresentation.name,
390
+ "data-fb-density": activePresentation.density,
391
+ children: [honeypotName ? /* @__PURE__ */ jsx(Honeypot, {
392
+ name: honeypotName,
393
+ inputRef: honeypotRef
394
+ }) : null, children]
395
+ }))
396
+ });
397
+ if (state.submitted) return /* @__PURE__ */ jsx(FormContext.Provider, {
398
+ value: contextValue,
399
+ children: wrap(/* @__PURE__ */ jsx("p", {
400
+ role: "status",
401
+ className: cn("fb-form__success", className),
402
+ "data-fb-presentation": activePresentation.name,
403
+ "data-fb-density": activePresentation.density,
404
+ children: interpolate(successMessage, recall)
405
+ }))
406
+ });
407
+ const rendered = (flow ? stepVisible : visible).filter((field) => field.hidden !== true && field.calcDisplay !== false);
408
+ return /* @__PURE__ */ jsx(FormContext.Provider, {
409
+ value: contextValue,
410
+ children: wrap(/* @__PURE__ */ jsxs("form", {
411
+ className: cn("fb-form-root", className),
412
+ noValidate: true,
413
+ onSubmit: handleSubmit,
414
+ "data-fb-presentation": activePresentation.name,
415
+ "data-fb-density": activePresentation.density,
416
+ children: [
417
+ honeypotName ? /* @__PURE__ */ jsx(Honeypot, {
418
+ name: honeypotName,
419
+ inputRef: honeypotRef
420
+ }) : null,
421
+ /* @__PURE__ */ jsx(FormLayout, {
422
+ enabled: layout !== false,
423
+ children: rendered.map((field) => {
424
+ const renderer = rendererRegistry.get(field.blockType);
425
+ if (!renderer) return null;
426
+ const width = typeof field.width === "string" && FIELD_WIDTHS.has(field.width) ? field.width : void 0;
427
+ const recalledField = applyRecall(field, recall);
428
+ return /* @__PURE__ */ jsx("div", {
429
+ ...widthProps(width),
430
+ children: calcExpressionOf(field) ? /* @__PURE__ */ jsx(CalcFieldHost, {
431
+ field: recalledField,
432
+ renderer,
433
+ value: effectiveValues[field.name],
434
+ locale,
435
+ t: translate
436
+ }) : /* @__PURE__ */ jsx(FieldHost, {
437
+ field: recalledField,
438
+ renderer,
439
+ locale,
440
+ t: translate
441
+ })
442
+ }, field.name);
443
+ })
444
+ }),
445
+ state.submitError ? /* @__PURE__ */ jsx("p", {
446
+ role: "alert",
447
+ className: "fb-form__submit-error",
448
+ children: state.submitError
449
+ }) : null,
450
+ flow ? /* @__PURE__ */ jsxs("div", {
451
+ className: "fb-form__controls",
452
+ children: [!step.isFirst ? renderBack ? renderBack({
453
+ label: backLabel,
454
+ submitting: state.submitting,
455
+ onClick: goBack
456
+ }) : /* @__PURE__ */ jsx("button", {
457
+ type: "button",
458
+ className: backButtonClassName,
459
+ onClick: goBack,
460
+ disabled: state.submitting,
461
+ children: backLabel
462
+ }) : null, step.isTerminal ? renderSubmit ? renderSubmit({
463
+ label: submitLabel,
464
+ submitting: state.submitting
465
+ }) : /* @__PURE__ */ jsx("button", {
466
+ type: "submit",
467
+ className: submitButtonClassName,
468
+ disabled: state.submitting,
469
+ children: submitLabel
470
+ }) : renderNext ? renderNext({
471
+ label: nextLabel,
472
+ submitting: state.submitting,
473
+ onClick: () => void goNext()
474
+ }) : /* @__PURE__ */ jsx("button", {
475
+ type: "button",
476
+ className: nextButtonClassName,
477
+ disabled: state.submitting,
478
+ onClick: () => {
479
+ goNext();
480
+ },
481
+ children: nextLabel
482
+ })]
483
+ }) : renderSubmit ? renderSubmit({
484
+ label: submitLabel,
485
+ submitting: state.submitting
486
+ }) : /* @__PURE__ */ jsx("button", {
487
+ type: "submit",
488
+ className: submitButtonClassName,
489
+ disabled: state.submitting,
490
+ children: submitLabel
491
+ })
492
+ ]
493
+ }))
494
+ });
495
+ };
496
+ //#endregion
497
+ export { Form };
498
+
499
+ //# sourceMappingURL=Form.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Form.js","names":[],"sources":["../../src/react/Form.tsx"],"sourcesContent":["'use client'\n\nimport {\n\tcreateElement,\n\ttype FormEvent as ReactFormEvent,\n\ttype ReactNode,\n\tuseCallback,\n\tuseEffect,\n\tuseId,\n\tuseMemo,\n\tuseReducer,\n\tuseRef,\n\tuseState,\n} from 'react'\nimport { calcExpressionOf, computeCalcFields } from '../calc/computeCalcFields'\nimport { evaluateCondition } from '../conditions/evaluate'\nimport { noopEventSink } from '../events/noopSink'\nimport type { FormEventSink } from '../events/types'\nimport type { AnyFormFieldDefinition } from '../fields/types'\nimport { firstStepId, isTerminalStepId, resolveNextStepId, stepFieldNames } from '../flow/engine'\nimport type { FormFlow } from '../flow/types'\nimport { defaultPresentationDescriptors } from '../presentations/defaults'\nimport { interpolate } from '../recall/interpolate'\nimport { buildRecallResolver } from '../recall/resolver'\nimport { CAPTCHA_TOKEN_KEY, DEFAULT_HONEYPOT_FIELD } from '../spam/constants'\nimport type { FormFieldInstance, SubmissionValue } from '../submissions/types'\nimport { en } from '../translations/en'\nimport { makeTranslate } from '../translations/makeTranslate'\nimport type { AnyValidationRuleDefinition } from '../validation/types'\nimport { cn } from './cn'\nimport type { FieldRenderer, RendererTranslate } from './contract'\nimport { emitFormEvent } from './events'\nimport { FormContext, type FormStepInfo } from './FormContext'\nimport { type FieldWidth, FormLayout, widthProps } from './FormLayout'\nimport { Honeypot } from './Honeypot'\nimport { defaultPresentations } from './presentation/presentations'\nimport { type PresentationsConfig, resolvePresentations } from './presentation/registry'\nimport type { FormPresentation } from './presentation/types'\nimport { applyRecall } from './recall'\nimport { type RenderersConfig, resolveRenderers } from './registry'\nimport { defaultRenderers } from './renderers'\nimport { buildFieldTypeRegistry, buildValidationRuleRegistry, visibleFields } from './resolveForm'\nimport { type FieldErrors, type FormAction, formReducer, initialFormState } from './state'\nimport { type SubmitFormResult, type SubmitHandler, submitForm } from './submitForm'\nimport { useField } from './useField'\nimport { validateFieldValue } from './validateField'\n\nexport type FormDocument = {\n\tid: number | string\n\tfields: FormFieldInstance[]\n\tflow?: FormFlow\n\t/** Stored presentation name; overridden by the `presentation` prop. */\n\tdefaultPresentation?: string\n}\n\n/** Props passed to `renderSubmit`. */\nexport type SubmitButtonRenderProps = {\n\tlabel: string\n\tsubmitting: boolean\n}\n\n/** Props passed to `renderNext`. */\nexport type NextButtonRenderProps = {\n\tlabel: string\n\tsubmitting: boolean\n\tonClick: () => void\n}\n\n/** Props passed to `renderBack`. */\nexport type BackButtonRenderProps = {\n\tlabel: string\n\tsubmitting: boolean\n\tonClick: () => void\n}\n\nexport type FormProps = {\n\tform: FormDocument\n\tfieldTypes?: AnyFormFieldDefinition[]\n\trules?: AnyValidationRuleDefinition[]\n\trenderers?: RenderersConfig\n\tapiRoute?: string\n\tonSubmit?: SubmitHandler\n\tonSuccess?: (submissionId?: string) => void\n\tonError?: (message: string) => void\n\tevents?: FormEventSink\n\tt?: RendererTranslate\n\tlocale?: string\n\tlayout?: boolean\n\tsubmitLabel?: string\n\tnextLabel?: string\n\tbackLabel?: string\n\t/** Label for the overlay close control (modal/drawer). */\n\tcloseLabel?: string\n\tsuccessMessage?: string\n\t/** Active presentation: a name into the registry or an inline presentation. Overrides the form's stored default. */\n\tpresentation?: string | FormPresentation\n\t/** Per-render presentation overrides merged onto the defaults (add, replace, or `false` to remove). */\n\tpresentations?: PresentationsConfig\n\t/** Invoked when an overlay presentation dismisses (close button, Escape, outside click, or `dismissOnSuccess`). */\n\tonClose?: () => void\n\t/** Accessible name for an overlay surface. */\n\ttitle?: string\n\t/** Seed initial field values (e.g. from `valuesFromSearchParams`). Still validated on submit. */\n\tinitialValues?: Record<string, unknown>\n\t/** Honeypot decoy (on by default). `false` removes it; `{ name }` matches a customized server `spam.honeypot.fieldName`. */\n\thoneypot?: false | { name?: string }\n\t/** A token from your captcha widget; verified server-side when a captcha provider is configured. */\n\tcaptchaToken?: string\n\t/** Custom layout: render fields with `useField`/`useFormState` instead of the auto-rendered field loop. */\n\tchildren?: ReactNode\n\t/** Additional CSS class names applied to the root `<form>` element (and the success node). */\n\tclassName?: string\n\t/** Replace the default submit button entirely. Receives the resolved label and submitting state. */\n\trenderSubmit?: (props: SubmitButtonRenderProps) => ReactNode\n\t/** Replace the default \"Next\" button in multi-step forms. */\n\trenderNext?: (props: NextButtonRenderProps) => ReactNode\n\t/** Replace the default \"Back\" button in multi-step forms. */\n\trenderBack?: (props: BackButtonRenderProps) => ReactNode\n\t/** CSS class forwarded to the default submit `<button>`. Ignored when `renderSubmit` is provided. */\n\tsubmitButtonClassName?: string\n\t/** CSS class forwarded to the default \"Next\" `<button>`. Ignored when `renderNext` is provided. */\n\tnextButtonClassName?: string\n\t/** CSS class forwarded to the default \"Back\" `<button>`. Ignored when `renderBack` is provided. */\n\tbackButtonClassName?: string\n}\n\nconst isEmpty = (value: unknown): boolean =>\n\tvalue == null || value === '' || (Array.isArray(value) && value.length === 0)\n\nconst FIELD_WIDTHS = new Set<string>(['full', 'half', 'third', 'twoThirds'])\n\ntype FieldHostProps = {\n\tfield: FormFieldInstance\n\trenderer: FieldRenderer\n\tlocale: string\n\tt: RendererTranslate\n}\n\nconst FieldHost = ({ field, renderer, locale, t }: FieldHostProps) => {\n\tconst id = useId()\n\tconst { value, errors, warnings, setValue, onBlur } = useField(field.name)\n\treturn createElement(renderer, {\n\t\tfield,\n\t\tid,\n\t\tname: field.name,\n\t\tvalue,\n\t\tonChange: setValue,\n\t\tonBlur,\n\t\terrors,\n\t\twarnings,\n\t\trequired: Boolean(field.required),\n\t\tlocale,\n\t\tt,\n\t})\n}\n\ntype CalcFieldHostProps = FieldHostProps & { value: unknown }\n\n/** Hosts a derived (calc) field: read-only, value supplied from `effectiveValues`, never bound via `useField`. */\nconst CalcFieldHost = ({ field, renderer, value, locale, t }: CalcFieldHostProps) => {\n\tconst id = useId()\n\treturn createElement(renderer, {\n\t\tfield,\n\t\tid,\n\t\tname: field.name,\n\t\tvalue,\n\t\tonChange: () => {},\n\t\tonBlur: () => {},\n\t\terrors: [],\n\t\twarnings: [],\n\t\trequired: false,\n\t\tdisabled: true,\n\t\tlocale,\n\t\tt,\n\t})\n}\n\n/** The headless form controller: state, progressive client validation, conditional visibility, submission, events. */\nexport const Form = ({\n\tform,\n\tfieldTypes,\n\trules,\n\trenderers,\n\tapiRoute,\n\tonSubmit,\n\tonSuccess,\n\tonError,\n\tevents,\n\tt,\n\tlocale = 'en',\n\tlayout,\n\tsubmitLabel = 'Submit',\n\tnextLabel = 'Next',\n\tbackLabel = 'Back',\n\tcloseLabel = 'Close',\n\tsuccessMessage = 'Thank you.',\n\tpresentation,\n\tpresentations,\n\tonClose,\n\ttitle,\n\tinitialValues,\n\thoneypot,\n\tcaptchaToken,\n\tchildren,\n\tclassName,\n\trenderSubmit,\n\trenderNext,\n\trenderBack,\n\tsubmitButtonClassName,\n\tnextButtonClassName,\n\tbackButtonClassName,\n}: FormProps) => {\n\tconst honeypotName = honeypot === false ? null : (honeypot?.name ?? DEFAULT_HONEYPOT_FIELD)\n\tconst honeypotRef = useRef<HTMLInputElement>(null)\n\tconst registry = useMemo(() => buildFieldTypeRegistry(fieldTypes), [fieldTypes])\n\tconst ruleRegistry = useMemo(() => buildValidationRuleRegistry(rules), [rules])\n\tconst rendererRegistry = useMemo(() => resolveRenderers(defaultRenderers, renderers), [renderers])\n\tconst presentationRegistry = useMemo(\n\t\t() => resolvePresentations(defaultPresentations, presentations),\n\t\t[presentations]\n\t)\n\tconst activePresentation: FormPresentation =\n\t\ttypeof presentation === 'object'\n\t\t\t? presentation\n\t\t\t: (presentationRegistry.get(presentation ?? form.defaultPresentation ?? 'page') ??\n\t\t\t\tpresentationRegistry.get('page') ??\n\t\t\t\tdefaultPresentationDescriptors.page)\n\tconst fieldsByName = useMemo(\n\t\t() => new Map(form.fields.map((field) => [field.name, field])),\n\t\t[form.fields]\n\t)\n\tconst translate = useMemo<RendererTranslate>(() => t ?? makeTranslate(en), [t])\n\n\t// Latest-value refs so event emission and the mount/unmount effect tolerate an inline `events` prop or a changing form id.\n\tconst sinkRef = useRef<FormEventSink>(noopEventSink)\n\tsinkRef.current = events ?? noopEventSink\n\tconst formIdRef = useRef('')\n\tformIdRef.current = String(form.id)\n\n\tconst [state, rawDispatch] = useReducer(formReducer, form.fields, (fields) =>\n\t\tinitialFormState({\n\t\t\t...Object.fromEntries(fields.map((field) => [field.name, undefined])),\n\t\t\t...(initialValues ?? {}),\n\t\t})\n\t)\n\n\t// Authoritative values for derived (calc) fields, recomputed from user answers on every change. The\n\t// server recomputes these too at submit; the client copy drives the live calc renderer, recall, and submit.\n\tconst effectiveValues = useMemo(\n\t\t() => computeCalcFields(form.fields, state.values),\n\t\t[form.fields, state.values]\n\t)\n\n\tconst recall = useMemo(\n\t\t() =>\n\t\t\tbuildRecallResolver({\n\t\t\t\tfields: form.fields,\n\t\t\t\tvalues: effectiveValues,\n\t\t\t\tregistry,\n\t\t\t\tlocale,\n\t\t\t\tt: translate,\n\t\t\t}),\n\t\t[form.fields, effectiveValues, registry, locale, translate]\n\t)\n\n\t// Multi-step is active only when a flow declares two or more steps; otherwise this is an ordinary single-step form.\n\tconst flow = form.flow && form.flow.steps.length >= 2 ? form.flow : undefined\n\tconst [currentStepId, setCurrentStepId] = useState<string | undefined>(() =>\n\t\tflow ? firstStepId(flow) : undefined\n\t)\n\tconst [history, setHistory] = useState<string[]>([])\n\n\tconst startedRef = useRef(false)\n\tconst submittedRef = useRef(false)\n\tconst submittingRef = useRef(false)\n\tconst flowRef = useRef(flow)\n\tflowRef.current = flow\n\n\tconst dispatch = useCallback((action: FormAction) => {\n\t\tif (action.type === 'SET_VALUE' && !startedRef.current) {\n\t\t\tstartedRef.current = true\n\t\t\temitFormEvent(sinkRef.current, formIdRef.current, { type: 'form.started' })\n\t\t}\n\t\trawDispatch(action)\n\t}, [])\n\n\tconst validateField = useCallback(\n\t\t(name: string, value: unknown) => {\n\t\t\tconst field = fieldsByName.get(name)\n\t\t\tif (!field) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst answers = { ...effectiveValues, [name]: value }\n\t\t\t// Mirror the server: a field whose `validateWhen` is unmet is not validated; clear any stale error.\n\t\t\tif (!evaluateCondition(field.validateWhen, answers)) {\n\t\t\t\trawDispatch({ type: 'SET_FIELD_ISSUES', name, errors: [], warnings: [] })\n\t\t\t\treturn\n\t\t\t}\n\t\t\tvoid validateFieldValue({\n\t\t\t\tfield,\n\t\t\t\tvalue,\n\t\t\t\tregistry,\n\t\t\t\truleRegistry,\n\t\t\t\tanswers,\n\t\t\t\tlocale,\n\t\t\t\tt: translate,\n\t\t\t}).then(({ errors, warnings }) => {\n\t\t\t\trawDispatch({ type: 'SET_FIELD_ISSUES', name, errors, warnings })\n\t\t\t\tconst [firstError] = errors\n\t\t\t\tif (firstError !== undefined) {\n\t\t\t\t\temitFormEvent(sinkRef.current, formIdRef.current, {\n\t\t\t\t\t\ttype: 'field.errored',\n\t\t\t\t\t\tfield: name,\n\t\t\t\t\t\tmessage: firstError,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\t\t[fieldsByName, effectiveValues, registry, ruleRegistry, locale, translate]\n\t)\n\n\tconst visible = visibleFields(form.fields, effectiveValues)\n\tconst stepNames = flow && currentStepId ? stepFieldNames(flow, currentStepId) : []\n\tconst stepVisible: FormFieldInstance[] = stepNames\n\t\t.map((name) => visible.find((field) => field.name === name))\n\t\t.filter((field): field is FormFieldInstance => Boolean(field))\n\n\tconst goNext = async () => {\n\t\tif (!flow || !currentStepId) {\n\t\t\treturn\n\t\t}\n\t\tconst results = await Promise.all(\n\t\t\tstepVisible\n\t\t\t\t.filter((field) => !calcExpressionOf(field))\n\t\t\t\t.filter((field) => evaluateCondition(field.validateWhen, effectiveValues))\n\t\t\t\t.map(async (field) => ({\n\t\t\t\t\tfield,\n\t\t\t\t\t...(await validateFieldValue({\n\t\t\t\t\t\tfield,\n\t\t\t\t\t\tvalue: effectiveValues[field.name],\n\t\t\t\t\t\tregistry,\n\t\t\t\t\t\truleRegistry,\n\t\t\t\t\t\tanswers: effectiveValues,\n\t\t\t\t\t\tlocale,\n\t\t\t\t\t\tt: translate,\n\t\t\t\t\t})),\n\t\t\t\t}))\n\t\t)\n\t\tlet hasError = false\n\t\tfor (const result of results) {\n\t\t\trawDispatch({ type: 'TOUCH', name: result.field.name })\n\t\t\trawDispatch({\n\t\t\t\ttype: 'SET_FIELD_ISSUES',\n\t\t\t\tname: result.field.name,\n\t\t\t\terrors: result.errors,\n\t\t\t\twarnings: result.warnings,\n\t\t\t})\n\t\t\tif (result.errors.length > 0) {\n\t\t\t\thasError = true\n\t\t\t}\n\t\t}\n\t\tif (hasError) {\n\t\t\treturn\n\t\t}\n\t\tconst next = resolveNextStepId(flow, currentStepId, state.values)\n\t\tif (!next) {\n\t\t\treturn\n\t\t}\n\t\temitFormEvent(sinkRef.current, formIdRef.current, {\n\t\t\ttype: 'step.completed',\n\t\t\tstepId: currentStepId,\n\t\t})\n\t\tsetHistory((prev) => [...prev, currentStepId])\n\t\tsetCurrentStepId(next)\n\t\temitFormEvent(sinkRef.current, formIdRef.current, { type: 'step.viewed', stepId: next })\n\t}\n\n\tconst goBack = () => {\n\t\tconst prev = history[history.length - 1]\n\t\tif (prev === undefined) {\n\t\t\treturn\n\t\t}\n\t\tsetHistory((entries) => entries.slice(0, -1))\n\t\tsetCurrentStepId(prev)\n\t\temitFormEvent(sinkRef.current, formIdRef.current, { type: 'step.viewed', stepId: prev })\n\t}\n\n\tuseEffect(() => {\n\t\temitFormEvent(sinkRef.current, formIdRef.current, { type: 'form.viewed' })\n\t\tconst mountFlow = flowRef.current\n\t\tif (mountFlow) {\n\t\t\tconst first = firstStepId(mountFlow)\n\t\t\tif (first) {\n\t\t\t\temitFormEvent(sinkRef.current, formIdRef.current, { type: 'step.viewed', stepId: first })\n\t\t\t}\n\t\t}\n\t\treturn () => {\n\t\t\tif (!submittedRef.current && !submittingRef.current) {\n\t\t\t\temitFormEvent(sinkRef.current, formIdRef.current, { type: 'form.abandoned' })\n\t\t\t}\n\t\t}\n\t}, [])\n\n\tconst handleClose = useCallback(() => {\n\t\tonClose?.()\n\t}, [onClose])\n\n\tconst handleSubmit = async (event: ReactFormEvent<HTMLFormElement>) => {\n\t\tevent.preventDefault()\n\t\t// Re-entrancy guard: claim the in-flight slot before the async validation window so a fast second\n\t\t// activation (double-click, Enter + click) cannot reach the transport and POST the submission twice.\n\t\tif (submittingRef.current) {\n\t\t\treturn\n\t\t}\n\t\tsubmittingRef.current = true\n\t\tconst visible = visibleFields(form.fields, effectiveValues)\n\t\tconst results = await Promise.all(\n\t\t\t// Calc fields carry no rules and have no input; they are always satisfied, so skip validating them.\n\t\t\t// A field whose `validateWhen` is unmet is skipped too, mirroring the server (no client/server divergence).\n\t\t\tvisible\n\t\t\t\t.filter((field) => !calcExpressionOf(field))\n\t\t\t\t.filter((field) => evaluateCondition(field.validateWhen, effectiveValues))\n\t\t\t\t.map(async (field) => ({\n\t\t\t\t\tfield,\n\t\t\t\t\t...(await validateFieldValue({\n\t\t\t\t\t\tfield,\n\t\t\t\t\t\tvalue: effectiveValues[field.name],\n\t\t\t\t\t\tregistry,\n\t\t\t\t\t\truleRegistry,\n\t\t\t\t\t\tanswers: effectiveValues,\n\t\t\t\t\t\tlocale,\n\t\t\t\t\t\tt: translate,\n\t\t\t\t\t})),\n\t\t\t\t}))\n\t\t)\n\t\tconst errors: FieldErrors = {}\n\t\tconst warnings: FieldErrors = {}\n\t\tfor (const result of results) {\n\t\t\tif (result.errors.length > 0) {\n\t\t\t\terrors[result.field.name] = result.errors\n\t\t\t\tconst [firstError] = result.errors\n\t\t\t\tif (firstError !== undefined) {\n\t\t\t\t\temitFormEvent(sinkRef.current, formIdRef.current, {\n\t\t\t\t\t\ttype: 'field.errored',\n\t\t\t\t\t\tfield: result.field.name,\n\t\t\t\t\t\tmessage: firstError,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (result.warnings.length > 0) {\n\t\t\t\twarnings[result.field.name] = result.warnings\n\t\t\t}\n\t\t}\n\n\t\t// Validate sub-fields within each visible repeater, mirroring the server's per-row pass.\n\t\t// Errors are stored under the composite key `fieldName[rowIndex].subFieldName` so the\n\t\t// repeater renderer can look them up from form state and display them inline.\n\t\tfor (const field of visible.filter((f) => f.blockType === 'repeater')) {\n\t\t\tconst rows = Array.isArray(effectiveValues[field.name])\n\t\t\t\t? (effectiveValues[field.name] as Array<Record<string, unknown>>)\n\t\t\t\t: []\n\t\t\tconst subFields = Array.isArray(field.subFields)\n\t\t\t\t? (field.subFields as FormFieldInstance[])\n\t\t\t\t: []\n\t\t\tfor (let rowIndex = 0; rowIndex < rows.length; rowIndex++) {\n\t\t\t\tconst row = rows[rowIndex] ?? {}\n\t\t\t\tfor (const subField of subFields) {\n\t\t\t\t\tif (!evaluateCondition(subField.visibleWhen, row)) continue\n\t\t\t\t\tif (!evaluateCondition(subField.validateWhen, row)) continue\n\t\t\t\t\tconst subResult = await validateFieldValue({\n\t\t\t\t\t\tfield: subField,\n\t\t\t\t\t\tvalue: row[subField.name],\n\t\t\t\t\t\tregistry,\n\t\t\t\t\t\truleRegistry,\n\t\t\t\t\t\tanswers: row,\n\t\t\t\t\t\tlocale,\n\t\t\t\t\t\tt: translate,\n\t\t\t\t\t})\n\t\t\t\t\tconst compositeKey = `${field.name}[${rowIndex}].${subField.name}`\n\t\t\t\t\tif (subResult.errors.length > 0) errors[compositeKey] = subResult.errors\n\t\t\t\t\tif (subResult.warnings.length > 0) warnings[compositeKey] = subResult.warnings\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\trawDispatch({ type: 'SET_ALL_ISSUES', errors, warnings })\n\t\tif (Object.keys(errors).length > 0) {\n\t\t\tsubmittingRef.current = false\n\t\t\treturn\n\t\t}\n\t\trawDispatch({ type: 'SUBMIT_START' })\n\t\tconst values: SubmissionValue[] = visible\n\t\t\t.filter((field) => !isEmpty(effectiveValues[field.name]))\n\t\t\t.map((field) => ({ field: field.name, value: effectiveValues[field.name] }))\n\t\tif (honeypotName) {\n\t\t\tconst decoy = honeypotRef.current?.value ?? ''\n\t\t\tif (decoy !== '') {\n\t\t\t\tvalues.push({ field: honeypotName, value: decoy })\n\t\t\t}\n\t\t}\n\t\tif (captchaToken) {\n\t\t\tvalues.push({ field: CAPTCHA_TOKEN_KEY, value: captchaToken })\n\t\t}\n\t\tconst result: SubmitFormResult = onSubmit\n\t\t\t? await onSubmit({ formId: form.id, values })\n\t\t\t: await submitForm({ formId: form.id, values, apiRoute })\n\t\tsubmittingRef.current = false\n\t\tif (result.ok) {\n\t\t\tsubmittedRef.current = true\n\t\t\trawDispatch({ type: 'SUBMIT_SUCCESS' })\n\t\t\temitFormEvent(sinkRef.current, formIdRef.current, {\n\t\t\t\ttype: 'submission.created',\n\t\t\t\tsubmissionId: result.submissionId,\n\t\t\t})\n\t\t\tonSuccess?.(result.submissionId)\n\t\t\tif (activePresentation.dismissOnSuccess) {\n\t\t\t\thandleClose()\n\t\t\t}\n\t\t} else {\n\t\t\tif (result.fieldErrors) {\n\t\t\t\trawDispatch({ type: 'SET_ALL_ISSUES', errors: result.fieldErrors, warnings: {} })\n\t\t\t}\n\t\t\tconst message = result.message ?? 'Submission failed'\n\t\t\trawDispatch({ type: 'SUBMIT_ERROR', message })\n\t\t\tonError?.(message)\n\t\t}\n\t}\n\n\tconst step: FormStepInfo = flow\n\t\t? {\n\t\t\t\tflow,\n\t\t\t\tcurrentStepId,\n\t\t\t\tstepIndex: flow.steps.findIndex((s) => s.id === currentStepId),\n\t\t\t\tstepCount: flow.steps.length,\n\t\t\t\tisFirst: history.length === 0,\n\t\t\t\tisTerminal: currentStepId ? isTerminalStepId(flow, currentStepId, state.values) : true,\n\t\t\t\tgoNext: () => {\n\t\t\t\t\tvoid goNext()\n\t\t\t\t},\n\t\t\t\tgoBack,\n\t\t\t}\n\t\t: {\n\t\t\t\tstepIndex: 0,\n\t\t\t\tstepCount: 1,\n\t\t\t\tisFirst: true,\n\t\t\t\tisTerminal: true,\n\t\t\t\tgoNext: () => {},\n\t\t\t\tgoBack: () => {},\n\t\t\t}\n\n\tconst contextValue = { state, dispatch, validateField, locale, step, rendererRegistry }\n\n\tconst PresentationWrapper = activePresentation.Wrapper\n\tconst wrap = (content: ReactNode): ReactNode =>\n\t\tPresentationWrapper ? (\n\t\t\t<PresentationWrapper\n\t\t\t\tpresentation={activePresentation}\n\t\t\t\topen\n\t\t\t\tonClose={handleClose}\n\t\t\t\ttitle={title}\n\t\t\t\tcloseLabel={closeLabel}\n\t\t\t>\n\t\t\t\t{content}\n\t\t\t</PresentationWrapper>\n\t\t) : (\n\t\t\tcontent\n\t\t)\n\n\tif (children !== undefined) {\n\t\treturn (\n\t\t\t<FormContext.Provider value={contextValue}>\n\t\t\t\t{wrap(\n\t\t\t\t\t<form\n\t\t\t\t\t\tclassName={cn('fb-form-root', className)}\n\t\t\t\t\t\tnoValidate\n\t\t\t\t\t\tonSubmit={handleSubmit}\n\t\t\t\t\t\tdata-fb-presentation={activePresentation.name}\n\t\t\t\t\t\tdata-fb-density={activePresentation.density}\n\t\t\t\t\t>\n\t\t\t\t\t\t{honeypotName ? <Honeypot name={honeypotName} inputRef={honeypotRef} /> : null}\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</form>\n\t\t\t\t)}\n\t\t\t</FormContext.Provider>\n\t\t)\n\t}\n\n\tif (state.submitted) {\n\t\treturn (\n\t\t\t<FormContext.Provider value={contextValue}>\n\t\t\t\t{wrap(\n\t\t\t\t\t<p\n\t\t\t\t\t\trole=\"status\"\n\t\t\t\t\t\tclassName={cn('fb-form__success', className)}\n\t\t\t\t\t\tdata-fb-presentation={activePresentation.name}\n\t\t\t\t\t\tdata-fb-density={activePresentation.density}\n\t\t\t\t\t>\n\t\t\t\t\t\t{interpolate(successMessage, recall)}\n\t\t\t\t\t</p>\n\t\t\t\t)}\n\t\t\t</FormContext.Provider>\n\t\t)\n\t}\n\n\tconst rendered = (flow ? stepVisible : visible).filter(\n\t\t(field) => field.hidden !== true && field.calcDisplay !== false\n\t)\n\n\treturn (\n\t\t<FormContext.Provider value={contextValue}>\n\t\t\t{wrap(\n\t\t\t\t<form\n\t\t\t\t\tclassName={cn('fb-form-root', className)}\n\t\t\t\t\tnoValidate\n\t\t\t\t\tonSubmit={handleSubmit}\n\t\t\t\t\tdata-fb-presentation={activePresentation.name}\n\t\t\t\t\tdata-fb-density={activePresentation.density}\n\t\t\t\t>\n\t\t\t\t\t{honeypotName ? <Honeypot name={honeypotName} inputRef={honeypotRef} /> : null}\n\t\t\t\t\t<FormLayout enabled={layout !== false}>\n\t\t\t\t\t\t{rendered.map((field) => {\n\t\t\t\t\t\t\tconst renderer = rendererRegistry.get(field.blockType)\n\t\t\t\t\t\t\tif (!renderer) {\n\t\t\t\t\t\t\t\treturn null\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst width: FieldWidth | undefined =\n\t\t\t\t\t\t\t\ttypeof field.width === 'string' && FIELD_WIDTHS.has(field.width)\n\t\t\t\t\t\t\t\t\t? (field.width as FieldWidth)\n\t\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t\tconst recalledField = applyRecall(field, recall)\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<div key={field.name} {...widthProps(width)}>\n\t\t\t\t\t\t\t\t\t{calcExpressionOf(field) ? (\n\t\t\t\t\t\t\t\t\t\t<CalcFieldHost\n\t\t\t\t\t\t\t\t\t\t\tfield={recalledField}\n\t\t\t\t\t\t\t\t\t\t\trenderer={renderer}\n\t\t\t\t\t\t\t\t\t\t\tvalue={effectiveValues[field.name]}\n\t\t\t\t\t\t\t\t\t\t\tlocale={locale}\n\t\t\t\t\t\t\t\t\t\t\tt={translate}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t<FieldHost\n\t\t\t\t\t\t\t\t\t\t\tfield={recalledField}\n\t\t\t\t\t\t\t\t\t\t\trenderer={renderer}\n\t\t\t\t\t\t\t\t\t\t\tlocale={locale}\n\t\t\t\t\t\t\t\t\t\t\tt={translate}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t})}\n\t\t\t\t\t</FormLayout>\n\t\t\t\t\t{state.submitError ? (\n\t\t\t\t\t\t<p role=\"alert\" className=\"fb-form__submit-error\">\n\t\t\t\t\t\t\t{state.submitError}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{flow ? (\n\t\t\t\t\t\t<div className=\"fb-form__controls\">\n\t\t\t\t\t\t\t{!step.isFirst ? (\n\t\t\t\t\t\t\t\trenderBack ? (\n\t\t\t\t\t\t\t\t\trenderBack({ label: backLabel, submitting: state.submitting, onClick: goBack })\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclassName={backButtonClassName}\n\t\t\t\t\t\t\t\t\t\tonClick={goBack}\n\t\t\t\t\t\t\t\t\t\tdisabled={state.submitting}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{backLabel}\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t{step.isTerminal ? (\n\t\t\t\t\t\t\t\trenderSubmit ? (\n\t\t\t\t\t\t\t\t\trenderSubmit({ label: submitLabel, submitting: state.submitting })\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\t\t\t\t\tclassName={submitButtonClassName}\n\t\t\t\t\t\t\t\t\t\tdisabled={state.submitting}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{submitLabel}\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t) : renderNext ? (\n\t\t\t\t\t\t\t\trenderNext({\n\t\t\t\t\t\t\t\t\tlabel: nextLabel,\n\t\t\t\t\t\t\t\t\tsubmitting: state.submitting,\n\t\t\t\t\t\t\t\t\tonClick: () => void goNext(),\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclassName={nextButtonClassName}\n\t\t\t\t\t\t\t\t\tdisabled={state.submitting}\n\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\tvoid goNext()\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{nextLabel}\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : renderSubmit ? (\n\t\t\t\t\t\trenderSubmit({ label: submitLabel, submitting: state.submitting })\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<button type=\"submit\" className={submitButtonClassName} disabled={state.submitting}>\n\t\t\t\t\t\t\t{submitLabel}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t)}\n\t\t\t\t</form>\n\t\t\t)}\n\t\t</FormContext.Provider>\n\t)\n}\n"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { FormFlow } from "../flow/types.js";
2
+ //#region src/react/FormContext.d.ts
3
+ /** Multi-step navigation state. Defaults to a single terminal step when the form has no flow. */
4
+ type FormStepInfo = {
5
+ flow?: FormFlow;
6
+ currentStepId?: string;
7
+ stepIndex: number;
8
+ stepCount: number;
9
+ isFirst: boolean;
10
+ isTerminal: boolean;
11
+ goNext: () => void;
12
+ goBack: () => void;
13
+ };
14
+ //#endregion
15
+ export { FormStepInfo };
16
+ //# sourceMappingURL=FormContext.d.ts.map
@@ -0,0 +1,14 @@
1
+ "use client";
2
+ import { createContext, useContext } from "react";
3
+ //#region src/react/FormContext.ts
4
+ const FormContext = createContext(null);
5
+ /** Read the form controller context. Throws if used outside `<Form>`. */
6
+ const useFormContext = () => {
7
+ const context = useContext(FormContext);
8
+ if (!context) throw new Error("useFormContext must be used within a <Form>");
9
+ return context;
10
+ };
11
+ //#endregion
12
+ export { FormContext, useFormContext };
13
+
14
+ //# sourceMappingURL=FormContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FormContext.js","names":[],"sources":["../../src/react/FormContext.ts"],"sourcesContent":["'use client'\n\nimport type { Dispatch } from 'react'\nimport { createContext, useContext } from 'react'\nimport type { FormFlow } from '../flow/types'\nimport type { RendererRegistry } from './registry'\nimport type { FormAction, FormState } from './state'\n\n/** Multi-step navigation state. Defaults to a single terminal step when the form has no flow. */\nexport type FormStepInfo = {\n\tflow?: FormFlow\n\tcurrentStepId?: string\n\tstepIndex: number\n\tstepCount: number\n\tisFirst: boolean\n\tisTerminal: boolean\n\tgoNext: () => void\n\tgoBack: () => void\n}\n\nexport type FormContextValue = {\n\tstate: FormState\n\tdispatch: Dispatch<FormAction>\n\t/** Validate one field now (client mode) against the supplied value and store its issues. */\n\tvalidateField: (name: string, value: unknown) => void\n\tlocale: string\n\tstep: FormStepInfo\n\t/** The active renderer registry, exposed so nested renderers (e.g. repeater) can look up sub-renderers. */\n\trendererRegistry: RendererRegistry\n}\n\nexport const FormContext = createContext<FormContextValue | null>(null)\n\n/** Read the form controller context. Throws if used outside `<Form>`. */\nexport const useFormContext = (): FormContextValue => {\n\tconst context = useContext(FormContext)\n\tif (!context) {\n\t\tthrow new Error('useFormContext must be used within a <Form>')\n\t}\n\treturn context\n}\n"],"mappings":";;;AA+BA,MAAa,cAAc,cAAuC,IAAI;;AAGtE,MAAa,uBAAyC;CACrD,MAAM,UAAU,WAAW,WAAW;CACtC,IAAI,CAAC,SACJ,MAAM,IAAI,MAAM,6CAA6C;CAE9D,OAAO;AACR"}
@@ -0,0 +1,20 @@
1
+ import { ReactNode } from "react";
2
+
3
+ //#region src/react/FormLayout.d.ts
4
+ type FieldWidth = 'full' | 'half' | 'third' | 'twoThirds';
5
+ type FormLayoutProps = {
6
+ children: ReactNode; /** When false, render a plain container with no grid class (document-order layout). */
7
+ enabled?: boolean;
8
+ };
9
+ /** Establishes the layout container. With the stylesheet imported, children with `data-width` flow into a grid. */
10
+ declare const FormLayout: ({
11
+ children,
12
+ enabled
13
+ }: FormLayoutProps) => import("react/jsx-runtime").JSX.Element;
14
+ /** Props to spread onto a field wrapper to declare its grid width. */
15
+ declare const widthProps: (width: FieldWidth | undefined) => {
16
+ 'data-width': FieldWidth;
17
+ };
18
+ //#endregion
19
+ export { FieldWidth, FormLayout, FormLayoutProps, widthProps };
20
+ //# sourceMappingURL=FormLayout.d.ts.map
@@ -0,0 +1,14 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ //#region src/react/FormLayout.tsx
4
+ /** Establishes the layout container. With the stylesheet imported, children with `data-width` flow into a grid. */
5
+ const FormLayout = ({ children, enabled = true }) => /* @__PURE__ */ jsx("div", {
6
+ className: enabled ? "fb-form fb-form--grid" : "fb-form",
7
+ children
8
+ });
9
+ /** Props to spread onto a field wrapper to declare its grid width. */
10
+ const widthProps = (width) => ({ "data-width": width ?? "full" });
11
+ //#endregion
12
+ export { FormLayout, widthProps };
13
+
14
+ //# sourceMappingURL=FormLayout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FormLayout.js","names":[],"sources":["../../src/react/FormLayout.tsx"],"sourcesContent":["'use client'\n\nimport type { ReactNode } from 'react'\n\nexport type FieldWidth = 'full' | 'half' | 'third' | 'twoThirds'\n\nexport type FormLayoutProps = {\n\tchildren: ReactNode\n\t/** When false, render a plain container with no grid class (document-order layout). */\n\tenabled?: boolean\n}\n\n/** Establishes the layout container. With the stylesheet imported, children with `data-width` flow into a grid. */\nexport const FormLayout = ({ children, enabled = true }: FormLayoutProps) => (\n\t<div className={enabled ? 'fb-form fb-form--grid' : 'fb-form'}>{children}</div>\n)\n\n/** Props to spread onto a field wrapper to declare its grid width. */\nexport const widthProps = (width: FieldWidth | undefined) => ({ 'data-width': width ?? 'full' })\n"],"mappings":";;;;AAaA,MAAa,cAAc,EAAE,UAAU,UAAU,WAChD,oBAAC,OAAD;CAAK,WAAW,UAAU,0BAA0B;CAAY;AAAc,CAAA;;AAI/E,MAAa,cAAc,WAAmC,EAAE,cAAc,SAAS,OAAO"}