@10x-media/form-builder 0.1.0-beta.0 → 0.1.0-beta.10

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 (644) hide show
  1. package/CHANGELOG.md +345 -0
  2. package/README.md +45 -1402
  3. package/dist/actions/body/converters.d.ts +20 -0
  4. package/dist/actions/body/converters.js +57 -0
  5. package/dist/actions/body/converters.js.map +1 -0
  6. package/dist/actions/body/escapeHtml.d.ts +6 -0
  7. package/dist/actions/body/escapeHtml.js +14 -0
  8. package/dist/actions/body/escapeHtml.js.map +1 -0
  9. package/dist/actions/body/serializeBody.d.ts +55 -0
  10. package/dist/actions/body/serializeBody.js +78 -0
  11. package/dist/actions/body/serializeBody.js.map +1 -0
  12. package/dist/actions/body/serializeSlate.js +31 -0
  13. package/dist/actions/body/serializeSlate.js.map +1 -0
  14. package/dist/actions/body/textOfBody.d.ts +13 -0
  15. package/dist/actions/body/textOfBody.js +35 -0
  16. package/dist/actions/body/textOfBody.js.map +1 -0
  17. package/dist/actions/body/wildcards.d.ts +10 -0
  18. package/dist/actions/body/wildcards.js +33 -0
  19. package/dist/actions/body/wildcards.js.map +1 -0
  20. package/dist/actions/buildActionBlocks.js +22 -0
  21. package/dist/actions/buildActionBlocks.js.map +1 -0
  22. package/dist/actions/builtin/confirmation.js +52 -0
  23. package/dist/actions/builtin/confirmation.js.map +1 -0
  24. package/dist/actions/builtin/emailAction.d.ts +17 -0
  25. package/dist/actions/builtin/emailAction.js +83 -0
  26. package/dist/actions/builtin/emailAction.js.map +1 -0
  27. package/dist/actions/builtin/emailTeam.js +22 -0
  28. package/dist/actions/builtin/emailTeam.js.map +1 -0
  29. package/dist/actions/builtin/index.d.ts +22 -0
  30. package/dist/actions/builtin/index.js +27 -0
  31. package/dist/actions/builtin/index.js.map +1 -0
  32. package/dist/actions/builtin/signedWebhook.js +53 -0
  33. package/dist/actions/builtin/signedWebhook.js.map +1 -0
  34. package/dist/actions/defineAction.d.ts +37 -0
  35. package/dist/actions/defineAction.js +6 -0
  36. package/dist/actions/defineAction.js.map +1 -0
  37. package/dist/actions/dispatch.js +49 -0
  38. package/dist/actions/dispatch.js.map +1 -0
  39. package/dist/actions/emailRecipients.d.ts +12 -0
  40. package/dist/actions/emailRecipients.js +116 -0
  41. package/dist/actions/emailRecipients.js.map +1 -0
  42. package/dist/actions/fromAddresses.d.ts +21 -0
  43. package/dist/actions/fromAddresses.js +74 -0
  44. package/dist/actions/fromAddresses.js.map +1 -0
  45. package/dist/actions/registry.d.ts +17 -0
  46. package/dist/actions/registry.js +12 -0
  47. package/dist/actions/registry.js.map +1 -0
  48. package/dist/actions/runActions.d.ts +9 -0
  49. package/dist/actions/runActions.js +43 -0
  50. package/dist/actions/runActions.js.map +1 -0
  51. package/dist/actions/sign.d.ts +7 -0
  52. package/dist/actions/sign.js +9 -0
  53. package/dist/actions/sign.js.map +1 -0
  54. package/dist/actions/task.js +87 -0
  55. package/dist/actions/task.js.map +1 -0
  56. package/dist/aggregation/aggregateResponses.d.ts +40 -0
  57. package/dist/aggregation/aggregateResponses.js +80 -0
  58. package/dist/aggregation/aggregateResponses.js.map +1 -0
  59. package/dist/aggregation/aggregateRows.d.ts +10 -0
  60. package/dist/aggregation/aggregateRows.js +64 -0
  61. package/dist/aggregation/aggregateRows.js.map +1 -0
  62. package/dist/aggregation/resolveResultsRequest.d.ts +61 -0
  63. package/dist/aggregation/resolveResultsRequest.js +113 -0
  64. package/dist/aggregation/resolveResultsRequest.js.map +1 -0
  65. package/dist/aggregation/types.d.ts +39 -0
  66. package/dist/calc/computeCalcFields.d.ts +15 -0
  67. package/dist/calc/computeCalcFields.js +28 -0
  68. package/dist/calc/computeCalcFields.js.map +1 -0
  69. package/dist/calc/evaluate.d.ts +8 -0
  70. package/dist/calc/evaluate.js +58 -0
  71. package/dist/calc/evaluate.js.map +1 -0
  72. package/dist/calc/normalizeCalc.d.ts +8 -0
  73. package/dist/calc/normalizeCalc.js +87 -0
  74. package/dist/calc/normalizeCalc.js.map +1 -0
  75. package/dist/calc/types.d.ts +34 -0
  76. package/dist/calc/types.js +22 -0
  77. package/dist/calc/types.js.map +1 -0
  78. package/dist/client/ByteSizeField.d.ts +29 -0
  79. package/dist/client/ByteSizeField.js +58 -0
  80. package/dist/client/ByteSizeField.js.map +1 -0
  81. package/dist/client/ClosePollButton.d.ts +15 -0
  82. package/dist/client/ClosePollButton.js +80 -0
  83. package/dist/client/ClosePollButton.js.map +1 -0
  84. package/dist/client/CondensedArray.d.ts +15 -0
  85. package/dist/client/CondensedArray.js +97 -0
  86. package/dist/client/CondensedArray.js.map +1 -0
  87. package/dist/client/ConditionBuilder.js +122 -0
  88. package/dist/client/ConditionBuilder.js.map +1 -0
  89. package/dist/client/ConditionRow.js +150 -0
  90. package/dist/client/ConditionRow.js.map +1 -0
  91. package/dist/client/ConsentBlockLabel.d.ts +15 -0
  92. package/dist/client/ConsentBlockLabel.js +71 -0
  93. package/dist/client/ConsentBlockLabel.js.map +1 -0
  94. package/dist/client/ConsentSourceRowLabel.d.ts +9 -0
  95. package/dist/client/ConsentSourceRowLabel.js +21 -0
  96. package/dist/client/ConsentSourceRowLabel.js.map +1 -0
  97. package/dist/client/EndpointOptionsSelect.d.ts +46 -0
  98. package/dist/client/EndpointOptionsSelect.js +106 -0
  99. package/dist/client/EndpointOptionsSelect.js.map +1 -0
  100. package/dist/client/FieldBlockLabel.d.ts +18 -0
  101. package/dist/client/FieldBlockLabel.js +34 -0
  102. package/dist/client/FieldBlockLabel.js.map +1 -0
  103. package/dist/client/FieldNameSelect.d.ts +37 -0
  104. package/dist/client/FieldNameSelect.js +72 -0
  105. package/dist/client/FieldNameSelect.js.map +1 -0
  106. package/dist/client/FlowBuilder.d.ts +15 -0
  107. package/dist/client/FlowBuilder.js +457 -0
  108. package/dist/client/FlowBuilder.js.map +1 -0
  109. package/dist/client/FormConditionField.d.ts +21 -0
  110. package/dist/client/FormConditionField.js +30 -0
  111. package/dist/client/FormConditionField.js.map +1 -0
  112. package/dist/client/RecipientsSelect.d.ts +31 -0
  113. package/dist/client/RecipientsSelect.js +174 -0
  114. package/dist/client/RecipientsSelect.js.map +1 -0
  115. package/dist/client/RuleDescription.d.ts +21 -0
  116. package/dist/client/RuleDescription.js +19 -0
  117. package/dist/client/RuleDescription.js.map +1 -0
  118. package/dist/client/admin.css +275 -0
  119. package/dist/client/endpointOptions.js +29 -0
  120. package/dist/client/endpointOptions.js.map +1 -0
  121. package/dist/client/flowAuthoring.js +142 -0
  122. package/dist/client/flowAuthoring.js.map +1 -0
  123. package/dist/client/synthesizeClientField.js +57 -0
  124. package/dist/client/synthesizeClientField.js.map +1 -0
  125. package/dist/client/toStaticLabel.js +13 -0
  126. package/dist/client/toStaticLabel.js.map +1 -0
  127. package/dist/collections/buttonFields.d.ts +34 -0
  128. package/dist/collections/buttonFields.js +35 -0
  129. package/dist/collections/buttonFields.js.map +1 -0
  130. package/dist/collections/cells/FieldCountCell.d.ts +15 -0
  131. package/dist/collections/cells/FieldCountCell.js +18 -0
  132. package/dist/collections/cells/FieldCountCell.js.map +1 -0
  133. package/dist/collections/cells/FlowStepsCell.d.ts +14 -0
  134. package/dist/collections/cells/FlowStepsCell.js +17 -0
  135. package/dist/collections/cells/FlowStepsCell.js.map +1 -0
  136. package/dist/collections/formSubmissions.js +204 -0
  137. package/dist/collections/formSubmissions.js.map +1 -0
  138. package/dist/collections/forms.js +482 -0
  139. package/dist/collections/forms.js.map +1 -0
  140. package/dist/collections/formsEndpoints.js +101 -0
  141. package/dist/collections/formsEndpoints.js.map +1 -0
  142. package/dist/collections/redirectFields.d.ts +29 -0
  143. package/dist/conditions/conditionType.js +21 -0
  144. package/dist/conditions/conditionType.js.map +1 -0
  145. package/dist/conditions/evaluate.d.ts +17 -0
  146. package/dist/conditions/evaluate.js +94 -0
  147. package/dist/conditions/evaluate.js.map +1 -0
  148. package/dist/conditions/fieldTypes.d.ts +11 -0
  149. package/dist/{fieldTypes-CzhhJXjg.js → conditions/fieldTypes.js} +6 -3
  150. package/dist/conditions/fieldTypes.js.map +1 -0
  151. package/dist/conditions/normalizeConditions.js +61 -0
  152. package/dist/conditions/normalizeConditions.js.map +1 -0
  153. package/dist/conditions/types.d.ts +8 -0
  154. package/dist/consent/applyConsentStatements.d.ts +14 -0
  155. package/dist/consent/applyConsentStatements.js +17 -0
  156. package/dist/consent/applyConsentStatements.js.map +1 -0
  157. package/dist/consent/captureConsent.d.ts +55 -0
  158. package/dist/consent/captureConsent.js +73 -0
  159. package/dist/consent/captureConsent.js.map +1 -0
  160. package/dist/consent/consentSourcesField.d.ts +66 -0
  161. package/dist/consent/consentSourcesField.js +90 -0
  162. package/dist/consent/consentSourcesField.js.map +1 -0
  163. package/dist/consent/resolveConsentEntries.d.ts +24 -0
  164. package/dist/consent/resolveConsentEntries.js +40 -0
  165. package/dist/consent/resolveConsentEntries.js.map +1 -0
  166. package/dist/consent/resolveConsentSourcesRequest.d.ts +37 -0
  167. package/dist/consent/resolveConsentSourcesRequest.js +54 -0
  168. package/dist/consent/resolveConsentSourcesRequest.js.map +1 -0
  169. package/dist/consent/resolveConsentStatements.d.ts +45 -0
  170. package/dist/consent/resolveConsentStatements.js +44 -0
  171. package/dist/consent/resolveConsentStatements.js.map +1 -0
  172. package/dist/consent/resolvePublishedVersionRef.d.ts +23 -0
  173. package/dist/consent/resolvePublishedVersionRef.js +30 -0
  174. package/dist/consent/resolvePublishedVersionRef.js.map +1 -0
  175. package/dist/consent/types.d.ts +61 -0
  176. package/dist/email/departments.d.ts +59 -0
  177. package/dist/email/departments.js +87 -0
  178. package/dist/email/departments.js.map +1 -0
  179. package/dist/email/departmentsField.d.ts +53 -0
  180. package/dist/email/departmentsField.js +73 -0
  181. package/dist/email/departmentsField.js.map +1 -0
  182. package/dist/events/noopSink.js +6 -0
  183. package/dist/events/noopSink.js.map +1 -0
  184. package/dist/events/resolveEventSink.js +8 -0
  185. package/dist/events/resolveEventSink.js.map +1 -0
  186. package/dist/events/types.d.ts +31 -0
  187. package/dist/exports/client.d.ts +15 -21
  188. package/dist/exports/client.js +15 -319
  189. package/dist/exports/i18n.d.ts +6 -138
  190. package/dist/exports/i18n.js +6 -3
  191. package/dist/exports/react.d.ts +63 -550
  192. package/dist/exports/react.js +55 -1563
  193. package/dist/exports/rsc.d.ts +9 -16
  194. package/dist/exports/rsc.js +9 -55
  195. package/dist/exports/types.d.ts +36 -5
  196. package/dist/fields/buildFieldBlocks.js +80 -0
  197. package/dist/fields/buildFieldBlocks.js.map +1 -0
  198. package/dist/fields/builtin/calculation.js +144 -0
  199. package/dist/fields/builtin/calculation.js.map +1 -0
  200. package/dist/fields/builtin/checkbox.js +21 -0
  201. package/dist/fields/builtin/checkbox.js.map +1 -0
  202. package/dist/fields/builtin/consent.js +47 -0
  203. package/dist/fields/builtin/consent.js.map +1 -0
  204. package/dist/fields/builtin/country.d.ts +13 -0
  205. package/dist/fields/builtin/country.js +30 -0
  206. package/dist/fields/builtin/country.js.map +1 -0
  207. package/dist/fields/builtin/date.js +31 -0
  208. package/dist/fields/builtin/date.js.map +1 -0
  209. package/dist/fields/builtin/email.js +18 -0
  210. package/dist/fields/builtin/email.js.map +1 -0
  211. package/dist/fields/builtin/file.d.ts +15 -0
  212. package/dist/fields/builtin/file.js +127 -0
  213. package/dist/fields/builtin/file.js.map +1 -0
  214. package/dist/fields/builtin/index.d.ts +26 -0
  215. package/dist/fields/builtin/index.js +49 -0
  216. package/dist/fields/builtin/index.js.map +1 -0
  217. package/dist/fields/builtin/message.js +30 -0
  218. package/dist/fields/builtin/message.js.map +1 -0
  219. package/dist/fields/builtin/number.js +17 -0
  220. package/dist/fields/builtin/number.js.map +1 -0
  221. package/dist/fields/builtin/repeater.js +49 -0
  222. package/dist/fields/builtin/repeater.js.map +1 -0
  223. package/dist/fields/builtin/select.js +49 -0
  224. package/dist/fields/builtin/select.js.map +1 -0
  225. package/dist/fields/builtin/state.d.ts +13 -0
  226. package/dist/fields/builtin/state.js +30 -0
  227. package/dist/fields/builtin/state.js.map +1 -0
  228. package/dist/fields/builtin/text.js +13 -0
  229. package/dist/fields/builtin/text.js.map +1 -0
  230. package/dist/fields/builtin/textarea.js +13 -0
  231. package/dist/fields/builtin/textarea.js.map +1 -0
  232. package/dist/fields/data/regions.d.ts +21 -0
  233. package/dist/fields/data/regions.js +1238 -0
  234. package/dist/fields/data/regions.js.map +1 -0
  235. package/dist/fields/defineFormField.d.ts +13 -0
  236. package/dist/fields/defineFormField.js +12 -0
  237. package/dist/fields/defineFormField.js.map +1 -0
  238. package/dist/fields/fieldKey.d.ts +15 -0
  239. package/dist/fields/fieldKey.js +16 -0
  240. package/dist/fields/fieldKey.js.map +1 -0
  241. package/dist/fields/fieldNamesOfType.js +30 -0
  242. package/dist/fields/fieldNamesOfType.js.map +1 -0
  243. package/dist/fields/instanceOptions.js +20 -0
  244. package/dist/fields/instanceOptions.js.map +1 -0
  245. package/dist/fields/localizedIf.d.ts +13 -0
  246. package/dist/fields/localizedIf.js +12 -0
  247. package/dist/fields/localizedIf.js.map +1 -0
  248. package/dist/fields/registry.d.ts +12 -0
  249. package/dist/fields/registry.js +39 -0
  250. package/dist/fields/registry.js.map +1 -0
  251. package/dist/fields/sharedConfig.js +151 -0
  252. package/dist/fields/sharedConfig.js.map +1 -0
  253. package/dist/fields/types.d.ts +152 -0
  254. package/dist/flow/engine.d.ts +19 -0
  255. package/dist/flow/engine.js +29 -0
  256. package/dist/flow/engine.js.map +1 -0
  257. package/dist/flow/normalizeFlow.js +54 -0
  258. package/dist/flow/normalizeFlow.js.map +1 -0
  259. package/dist/flow/stepLabel.js +15 -0
  260. package/dist/flow/stepLabel.js.map +1 -0
  261. package/dist/flow/types.d.ts +32 -0
  262. package/dist/flow/types.js +11 -0
  263. package/dist/flow/types.js.map +1 -0
  264. package/dist/form/pollState.d.ts +22 -0
  265. package/dist/form/pollState.js +17 -0
  266. package/dist/form/pollState.js.map +1 -0
  267. package/dist/form/toFormDocument.d.ts +102 -0
  268. package/dist/form/toFormDocument.js +87 -0
  269. package/dist/form/toFormDocument.js.map +1 -0
  270. package/dist/form/types.d.ts +65 -0
  271. package/dist/index.d.ts +88 -4
  272. package/dist/index.js +111 -1898
  273. package/dist/index.js.map +1 -1
  274. package/dist/options.d.ts +229 -0
  275. package/dist/plugin/access.js +12 -0
  276. package/dist/plugin/access.js.map +1 -0
  277. package/dist/plugin/applyRegistryConfig.d.ts +11 -0
  278. package/dist/plugin/applyRegistryConfig.js +20 -0
  279. package/dist/plugin/applyRegistryConfig.js.map +1 -0
  280. package/dist/plugin/collectionOverrides.d.ts +22 -0
  281. package/dist/plugin/customState.js +26 -0
  282. package/dist/plugin/customState.js.map +1 -0
  283. package/dist/plugin/registerCollections.js +60 -0
  284. package/dist/plugin/registerCollections.js.map +1 -0
  285. package/dist/plugin/registerTranslations.js +19 -0
  286. package/dist/plugin/registerTranslations.js.map +1 -0
  287. package/dist/plugin/uploadsCollection.d.ts +16 -0
  288. package/dist/plugin/uploadsCollection.js +53 -0
  289. package/dist/plugin/uploadsCollection.js.map +1 -0
  290. package/dist/poll/applyPollOptions.js +18 -0
  291. package/dist/poll/applyPollOptions.js.map +1 -0
  292. package/dist/poll/buildPollOptionSourceFields.js +50 -0
  293. package/dist/poll/buildPollOptionSourceFields.js.map +1 -0
  294. package/dist/poll/closeJob.d.ts +52 -0
  295. package/dist/poll/closeJob.js +119 -0
  296. package/dist/poll/closeJob.js.map +1 -0
  297. package/dist/poll/definePollOptionSource.d.ts +44 -0
  298. package/dist/poll/definePollOptionSource.js +6 -0
  299. package/dist/poll/definePollOptionSource.js.map +1 -0
  300. package/dist/poll/definePollType.d.ts +34 -0
  301. package/dist/poll/definePollType.js +6 -0
  302. package/dist/poll/definePollType.js.map +1 -0
  303. package/dist/poll/effectivePollOptions.d.ts +38 -0
  304. package/dist/poll/effectivePollOptions.js +64 -0
  305. package/dist/poll/effectivePollOptions.js.map +1 -0
  306. package/dist/poll/mostVoted.d.ts +21 -0
  307. package/dist/poll/mostVoted.js +32 -0
  308. package/dist/poll/mostVoted.js.map +1 -0
  309. package/dist/poll/outcomeBeforeChange.js +91 -0
  310. package/dist/poll/outcomeBeforeChange.js.map +1 -0
  311. package/dist/poll/outcomeFields.d.ts +38 -0
  312. package/dist/poll/outcomeFields.js +52 -0
  313. package/dist/poll/outcomeFields.js.map +1 -0
  314. package/dist/poll/pollTypeRegistry.d.ts +34 -0
  315. package/dist/poll/pollTypeRegistry.js +69 -0
  316. package/dist/poll/pollTypeRegistry.js.map +1 -0
  317. package/dist/poll/registry.d.ts +17 -0
  318. package/dist/poll/registry.js +12 -0
  319. package/dist/poll/registry.js.map +1 -0
  320. package/dist/poll/resolvePollCloseRequest.js +105 -0
  321. package/dist/poll/resolvePollCloseRequest.js.map +1 -0
  322. package/dist/poll/resolvePollOptions.d.ts +29 -0
  323. package/dist/poll/resolvePollOptions.js +52 -0
  324. package/dist/poll/resolvePollOptions.js.map +1 -0
  325. package/dist/poll/resolvePollOptionsRequest.js +50 -0
  326. package/dist/poll/resolvePollOptionsRequest.js.map +1 -0
  327. package/dist/poll/resolvePollOutcome.d.ts +34 -0
  328. package/dist/poll/resolvePollOutcome.js +76 -0
  329. package/dist/poll/resolvePollOutcome.js.map +1 -0
  330. package/dist/poll/resultsField.js +21 -0
  331. package/dist/poll/resultsField.js.map +1 -0
  332. package/dist/prefill/valuesFromSearchParams.d.ts +18 -0
  333. package/dist/prefill/valuesFromSearchParams.js +41 -0
  334. package/dist/prefill/valuesFromSearchParams.js.map +1 -0
  335. package/dist/presentations/defaults.d.ts +33 -0
  336. package/dist/presentations/defaults.js +35 -0
  337. package/dist/presentations/defaults.js.map +1 -0
  338. package/dist/presentations/types.d.ts +19 -0
  339. package/dist/react/Form.d.ts +128 -0
  340. package/dist/react/Form.js +619 -0
  341. package/dist/react/Form.js.map +1 -0
  342. package/dist/react/FormContext.d.ts +59 -0
  343. package/dist/react/FormContext.js +14 -0
  344. package/dist/react/FormContext.js.map +1 -0
  345. package/dist/react/FormControls.d.ts +55 -0
  346. package/dist/react/FormControls.js +56 -0
  347. package/dist/react/FormControls.js.map +1 -0
  348. package/dist/react/FormFields.d.ts +18 -0
  349. package/dist/react/FormFields.js +114 -0
  350. package/dist/react/FormFields.js.map +1 -0
  351. package/dist/react/FormLayout.d.ts +22 -0
  352. package/dist/react/FormLayout.js +15 -0
  353. package/dist/react/FormLayout.js.map +1 -0
  354. package/dist/react/FormResults.d.ts +28 -0
  355. package/dist/react/FormResults.js +93 -0
  356. package/dist/react/FormResults.js.map +1 -0
  357. package/dist/react/FormSteps.d.ts +17 -0
  358. package/dist/react/FormSteps.js +35 -0
  359. package/dist/react/FormSteps.js.map +1 -0
  360. package/dist/react/Honeypot.d.ts +22 -0
  361. package/dist/react/Honeypot.js +38 -0
  362. package/dist/react/Honeypot.js.map +1 -0
  363. package/dist/react/Poll.d.ts +43 -0
  364. package/dist/react/Poll.js +135 -0
  365. package/dist/react/Poll.js.map +1 -0
  366. package/dist/react/captcha/HcaptchaCaptcha.d.ts +28 -0
  367. package/dist/react/captcha/HcaptchaCaptcha.js +53 -0
  368. package/dist/react/captcha/HcaptchaCaptcha.js.map +1 -0
  369. package/dist/react/captcha/RecaptchaCaptcha.d.ts +41 -0
  370. package/dist/react/captcha/RecaptchaCaptcha.js +93 -0
  371. package/dist/react/captcha/RecaptchaCaptcha.js.map +1 -0
  372. package/dist/react/captcha/TurnstileCaptcha.d.ts +28 -0
  373. package/dist/react/captcha/TurnstileCaptcha.js +53 -0
  374. package/dist/react/captcha/TurnstileCaptcha.js.map +1 -0
  375. package/dist/react/captcha/types.d.ts +8 -0
  376. package/dist/react/captcha/useCaptchaScript.js +45 -0
  377. package/dist/react/captcha/useCaptchaScript.js.map +1 -0
  378. package/dist/react/captcha/vendors.js +8 -0
  379. package/dist/react/captcha/vendors.js.map +1 -0
  380. package/dist/react/cn.d.ts +6 -0
  381. package/dist/react/cn.js +8 -0
  382. package/dist/react/cn.js.map +1 -0
  383. package/dist/react/contract.d.ts +31 -0
  384. package/dist/react/contract.js +7 -0
  385. package/dist/react/contract.js.map +1 -0
  386. package/dist/react/events.js +14 -0
  387. package/dist/react/events.js.map +1 -0
  388. package/dist/react/fetchResults.d.ts +25 -0
  389. package/dist/react/fetchResults.js +31 -0
  390. package/dist/react/fetchResults.js.map +1 -0
  391. package/dist/react/presentation/Backdrop.d.ts +18 -0
  392. package/dist/react/presentation/Backdrop.js +14 -0
  393. package/dist/react/presentation/Backdrop.js.map +1 -0
  394. package/dist/react/presentation/DialogSurface.d.ts +35 -0
  395. package/dist/react/presentation/DialogSurface.js +53 -0
  396. package/dist/react/presentation/DialogSurface.js.map +1 -0
  397. package/dist/react/presentation/presentations.d.ts +7 -0
  398. package/dist/react/presentation/presentations.js +32 -0
  399. package/dist/react/presentation/presentations.js.map +1 -0
  400. package/dist/react/presentation/registry.d.ts +11 -0
  401. package/dist/react/presentation/registry.js +12 -0
  402. package/dist/react/presentation/registry.js.map +1 -0
  403. package/dist/react/presentation/types.d.ts +19 -0
  404. package/dist/react/presentation/useDismiss.d.ts +19 -0
  405. package/dist/react/presentation/useDismiss.js +33 -0
  406. package/dist/react/presentation/useDismiss.js.map +1 -0
  407. package/dist/react/presentation/useFocusTrap.d.ts +8 -0
  408. package/dist/react/presentation/useFocusTrap.js +35 -0
  409. package/dist/react/presentation/useFocusTrap.js.map +1 -0
  410. package/dist/react/presentation/useScrollLock.d.ts +6 -0
  411. package/dist/react/presentation/useScrollLock.js +18 -0
  412. package/dist/react/presentation/useScrollLock.js.map +1 -0
  413. package/dist/react/primitives/Checkbox.d.ts +28 -0
  414. package/dist/react/primitives/Checkbox.js +21 -0
  415. package/dist/react/primitives/Checkbox.js.map +1 -0
  416. package/dist/react/primitives/FieldShell.d.ts +29 -0
  417. package/dist/react/primitives/FieldShell.js +44 -0
  418. package/dist/react/primitives/FieldShell.js.map +1 -0
  419. package/dist/react/primitives/Input.d.ts +30 -0
  420. package/dist/react/primitives/Input.js +21 -0
  421. package/dist/react/primitives/Input.js.map +1 -0
  422. package/dist/react/primitives/Select.d.ts +34 -0
  423. package/dist/react/primitives/Select.js +26 -0
  424. package/dist/react/primitives/Select.js.map +1 -0
  425. package/dist/react/primitives/Textarea.d.ts +28 -0
  426. package/dist/react/primitives/Textarea.js +20 -0
  427. package/dist/react/primitives/Textarea.js.map +1 -0
  428. package/dist/react/recall.js +20 -0
  429. package/dist/react/recall.js.map +1 -0
  430. package/dist/react/registry.d.ts +16 -0
  431. package/dist/react/registry.js +16 -0
  432. package/dist/react/registry.js.map +1 -0
  433. package/dist/react/renderers/calculation.js +27 -0
  434. package/dist/react/renderers/calculation.js.map +1 -0
  435. package/dist/react/renderers/checkbox.js +32 -0
  436. package/dist/react/renderers/checkbox.js.map +1 -0
  437. package/dist/react/renderers/consent.js +97 -0
  438. package/dist/react/renderers/consent.js.map +1 -0
  439. package/dist/react/renderers/date.js +33 -0
  440. package/dist/react/renderers/date.js.map +1 -0
  441. package/dist/react/renderers/email.js +34 -0
  442. package/dist/react/renderers/email.js.map +1 -0
  443. package/dist/react/renderers/file.js +107 -0
  444. package/dist/react/renderers/file.js.map +1 -0
  445. package/dist/react/renderers/index.d.ts +8 -0
  446. package/dist/react/renderers/index.js +35 -0
  447. package/dist/react/renderers/index.js.map +1 -0
  448. package/dist/react/renderers/message.js +41 -0
  449. package/dist/react/renderers/message.js.map +1 -0
  450. package/dist/react/renderers/number.js +37 -0
  451. package/dist/react/renderers/number.js.map +1 -0
  452. package/dist/react/renderers/region.js +43 -0
  453. package/dist/react/renderers/region.js.map +1 -0
  454. package/dist/react/renderers/repeater.js +131 -0
  455. package/dist/react/renderers/repeater.js.map +1 -0
  456. package/dist/react/renderers/select.js +35 -0
  457. package/dist/react/renderers/select.js.map +1 -0
  458. package/dist/react/renderers/text.js +34 -0
  459. package/dist/react/renderers/text.js.map +1 -0
  460. package/dist/react/renderers/textarea.js +33 -0
  461. package/dist/react/renderers/textarea.js.map +1 -0
  462. package/dist/react/resolveForm.js +16 -0
  463. package/dist/react/resolveForm.js.map +1 -0
  464. package/dist/react/state.d.ts +52 -0
  465. package/dist/react/state.js +125 -0
  466. package/dist/react/state.js.map +1 -0
  467. package/dist/react/submitForm.d.ts +31 -0
  468. package/dist/react/submitForm.js +58 -0
  469. package/dist/react/submitForm.js.map +1 -0
  470. package/dist/react/uploadFile.d.ts +23 -0
  471. package/dist/react/uploadFile.js +39 -0
  472. package/dist/react/uploadFile.js.map +1 -0
  473. package/dist/react/useField.d.ts +13 -0
  474. package/dist/react/useField.js +49 -0
  475. package/dist/react/useField.js.map +1 -0
  476. package/dist/react/useFormState.d.ts +8 -0
  477. package/dist/react/useFormState.js +9 -0
  478. package/dist/react/useFormState.js.map +1 -0
  479. package/dist/react/useFormStep.d.ts +8 -0
  480. package/dist/react/useFormStep.js +9 -0
  481. package/dist/react/useFormStep.js.map +1 -0
  482. package/dist/react/validateField.js +27 -0
  483. package/dist/react/validateField.js.map +1 -0
  484. package/dist/recall/interpolate.d.ts +11 -0
  485. package/dist/recall/interpolate.js +17 -0
  486. package/dist/recall/interpolate.js.map +1 -0
  487. package/dist/recall/resolver.d.ts +22 -0
  488. package/dist/recall/resolver.js +48 -0
  489. package/dist/recall/resolver.js.map +1 -0
  490. package/dist/spam/captcha.d.ts +13 -0
  491. package/dist/spam/captcha.js +12 -0
  492. package/dist/spam/captcha.js.map +1 -0
  493. package/dist/spam/clientIp.js +9 -0
  494. package/dist/spam/clientIp.js.map +1 -0
  495. package/dist/spam/constants.d.ts +12 -0
  496. package/dist/spam/constants.js +21 -0
  497. package/dist/spam/constants.js.map +1 -0
  498. package/dist/spam/identify.d.ts +12 -0
  499. package/dist/spam/identify.js +17 -0
  500. package/dist/spam/identify.js.map +1 -0
  501. package/dist/spam/providers/hcaptcha.d.ts +17 -0
  502. package/dist/spam/providers/hcaptcha.js +18 -0
  503. package/dist/spam/providers/hcaptcha.js.map +1 -0
  504. package/dist/spam/providers/recaptcha.d.ts +23 -0
  505. package/dist/spam/providers/recaptcha.js +23 -0
  506. package/dist/spam/providers/recaptcha.js.map +1 -0
  507. package/dist/spam/providers/siteverify.js +34 -0
  508. package/dist/spam/providers/siteverify.js.map +1 -0
  509. package/dist/spam/providers/turnstile.d.ts +17 -0
  510. package/dist/spam/providers/turnstile.js +18 -0
  511. package/dist/spam/providers/turnstile.js.map +1 -0
  512. package/dist/spam/rateLimiter.d.ts +18 -0
  513. package/dist/spam/rateLimiter.js +41 -0
  514. package/dist/spam/rateLimiter.js.map +1 -0
  515. package/dist/spam/reserved.js +30 -0
  516. package/dist/spam/reserved.js.map +1 -0
  517. package/dist/spam/resolveSpam.d.ts +12 -0
  518. package/dist/spam/resolveSpam.js +43 -0
  519. package/dist/spam/resolveSpam.js.map +1 -0
  520. package/dist/spam/spamGuard.js +81 -0
  521. package/dist/spam/spamGuard.js.map +1 -0
  522. package/dist/spam/types.d.ts +88 -0
  523. package/dist/spam/uploadHooks.js +33 -0
  524. package/dist/spam/uploadHooks.js.map +1 -0
  525. package/dist/submissions/SubmissionAnswers.d.ts +14 -0
  526. package/dist/submissions/SubmissionAnswers.js +137 -0
  527. package/dist/submissions/SubmissionAnswers.js.map +1 -0
  528. package/dist/submissions/SubmissionAnswersClient.js +178 -0
  529. package/dist/submissions/SubmissionAnswersClient.js.map +1 -0
  530. package/dist/submissions/coerceBoolean.js +14 -0
  531. package/dist/submissions/coerceBoolean.js.map +1 -0
  532. package/dist/submissions/createSubmission.d.ts +36 -0
  533. package/dist/submissions/createSubmission.js +26 -0
  534. package/dist/submissions/createSubmission.js.map +1 -0
  535. package/dist/submissions/runSubmission.d.ts +10 -0
  536. package/dist/submissions/runSubmission.js +306 -0
  537. package/dist/submissions/runSubmission.js.map +1 -0
  538. package/dist/submissions/types.d.ts +41 -0
  539. package/dist/submissions/validateSubmission.js +110 -0
  540. package/dist/submissions/validateSubmission.js.map +1 -0
  541. package/dist/submissions/votedCookie.d.ts +13 -0
  542. package/dist/submissions/votedCookie.js +27 -0
  543. package/dist/submissions/votedCookie.js.map +1 -0
  544. package/dist/translations/clientRuntimeKeys.d.ts +17 -0
  545. package/dist/translations/clientRuntimeKeys.js +46 -0
  546. package/dist/translations/clientRuntimeKeys.js.map +1 -0
  547. package/dist/translations/de.d.ts +12 -0
  548. package/dist/translations/de.js +309 -0
  549. package/dist/translations/de.js.map +1 -0
  550. package/dist/translations/en.d.ts +12 -0
  551. package/dist/translations/en.js +309 -0
  552. package/dist/translations/en.js.map +1 -0
  553. package/dist/translations/index.d.ts +23 -0
  554. package/dist/translations/index.js +37 -0
  555. package/dist/translations/index.js.map +1 -0
  556. package/dist/translations/keys.d.ts +308 -0
  557. package/dist/translations/keys.js +308 -0
  558. package/dist/translations/keys.js.map +1 -0
  559. package/dist/translations/makeTranslate.d.ts +15 -0
  560. package/dist/translations/makeTranslate.js +20 -0
  561. package/dist/translations/makeTranslate.js.map +1 -0
  562. package/dist/translations/server.js +32 -0
  563. package/dist/translations/server.js.map +1 -0
  564. package/dist/translations/useTranslation.js +12 -0
  565. package/dist/translations/useTranslation.js.map +1 -0
  566. package/dist/uploads/captureFileRef.d.ts +34 -0
  567. package/dist/uploads/captureFileRef.js +43 -0
  568. package/dist/uploads/captureFileRef.js.map +1 -0
  569. package/dist/uploads/formatBytes.d.ts +9 -0
  570. package/dist/uploads/formatBytes.js +25 -0
  571. package/dist/uploads/formatBytes.js.map +1 -0
  572. package/dist/uploads/resolveFileRef.d.ts +26 -0
  573. package/dist/uploads/resolveFileRef.js +45 -0
  574. package/dist/uploads/resolveFileRef.js.map +1 -0
  575. package/dist/uploads/types.d.ts +19 -0
  576. package/dist/validation/buildRuleBlocks.js +47 -0
  577. package/dist/validation/buildRuleBlocks.js.map +1 -0
  578. package/dist/validation/builtin/email.js +20 -0
  579. package/dist/validation/builtin/email.js.map +1 -0
  580. package/dist/validation/builtin/index.d.ts +14 -0
  581. package/dist/validation/builtin/index.js +38 -0
  582. package/dist/validation/builtin/index.js.map +1 -0
  583. package/dist/validation/builtin/matchesField.js +16 -0
  584. package/dist/validation/builtin/matchesField.js.map +1 -0
  585. package/dist/validation/builtin/max.js +22 -0
  586. package/dist/validation/builtin/max.js.map +1 -0
  587. package/dist/validation/builtin/maxDate.js +24 -0
  588. package/dist/validation/builtin/maxDate.js.map +1 -0
  589. package/dist/validation/builtin/maxLength.js +27 -0
  590. package/dist/validation/builtin/maxLength.js.map +1 -0
  591. package/dist/validation/builtin/min.js +22 -0
  592. package/dist/validation/builtin/min.js.map +1 -0
  593. package/dist/validation/builtin/minDate.js +24 -0
  594. package/dist/validation/builtin/minDate.js.map +1 -0
  595. package/dist/validation/builtin/minLength.js +27 -0
  596. package/dist/validation/builtin/minLength.js.map +1 -0
  597. package/dist/validation/builtin/notAlreadySubmitted.js +34 -0
  598. package/dist/validation/builtin/notAlreadySubmitted.js.map +1 -0
  599. package/dist/validation/builtin/oneOf.js +35 -0
  600. package/dist/validation/builtin/oneOf.js.map +1 -0
  601. package/dist/validation/builtin/pattern.js +50 -0
  602. package/dist/validation/builtin/pattern.js.map +1 -0
  603. package/dist/validation/builtin/url.js +23 -0
  604. package/dist/validation/builtin/url.js.map +1 -0
  605. package/dist/validation/builtin/validateDateBound.js +18 -0
  606. package/dist/validation/builtin/validateDateBound.js.map +1 -0
  607. package/dist/validation/builtin/validateRegexParams.js +44 -0
  608. package/dist/validation/builtin/validateRegexParams.js.map +1 -0
  609. package/dist/validation/defineValidationRule.d.ts +12 -0
  610. package/dist/validation/defineValidationRule.js +11 -0
  611. package/dist/validation/defineValidationRule.js.map +1 -0
  612. package/dist/validation/emailPattern.js +10 -0
  613. package/dist/validation/emailPattern.js.map +1 -0
  614. package/dist/validation/fieldTargetParam.d.ts +22 -0
  615. package/dist/validation/fieldTargetParam.js +38 -0
  616. package/dist/validation/fieldTargetParam.js.map +1 -0
  617. package/dist/validation/message.js +14 -0
  618. package/dist/validation/message.js.map +1 -0
  619. package/dist/validation/registry.d.ts +11 -0
  620. package/dist/validation/registry.js +13 -0
  621. package/dist/validation/registry.js.map +1 -0
  622. package/dist/validation/runValidation.js +90 -0
  623. package/dist/validation/runValidation.js.map +1 -0
  624. package/dist/validation/types.d.ts +70 -0
  625. package/dist/validation/validateUrl.js +22 -0
  626. package/dist/validation/validateUrl.js.map +1 -0
  627. package/package.json +12 -7
  628. package/styles/form-builder.css +21 -11
  629. package/dist/constants-B-BUfetP.d.ts +0 -288
  630. package/dist/exports/client.js.map +0 -1
  631. package/dist/exports/react.js.map +0 -1
  632. package/dist/exports/rsc.js.map +0 -1
  633. package/dist/fieldTypes-B8jkNRob.d.ts +0 -188
  634. package/dist/fieldTypes-CzhhJXjg.js.map +0 -1
  635. package/dist/index-DfFYGbVF.d.ts +0 -481
  636. package/dist/keys-N5xGiUsh.js +0 -132
  637. package/dist/keys-N5xGiUsh.js.map +0 -1
  638. package/dist/registry-CoCyhtvB.js +0 -282
  639. package/dist/registry-CoCyhtvB.js.map +0 -1
  640. package/dist/resolver-OeQyVH2N.js +0 -665
  641. package/dist/resolver-OeQyVH2N.js.map +0 -1
  642. package/dist/translations-edMqq_2e.js +0 -152
  643. package/dist/translations-edMqq_2e.js.map +0 -1
  644. package/dist/types-DsJ_6kGJ.d.ts +0 -23
@@ -0,0 +1,131 @@
1
+ "use client";
2
+ import { keys } from "../../translations/keys.js";
3
+ import { isNamedField } from "../../fields/fieldKey.js";
4
+ import { defineFieldRenderer } from "../contract.js";
5
+ import { useFormContext } from "../FormContext.js";
6
+ import { useField } from "../useField.js";
7
+ import { FieldShell } from "../primitives/FieldShell.js";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ import { createElement, useId, useRef } from "react";
10
+ //#region src/react/renderers/repeater.tsx
11
+ /** Process-wide counter for stable per-row React keys (rows are plain objects with no id of their own). */
12
+ let rowKeySeq = 0;
13
+ const nextRowKey = () => `fbrow-${rowKeySeq++}`;
14
+ /**
15
+ * Thin wrapper so each sub-field renderer is a proper React component (has stable hook identity
16
+ * per row/field). Reads errors for the composite path `field[row].subField` from
17
+ * form state so server-side validation errors are surfaced inline next to the sub-field input,
18
+ * overriding any static values passed by the parent.
19
+ */
20
+ const SubFieldWrapper = ({ renderer, name, ...props }) => {
21
+ const { state } = useFormContext();
22
+ const errors = state.errors?.[name] ?? [];
23
+ return renderer({
24
+ ...props,
25
+ name,
26
+ errors
27
+ });
28
+ };
29
+ const repeaterRenderer = defineFieldRenderer(({ field, name, id: rootId, errors, required, t, locale }) => {
30
+ const { rendererRegistry, dispatch } = useFormContext();
31
+ const { value, setValue, onBlur } = useField(name);
32
+ const addId = useId();
33
+ const rowKeysRef = useRef([]);
34
+ const rows = Array.isArray(value) ? value : [];
35
+ if (rowKeysRef.current.length !== rows.length) {
36
+ const next = rowKeysRef.current.slice(0, rows.length);
37
+ while (next.length < rows.length) next.push(nextRowKey());
38
+ rowKeysRef.current = next;
39
+ }
40
+ const subFields = (Array.isArray(field.subFields) ? field.subFields : []).filter(isNamedField);
41
+ const maxRows = typeof field.maxRows === "number" ? field.maxRows : void 0;
42
+ const minRows = typeof field.minRows === "number" ? field.minRows : 0;
43
+ const addLabel = typeof field.addLabel === "string" && field.addLabel.length > 0 ? field.addLabel : t(keys.repeaterAddRow);
44
+ const addRow = () => {
45
+ if (maxRows != null && rows.length >= maxRows) return;
46
+ rowKeysRef.current = [...rowKeysRef.current, nextRowKey()];
47
+ setValue([...rows, {}]);
48
+ onBlur();
49
+ };
50
+ const removeRow = (index) => {
51
+ rowKeysRef.current = rowKeysRef.current.filter((_, i) => i !== index);
52
+ dispatch({
53
+ type: "REMOVE_REPEATER_ROW",
54
+ name,
55
+ index
56
+ });
57
+ setValue(rows.filter((_, i) => i !== index));
58
+ onBlur();
59
+ };
60
+ const updateRow = (index, fieldName, fieldValue) => {
61
+ setValue(rows.map((row, i) => i === index ? {
62
+ ...row,
63
+ [fieldName]: fieldValue
64
+ } : row));
65
+ dispatch({
66
+ type: "SET_FIELD_ISSUES",
67
+ name: `${name}[${index}].${fieldName}`,
68
+ errors: []
69
+ });
70
+ };
71
+ return /* @__PURE__ */ jsx(FieldShell, {
72
+ id: rootId,
73
+ label: typeof field.label === "string" ? field.label : void 0,
74
+ description: typeof field.description === "string" ? field.description : void 0,
75
+ required,
76
+ errors,
77
+ describedById: `${rootId}-desc`,
78
+ children: /* @__PURE__ */ jsxs("div", {
79
+ className: "fb-repeater",
80
+ children: [rows.map((row, rowIndex) => {
81
+ const rowLabel = t(keys.repeaterRow).replace("{n}", String(rowIndex + 1));
82
+ return /* @__PURE__ */ jsxs("fieldset", {
83
+ className: "fb-repeater__row",
84
+ children: [/* @__PURE__ */ jsxs("legend", {
85
+ className: "fb-repeater__row-legend",
86
+ children: [rowLabel, rows.length > minRows && /* @__PURE__ */ jsx("button", {
87
+ type: "button",
88
+ className: "fb-repeater__remove",
89
+ onClick: () => removeRow(rowIndex),
90
+ "aria-label": `${t(keys.repeaterRemoveRow)} ${rowLabel}`,
91
+ children: t(keys.repeaterRemoveRow)
92
+ })]
93
+ }), /* @__PURE__ */ jsx("div", {
94
+ className: "fb-repeater__row-fields",
95
+ children: subFields.map((subField) => {
96
+ const renderer = rendererRegistry.get(subField.blockType);
97
+ if (!renderer) return null;
98
+ return /* @__PURE__ */ jsx("div", {
99
+ className: "fb-repeater__sub-field",
100
+ children: createElement(SubFieldWrapper, {
101
+ renderer,
102
+ field: subField,
103
+ id: `${rootId}-${rowIndex}-${subField.name}`,
104
+ name: `${name}[${rowIndex}].${subField.name}`,
105
+ value: row[subField.name],
106
+ onChange: (v) => updateRow(rowIndex, subField.name, v),
107
+ onBlur,
108
+ errors: [],
109
+ required: subField.required ?? false,
110
+ disabled: false,
111
+ locale,
112
+ t
113
+ })
114
+ }, subField.name);
115
+ })
116
+ })]
117
+ }, rowKeysRef.current[rowIndex]);
118
+ }), (maxRows == null || rows.length < maxRows) && /* @__PURE__ */ jsx("button", {
119
+ id: addId,
120
+ type: "button",
121
+ className: "fb-repeater__add",
122
+ onClick: addRow,
123
+ children: addLabel
124
+ })]
125
+ })
126
+ });
127
+ });
128
+ //#endregion
129
+ export { repeaterRenderer };
130
+
131
+ //# sourceMappingURL=repeater.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repeater.js","names":[],"sources":["../../../src/react/renderers/repeater.tsx"],"sourcesContent":["'use client'\n\nimport { createElement, useId, useRef } from 'react'\nimport { isNamedField } from '../../fields/fieldKey'\nimport type { FormFieldInstance } from '../../submissions/types'\nimport { keys } from '../../translations/keys'\nimport type { FieldRenderer } from '../contract'\nimport { defineFieldRenderer } from '../contract'\nimport { useFormContext } from '../FormContext'\nimport { FieldShell } from '../primitives/FieldShell'\nimport { useField } from '../useField'\n\ntype RepeaterRow = Record<string, unknown>\n\n/** Process-wide counter for stable per-row React keys (rows are plain objects with no id of their own). */\nlet rowKeySeq = 0\nconst nextRowKey = () => `fbrow-${rowKeySeq++}`\n\n/**\n * Thin wrapper so each sub-field renderer is a proper React component (has stable hook identity\n * per row/field). Reads errors for the composite path `field[row].subField` from\n * form state so server-side validation errors are surfaced inline next to the sub-field input,\n * overriding any static values passed by the parent.\n */\nconst SubFieldWrapper = ({\n\trenderer,\n\tname,\n\t...props\n}: { renderer: FieldRenderer } & Parameters<FieldRenderer>[0]) => {\n\tconst { state } = useFormContext()\n\tconst errors = (state.errors as Record<string, string[]>)?.[name] ?? []\n\treturn renderer({ ...props, name, errors })\n}\n\nexport const repeaterRenderer = defineFieldRenderer<RepeaterRow[]>(\n\t({ field, name, id: rootId, errors, required, t, locale }) => {\n\t\tconst { rendererRegistry, dispatch } = useFormContext()\n\t\tconst { value, setValue, onBlur } = useField<RepeaterRow[]>(name)\n\t\tconst addId = useId()\n\t\tconst rowKeysRef = useRef<string[]>([])\n\n\t\tconst rows = Array.isArray(value) ? value : []\n\t\t// One stable key per row so removing a middle row does not re-index survivors onto each other's\n\t\t// React instances (which would strand a stateful sub-renderer's local state, e.g. the file\n\t\t// renderer's filename). Reconciled to the row count each render; add/remove keep keys aligned.\n\t\tif (rowKeysRef.current.length !== rows.length) {\n\t\t\tconst next = rowKeysRef.current.slice(0, rows.length)\n\t\t\twhile (next.length < rows.length) next.push(nextRowKey())\n\t\t\trowKeysRef.current = next\n\t\t}\n\t\tconst subFields = (\n\t\t\tArray.isArray(field.subFields) ? (field.subFields as FormFieldInstance[]) : []\n\t\t).filter(isNamedField)\n\t\tconst maxRows = typeof field.maxRows === 'number' ? field.maxRows : undefined\n\t\tconst minRows = typeof field.minRows === 'number' ? field.minRows : 0\n\t\tconst addLabel =\n\t\t\ttypeof field.addLabel === 'string' && field.addLabel.length > 0\n\t\t\t\t? field.addLabel\n\t\t\t\t: t(keys.repeaterAddRow)\n\n\t\tconst addRow = () => {\n\t\t\tif (maxRows != null && rows.length >= maxRows) return\n\t\t\trowKeysRef.current = [...rowKeysRef.current, nextRowKey()]\n\t\t\tsetValue([...rows, {}])\n\t\t\tonBlur()\n\t\t}\n\n\t\tconst removeRow = (index: number) => {\n\t\t\trowKeysRef.current = rowKeysRef.current.filter((_, i) => i !== index)\n\t\t\t// setValue removes the row value; SET_VALUE cannot reach the composite sub-field issue keys\n\t\t\t// (`name[i].sub`), so reindex them separately or a deleted row's errors strand on a survivor.\n\t\t\tdispatch({ type: 'REMOVE_REPEATER_ROW', name, index })\n\t\t\tsetValue(rows.filter((_, i) => i !== index))\n\t\t\tonBlur()\n\t\t}\n\n\t\tconst updateRow = (index: number, fieldName: string, fieldValue: unknown) => {\n\t\t\tsetValue(rows.map((row, i) => (i === index ? { ...row, [fieldName]: fieldValue } : row)))\n\t\t\t// SET_VALUE clears only the repeater field's own error key, not composite sub-field keys, so a\n\t\t\t// stale server-side error for this sub-field would linger until the next submit. Clear it now.\n\t\t\tdispatch({ type: 'SET_FIELD_ISSUES', name: `${name}[${index}].${fieldName}`, errors: [] })\n\t\t}\n\n\t\treturn (\n\t\t\t<FieldShell\n\t\t\t\tid={rootId}\n\t\t\t\tlabel={typeof field.label === 'string' ? field.label : undefined}\n\t\t\t\tdescription={typeof field.description === 'string' ? field.description : undefined}\n\t\t\t\trequired={required}\n\t\t\t\terrors={errors}\n\t\t\t\tdescribedById={`${rootId}-desc`}\n\t\t\t>\n\t\t\t\t<div className=\"fb-repeater\">\n\t\t\t\t\t{rows.map((row, rowIndex) => {\n\t\t\t\t\t\tconst rowLabel = t(keys.repeaterRow).replace('{n}', String(rowIndex + 1))\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<fieldset key={rowKeysRef.current[rowIndex]} className=\"fb-repeater__row\">\n\t\t\t\t\t\t\t\t<legend className=\"fb-repeater__row-legend\">\n\t\t\t\t\t\t\t\t\t{rowLabel}\n\t\t\t\t\t\t\t\t\t{rows.length > minRows && (\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"fb-repeater__remove\"\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => removeRow(rowIndex)}\n\t\t\t\t\t\t\t\t\t\t\taria-label={`${t(keys.repeaterRemoveRow)} ${rowLabel}`}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{t(keys.repeaterRemoveRow)}\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</legend>\n\t\t\t\t\t\t\t\t<div className=\"fb-repeater__row-fields\">\n\t\t\t\t\t\t\t\t\t{subFields.map((subField) => {\n\t\t\t\t\t\t\t\t\t\tconst renderer = rendererRegistry.get(subField.blockType)\n\t\t\t\t\t\t\t\t\t\tif (!renderer) return null\n\t\t\t\t\t\t\t\t\t\tconst subId = `${rootId}-${rowIndex}-${subField.name}`\n\t\t\t\t\t\t\t\t\t\tconst compositeName = `${name}[${rowIndex}].${subField.name}`\n\t\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t\t<div key={subField.name} className=\"fb-repeater__sub-field\">\n\t\t\t\t\t\t\t\t\t\t\t\t{createElement(SubFieldWrapper, {\n\t\t\t\t\t\t\t\t\t\t\t\t\trenderer,\n\t\t\t\t\t\t\t\t\t\t\t\t\tfield: subField,\n\t\t\t\t\t\t\t\t\t\t\t\t\tid: subId,\n\t\t\t\t\t\t\t\t\t\t\t\t\tname: compositeName,\n\t\t\t\t\t\t\t\t\t\t\t\t\tvalue: row[subField.name],\n\t\t\t\t\t\t\t\t\t\t\t\t\tonChange: (v) => updateRow(rowIndex, subField.name, v),\n\t\t\t\t\t\t\t\t\t\t\t\t\tonBlur,\n\t\t\t\t\t\t\t\t\t\t\t\t\t// SubFieldWrapper overrides these from form state; passed here to satisfy the type\n\t\t\t\t\t\t\t\t\t\t\t\t\terrors: [],\n\t\t\t\t\t\t\t\t\t\t\t\t\trequired: subField.required ?? false,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdisabled: false,\n\t\t\t\t\t\t\t\t\t\t\t\t\tlocale,\n\t\t\t\t\t\t\t\t\t\t\t\t\tt,\n\t\t\t\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\t\t\t</div>\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</fieldset>\n\t\t\t\t\t\t)\n\t\t\t\t\t})}\n\t\t\t\t\t{(maxRows == null || rows.length < maxRows) && (\n\t\t\t\t\t\t<button id={addId} type=\"button\" className=\"fb-repeater__add\" onClick={addRow}>\n\t\t\t\t\t\t\t{addLabel}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t</FieldShell>\n\t\t)\n\t}\n)\n"],"mappings":";;;;;;;;;;;AAeA,IAAI,YAAY;AAChB,MAAM,mBAAmB,SAAS;;;;;;;AAQlC,MAAM,mBAAmB,EACxB,UACA,MACA,GAAG,YAC8D;CACjE,MAAM,EAAE,UAAU,eAAe;CACjC,MAAM,SAAU,MAAM,SAAsC,SAAS,CAAC;CACtE,OAAO,SAAS;EAAE,GAAG;EAAO;EAAM;CAAO,CAAC;AAC3C;AAEA,MAAa,mBAAmB,qBAC9B,EAAE,OAAO,MAAM,IAAI,QAAQ,QAAQ,UAAU,GAAG,aAAa;CAC7D,MAAM,EAAE,kBAAkB,aAAa,eAAe;CACtD,MAAM,EAAE,OAAO,UAAU,WAAW,SAAwB,IAAI;CAChE,MAAM,QAAQ,MAAM;CACpB,MAAM,aAAa,OAAiB,CAAC,CAAC;CAEtC,MAAM,OAAO,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC;CAI7C,IAAI,WAAW,QAAQ,WAAW,KAAK,QAAQ;EAC9C,MAAM,OAAO,WAAW,QAAQ,MAAM,GAAG,KAAK,MAAM;EACpD,OAAO,KAAK,SAAS,KAAK,QAAQ,KAAK,KAAK,WAAW,CAAC;EACxD,WAAW,UAAU;CACtB;CACA,MAAM,aACL,MAAM,QAAQ,MAAM,SAAS,IAAK,MAAM,YAAoC,CAAC,GAC5E,OAAO,YAAY;CACrB,MAAM,UAAU,OAAO,MAAM,YAAY,WAAW,MAAM,UAAU,KAAA;CACpE,MAAM,UAAU,OAAO,MAAM,YAAY,WAAW,MAAM,UAAU;CACpE,MAAM,WACL,OAAO,MAAM,aAAa,YAAY,MAAM,SAAS,SAAS,IAC3D,MAAM,WACN,EAAE,KAAK,cAAc;CAEzB,MAAM,eAAe;EACpB,IAAI,WAAW,QAAQ,KAAK,UAAU,SAAS;EAC/C,WAAW,UAAU,CAAC,GAAG,WAAW,SAAS,WAAW,CAAC;EACzD,SAAS,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;EACtB,OAAO;CACR;CAEA,MAAM,aAAa,UAAkB;EACpC,WAAW,UAAU,WAAW,QAAQ,QAAQ,GAAG,MAAM,MAAM,KAAK;EAGpE,SAAS;GAAE,MAAM;GAAuB;GAAM;EAAM,CAAC;EACrD,SAAS,KAAK,QAAQ,GAAG,MAAM,MAAM,KAAK,CAAC;EAC3C,OAAO;CACR;CAEA,MAAM,aAAa,OAAe,WAAmB,eAAwB;EAC5E,SAAS,KAAK,KAAK,KAAK,MAAO,MAAM,QAAQ;GAAE,GAAG;IAAM,YAAY;EAAW,IAAI,GAAI,CAAC;EAGxF,SAAS;GAAE,MAAM;GAAoB,MAAM,GAAG,KAAK,GAAG,MAAM,IAAI;GAAa,QAAQ,CAAC;EAAE,CAAC;CAC1F;CAEA,OACC,oBAAC,YAAD;EACC,IAAI;EACJ,OAAO,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ,KAAA;EACvD,aAAa,OAAO,MAAM,gBAAgB,WAAW,MAAM,cAAc,KAAA;EAC/D;EACF;EACR,eAAe,GAAG,OAAO;YAEzB,qBAAC,OAAD;GAAK,WAAU;aAAf,CACE,KAAK,KAAK,KAAK,aAAa;IAC5B,MAAM,WAAW,EAAE,KAAK,WAAW,EAAE,QAAQ,OAAO,OAAO,WAAW,CAAC,CAAC;IACxE,OACC,qBAAC,YAAD;KAA6C,WAAU;eAAvD,CACC,qBAAC,UAAD;MAAQ,WAAU;gBAAlB,CACE,UACA,KAAK,SAAS,WACd,oBAAC,UAAD;OACC,MAAK;OACL,WAAU;OACV,eAAe,UAAU,QAAQ;OACjC,cAAY,GAAG,EAAE,KAAK,iBAAiB,EAAE,GAAG;iBAE3C,EAAE,KAAK,iBAAiB;MAClB,CAAA,CAEF;SACR,oBAAC,OAAD;MAAK,WAAU;gBACb,UAAU,KAAK,aAAa;OAC5B,MAAM,WAAW,iBAAiB,IAAI,SAAS,SAAS;OACxD,IAAI,CAAC,UAAU,OAAO;OAGtB,OACC,oBAAC,OAAD;QAAyB,WAAU;kBACjC,cAAc,iBAAiB;SAC/B;SACA,OAAO;SACP,IAAI,GAPU,OAAO,GAAG,SAAS,GAAG,SAAS;SAQ7C,MAAM,GAPgB,KAAK,GAAG,SAAS,IAAI,SAAS;SAQpD,OAAO,IAAI,SAAS;SACpB,WAAW,MAAM,UAAU,UAAU,SAAS,MAAM,CAAC;SACrD;SAEA,QAAQ,CAAC;SACT,UAAU,SAAS,YAAY;SAC/B,UAAU;SACV;SACA;QACD,CAAC;OACG,GAhBK,SAAS,IAgBd;MAEP,CAAC;KACG,CAAA,CACI;OAzCK,WAAW,QAAQ,SAyCxB;GAEZ,CAAC,IACC,WAAW,QAAQ,KAAK,SAAS,YAClC,oBAAC,UAAD;IAAQ,IAAI;IAAO,MAAK;IAAS,WAAU;IAAmB,SAAS;cACrE;GACM,CAAA,CAEL;;CACM,CAAA;AAEd,CACD"}
@@ -0,0 +1,35 @@
1
+ "use client";
2
+ import { defineFieldRenderer } from "../contract.js";
3
+ import { FieldShell } from "../primitives/FieldShell.js";
4
+ import { Select } from "../primitives/Select.js";
5
+ import { jsx } from "react/jsx-runtime";
6
+ //#region src/react/renderers/select.tsx
7
+ const selectRenderer = defineFieldRenderer(({ field, id, name, value, onChange, onBlur, errors, required, disabled }) => {
8
+ const describedById = `${id}-desc`;
9
+ const options = Array.isArray(field.options) ? field.options : [];
10
+ return /* @__PURE__ */ jsx(FieldShell, {
11
+ id,
12
+ label: field.label,
13
+ description: typeof field.description === "string" ? field.description : void 0,
14
+ required,
15
+ errors,
16
+ describedById,
17
+ children: /* @__PURE__ */ jsx(Select, {
18
+ id,
19
+ name,
20
+ value: value ?? "",
21
+ options,
22
+ onChange,
23
+ onBlur,
24
+ placeholder: typeof field.placeholder === "string" ? field.placeholder : void 0,
25
+ required,
26
+ disabled,
27
+ invalid: errors.length > 0,
28
+ describedById
29
+ })
30
+ });
31
+ });
32
+ //#endregion
33
+ export { selectRenderer };
34
+
35
+ //# sourceMappingURL=select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select.js","names":[],"sources":["../../../src/react/renderers/select.tsx"],"sourcesContent":["'use client'\n\nimport { defineFieldRenderer } from '../contract'\nimport { FieldShell } from '../primitives/FieldShell'\nimport { Select } from '../primitives/Select'\n\nexport const selectRenderer = defineFieldRenderer<string>(\n\t({ field, id, name, value, onChange, onBlur, errors, required, disabled }) => {\n\t\tconst describedById = `${id}-desc`\n\t\tconst options = Array.isArray(field.options)\n\t\t\t? (field.options as { label: string; value: string }[])\n\t\t\t: []\n\t\treturn (\n\t\t\t<FieldShell\n\t\t\t\tid={id}\n\t\t\t\tlabel={field.label}\n\t\t\t\tdescription={typeof field.description === 'string' ? field.description : undefined}\n\t\t\t\trequired={required}\n\t\t\t\terrors={errors}\n\t\t\t\tdescribedById={describedById}\n\t\t\t>\n\t\t\t\t<Select\n\t\t\t\t\tid={id}\n\t\t\t\t\tname={name}\n\t\t\t\t\tvalue={value ?? ''}\n\t\t\t\t\toptions={options}\n\t\t\t\t\tonChange={onChange}\n\t\t\t\t\tonBlur={onBlur}\n\t\t\t\t\tplaceholder={typeof field.placeholder === 'string' ? field.placeholder : undefined}\n\t\t\t\t\trequired={required}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tinvalid={errors.length > 0}\n\t\t\t\t\tdescribedById={describedById}\n\t\t\t\t/>\n\t\t\t</FieldShell>\n\t\t)\n\t}\n)\n"],"mappings":";;;;;;AAMA,MAAa,iBAAiB,qBAC5B,EAAE,OAAO,IAAI,MAAM,OAAO,UAAU,QAAQ,QAAQ,UAAU,eAAe;CAC7E,MAAM,gBAAgB,GAAG,GAAG;CAC5B,MAAM,UAAU,MAAM,QAAQ,MAAM,OAAO,IACvC,MAAM,UACP,CAAC;CACJ,OACC,oBAAC,YAAD;EACK;EACJ,OAAO,MAAM;EACb,aAAa,OAAO,MAAM,gBAAgB,WAAW,MAAM,cAAc,KAAA;EAC/D;EACF;EACO;YAEf,oBAAC,QAAD;GACK;GACE;GACN,OAAO,SAAS;GACP;GACC;GACF;GACR,aAAa,OAAO,MAAM,gBAAgB,WAAW,MAAM,cAAc,KAAA;GAC/D;GACA;GACV,SAAS,OAAO,SAAS;GACV;EACf,CAAA;CACU,CAAA;AAEd,CACD"}
@@ -0,0 +1,34 @@
1
+ "use client";
2
+ import { defineFieldRenderer } from "../contract.js";
3
+ import { FieldShell } from "../primitives/FieldShell.js";
4
+ import { Input } from "../primitives/Input.js";
5
+ import { jsx } from "react/jsx-runtime";
6
+ //#region src/react/renderers/text.tsx
7
+ const textRenderer = defineFieldRenderer(({ field, id, name, value, onChange, onBlur, errors, required, disabled }) => {
8
+ const describedById = `${id}-desc`;
9
+ return /* @__PURE__ */ jsx(FieldShell, {
10
+ id,
11
+ label: field.label,
12
+ description: typeof field.description === "string" ? field.description : void 0,
13
+ required,
14
+ errors,
15
+ describedById,
16
+ children: /* @__PURE__ */ jsx(Input, {
17
+ id,
18
+ name,
19
+ type: "text",
20
+ value: value ?? "",
21
+ onChange,
22
+ onBlur,
23
+ placeholder: typeof field.placeholder === "string" ? field.placeholder : void 0,
24
+ required,
25
+ disabled,
26
+ invalid: errors.length > 0,
27
+ describedById
28
+ })
29
+ });
30
+ });
31
+ //#endregion
32
+ export { textRenderer };
33
+
34
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.js","names":[],"sources":["../../../src/react/renderers/text.tsx"],"sourcesContent":["'use client'\n\nimport { defineFieldRenderer } from '../contract'\nimport { FieldShell } from '../primitives/FieldShell'\nimport { Input } from '../primitives/Input'\n\nexport const textRenderer = defineFieldRenderer<string>(\n\t({ field, id, name, value, onChange, onBlur, errors, required, disabled }) => {\n\t\tconst describedById = `${id}-desc`\n\t\treturn (\n\t\t\t<FieldShell\n\t\t\t\tid={id}\n\t\t\t\tlabel={field.label}\n\t\t\t\tdescription={typeof field.description === 'string' ? field.description : undefined}\n\t\t\t\trequired={required}\n\t\t\t\terrors={errors}\n\t\t\t\tdescribedById={describedById}\n\t\t\t>\n\t\t\t\t<Input\n\t\t\t\t\tid={id}\n\t\t\t\t\tname={name}\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t\tvalue={value ?? ''}\n\t\t\t\t\tonChange={onChange}\n\t\t\t\t\tonBlur={onBlur}\n\t\t\t\t\tplaceholder={typeof field.placeholder === 'string' ? field.placeholder : undefined}\n\t\t\t\t\trequired={required}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tinvalid={errors.length > 0}\n\t\t\t\t\tdescribedById={describedById}\n\t\t\t\t/>\n\t\t\t</FieldShell>\n\t\t)\n\t}\n)\n"],"mappings":";;;;;;AAMA,MAAa,eAAe,qBAC1B,EAAE,OAAO,IAAI,MAAM,OAAO,UAAU,QAAQ,QAAQ,UAAU,eAAe;CAC7E,MAAM,gBAAgB,GAAG,GAAG;CAC5B,OACC,oBAAC,YAAD;EACK;EACJ,OAAO,MAAM;EACb,aAAa,OAAO,MAAM,gBAAgB,WAAW,MAAM,cAAc,KAAA;EAC/D;EACF;EACO;YAEf,oBAAC,OAAD;GACK;GACE;GACN,MAAK;GACL,OAAO,SAAS;GACN;GACF;GACR,aAAa,OAAO,MAAM,gBAAgB,WAAW,MAAM,cAAc,KAAA;GAC/D;GACA;GACV,SAAS,OAAO,SAAS;GACV;EACf,CAAA;CACU,CAAA;AAEd,CACD"}
@@ -0,0 +1,33 @@
1
+ "use client";
2
+ import { defineFieldRenderer } from "../contract.js";
3
+ import { FieldShell } from "../primitives/FieldShell.js";
4
+ import { Textarea } from "../primitives/Textarea.js";
5
+ import { jsx } from "react/jsx-runtime";
6
+ //#region src/react/renderers/textarea.tsx
7
+ const textareaRenderer = defineFieldRenderer(({ field, id, name, value, onChange, onBlur, errors, required, disabled }) => {
8
+ const describedById = `${id}-desc`;
9
+ return /* @__PURE__ */ jsx(FieldShell, {
10
+ id,
11
+ label: field.label,
12
+ description: typeof field.description === "string" ? field.description : void 0,
13
+ required,
14
+ errors,
15
+ describedById,
16
+ children: /* @__PURE__ */ jsx(Textarea, {
17
+ id,
18
+ name,
19
+ value: value ?? "",
20
+ onChange,
21
+ onBlur,
22
+ placeholder: typeof field.placeholder === "string" ? field.placeholder : void 0,
23
+ required,
24
+ disabled,
25
+ invalid: errors.length > 0,
26
+ describedById
27
+ })
28
+ });
29
+ });
30
+ //#endregion
31
+ export { textareaRenderer };
32
+
33
+ //# sourceMappingURL=textarea.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"textarea.js","names":[],"sources":["../../../src/react/renderers/textarea.tsx"],"sourcesContent":["'use client'\n\nimport { defineFieldRenderer } from '../contract'\nimport { FieldShell } from '../primitives/FieldShell'\nimport { Textarea } from '../primitives/Textarea'\n\nexport const textareaRenderer = defineFieldRenderer<string>(\n\t({ field, id, name, value, onChange, onBlur, errors, required, disabled }) => {\n\t\tconst describedById = `${id}-desc`\n\t\treturn (\n\t\t\t<FieldShell\n\t\t\t\tid={id}\n\t\t\t\tlabel={field.label}\n\t\t\t\tdescription={typeof field.description === 'string' ? field.description : undefined}\n\t\t\t\trequired={required}\n\t\t\t\terrors={errors}\n\t\t\t\tdescribedById={describedById}\n\t\t\t>\n\t\t\t\t<Textarea\n\t\t\t\t\tid={id}\n\t\t\t\t\tname={name}\n\t\t\t\t\tvalue={value ?? ''}\n\t\t\t\t\tonChange={onChange}\n\t\t\t\t\tonBlur={onBlur}\n\t\t\t\t\tplaceholder={typeof field.placeholder === 'string' ? field.placeholder : undefined}\n\t\t\t\t\trequired={required}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tinvalid={errors.length > 0}\n\t\t\t\t\tdescribedById={describedById}\n\t\t\t\t/>\n\t\t\t</FieldShell>\n\t\t)\n\t}\n)\n"],"mappings":";;;;;;AAMA,MAAa,mBAAmB,qBAC9B,EAAE,OAAO,IAAI,MAAM,OAAO,UAAU,QAAQ,QAAQ,UAAU,eAAe;CAC7E,MAAM,gBAAgB,GAAG,GAAG;CAC5B,OACC,oBAAC,YAAD;EACK;EACJ,OAAO,MAAM;EACb,aAAa,OAAO,MAAM,gBAAgB,WAAW,MAAM,cAAc,KAAA;EAC/D;EACF;EACO;YAEf,oBAAC,UAAD;GACK;GACE;GACN,OAAO,SAAS;GACN;GACF;GACR,aAAa,OAAO,MAAM,gBAAgB,WAAW,MAAM,cAAc,KAAA;GAC/D;GACA;GACV,SAAS,OAAO,SAAS;GACV;EACf,CAAA;CACU,CAAA;AAEd,CACD"}
@@ -0,0 +1,16 @@
1
+ import { defaultFieldDefinitions } from "../fields/builtin/index.js";
2
+ import { buildRegistry } from "../fields/registry.js";
3
+ import { evaluateCondition } from "../conditions/evaluate.js";
4
+ import { defaultValidationRules } from "../validation/builtin/index.js";
5
+ import { buildRuleRegistry } from "../validation/registry.js";
6
+ //#region src/react/resolveForm.ts
7
+ /** Build the field-type registry from the bundled defaults plus any consumer-supplied extra definitions. */
8
+ const buildFieldTypeRegistry = (extra = []) => buildRegistry([...defaultFieldDefinitions, ...extra]);
9
+ /** Build the validation-rule registry from the bundled defaults plus consumer extras. */
10
+ const buildValidationRuleRegistry = (extra = []) => buildRuleRegistry([...defaultValidationRules, ...extra]);
11
+ /** The subset of fields currently visible, evaluating each field's `visibleWhen` against the answers. */
12
+ const visibleFields = (fields, values) => fields.filter((field) => evaluateCondition(field.visibleWhen, values));
13
+ //#endregion
14
+ export { buildFieldTypeRegistry, buildValidationRuleRegistry, visibleFields };
15
+
16
+ //# sourceMappingURL=resolveForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveForm.js","names":[],"sources":["../../src/react/resolveForm.ts"],"sourcesContent":["import { evaluateCondition } from '../conditions/evaluate'\nimport { defaultFieldDefinitions } from '../fields/builtin'\nimport { buildRegistry, type FieldTypeRegistry } from '../fields/registry'\nimport type { AnyFormFieldDefinition } from '../fields/types'\nimport type { FormFieldInstance } from '../submissions/types'\nimport { defaultValidationRules } from '../validation/builtin'\nimport { buildRuleRegistry, type ValidationRuleRegistry } from '../validation/registry'\nimport type { AnyValidationRuleDefinition } from '../validation/types'\n\n/** Build the field-type registry from the bundled defaults plus any consumer-supplied extra definitions. */\nexport const buildFieldTypeRegistry = (extra: AnyFormFieldDefinition[] = []): FieldTypeRegistry =>\n\tbuildRegistry([...defaultFieldDefinitions, ...extra])\n\n/** Build the validation-rule registry from the bundled defaults plus consumer extras. */\nexport const buildValidationRuleRegistry = (\n\textra: AnyValidationRuleDefinition[] = []\n): ValidationRuleRegistry => buildRuleRegistry([...defaultValidationRules, ...extra])\n\n/** The subset of fields currently visible, evaluating each field's `visibleWhen` against the answers. */\nexport const visibleFields = (\n\tfields: FormFieldInstance[],\n\tvalues: Record<string, unknown>\n): FormFieldInstance[] => fields.filter((field) => evaluateCondition(field.visibleWhen, values))\n"],"mappings":";;;;;;;AAUA,MAAa,0BAA0B,QAAkC,CAAC,MACzE,cAAc,CAAC,GAAG,yBAAyB,GAAG,KAAK,CAAC;;AAGrD,MAAa,+BACZ,QAAuC,CAAC,MACZ,kBAAkB,CAAC,GAAG,wBAAwB,GAAG,KAAK,CAAC;;AAGpF,MAAa,iBACZ,QACA,WACyB,OAAO,QAAQ,UAAU,kBAAkB,MAAM,aAAa,MAAM,CAAC"}
@@ -0,0 +1,52 @@
1
+ //#region src/react/state.d.ts
2
+ type FieldErrors = Record<string, string[]>;
3
+ type FormState = {
4
+ values: Record<string, unknown>;
5
+ errors: FieldErrors;
6
+ touched: Record<string, boolean>;
7
+ submitting: boolean;
8
+ submitted: boolean;
9
+ /**
10
+ * The step ids whose validation the user has attempted (a blocked advance, or a submit). A field
11
+ * reveals its error when it is touched or its own step is in this set, never via a single global flag,
12
+ * so a submit attempt cannot pre-reveal errors on a step the visitor has not reached.
13
+ */
14
+ attemptedSteps: Set<string>;
15
+ submitError?: string;
16
+ };
17
+ type FormAction = {
18
+ type: 'SET_VALUE';
19
+ name: string;
20
+ value: unknown;
21
+ } | {
22
+ type: 'TOUCH';
23
+ name: string;
24
+ } | {
25
+ type: 'SET_FIELD_ISSUES';
26
+ name: string;
27
+ errors: string[];
28
+ } | {
29
+ type: 'SET_ALL_ISSUES';
30
+ errors: FieldErrors;
31
+ steps: string[];
32
+ } | {
33
+ type: 'MARK_STEP_ATTEMPTED';
34
+ stepId: string;
35
+ } | {
36
+ type: 'REMOVE_REPEATER_ROW';
37
+ name: string;
38
+ index: number;
39
+ } | {
40
+ type: 'SUBMIT_START';
41
+ } | {
42
+ type: 'SUBMIT_SUCCESS';
43
+ } | {
44
+ type: 'SUBMIT_ERROR';
45
+ message: string;
46
+ } | {
47
+ type: 'RESET';
48
+ values: Record<string, unknown>;
49
+ };
50
+ //#endregion
51
+ export { FieldErrors, FormAction, FormState };
52
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1,125 @@
1
+ import { isNamedField } from "../fields/fieldKey.js";
2
+ //#region src/react/state.ts
3
+ /**
4
+ * The step a field's error reveal is keyed to when the form has no flow, or the field belongs to no
5
+ * step. A single-step form has exactly this one step, so its reveal collapses to the old global one.
6
+ */
7
+ const DEFAULT_STEP_ID = "__form__";
8
+ /**
9
+ * Per-field defaults for the reducer's initial state. Nameless (bare) blocks carry no value and
10
+ * are skipped. A repeater with a positive `minRows` starts pre-seeded with that many empty rows,
11
+ * matching the schema's own floor. Computed once, ahead of the reducer, so seeding is never an
12
+ * action: it can't touch a field, trigger validation, or (via `Form`'s dispatch wrapper) be
13
+ * mistaken for the user's first edit and fire `form.started`.
14
+ */
15
+ const seedFieldValues = (fields) => Object.fromEntries(fields.filter(isNamedField).map((field) => {
16
+ if (field.blockType === "repeater") {
17
+ const minRows = typeof field.minRows === "number" ? field.minRows : 0;
18
+ if (minRows > 0) return [field.name, Array.from({ length: minRows }, () => ({}))];
19
+ }
20
+ return [field.name, void 0];
21
+ }));
22
+ const initialFormState = (values) => ({
23
+ values,
24
+ errors: {},
25
+ touched: {},
26
+ submitting: false,
27
+ submitted: false,
28
+ attemptedSteps: /* @__PURE__ */ new Set()
29
+ });
30
+ /**
31
+ * Re-key composite entries (`name[i].sub`) after repeater row `removed` is deleted: drop the removed
32
+ * index and shift every higher index down by one, so surviving rows keep their own errors/touched
33
+ * flags instead of inheriting a deleted or shifted neighbour's. Matches on the `name[<int>]` prefix,
34
+ * so it is agnostic to the sub-key shape after `]` and needs no sub-field list. Returns the same
35
+ * reference when nothing changed, so an unrelated dispatch does not churn state identity.
36
+ */
37
+ const reindexRepeaterKeys = (map, name, removed) => {
38
+ const prefix = `${name}[`;
39
+ let changed = false;
40
+ const next = {};
41
+ for (const [key, value] of Object.entries(map)) {
42
+ if (!key.startsWith(prefix)) {
43
+ next[key] = value;
44
+ continue;
45
+ }
46
+ const close = key.indexOf("]", prefix.length);
47
+ const idx = close === -1 ? NaN : Number(key.slice(prefix.length, close));
48
+ if (!Number.isInteger(idx) || idx < removed) {
49
+ next[key] = value;
50
+ continue;
51
+ }
52
+ if (idx === removed) {
53
+ changed = true;
54
+ continue;
55
+ }
56
+ next[`${name}[${idx - 1}]${key.slice(close + 1)}`] = value;
57
+ changed = true;
58
+ }
59
+ return changed ? next : map;
60
+ };
61
+ /** Changing a value clears that field's prior errors (re-validated by the caller). */
62
+ const formReducer = (state, action) => {
63
+ switch (action.type) {
64
+ case "SET_VALUE": {
65
+ const { [action.name]: _removed, ...restErrors } = state.errors;
66
+ return {
67
+ ...state,
68
+ values: {
69
+ ...state.values,
70
+ [action.name]: action.value
71
+ },
72
+ errors: restErrors
73
+ };
74
+ }
75
+ case "TOUCH": return state.touched[action.name] ? state : {
76
+ ...state,
77
+ touched: {
78
+ ...state.touched,
79
+ [action.name]: true
80
+ }
81
+ };
82
+ case "SET_FIELD_ISSUES": return {
83
+ ...state,
84
+ errors: {
85
+ ...state.errors,
86
+ [action.name]: action.errors
87
+ }
88
+ };
89
+ case "SET_ALL_ISSUES": return {
90
+ ...state,
91
+ errors: action.errors,
92
+ attemptedSteps: new Set([...state.attemptedSteps, ...action.steps])
93
+ };
94
+ case "MARK_STEP_ATTEMPTED": return state.attemptedSteps.has(action.stepId) ? state : {
95
+ ...state,
96
+ attemptedSteps: new Set([...state.attemptedSteps, action.stepId])
97
+ };
98
+ case "REMOVE_REPEATER_ROW": return {
99
+ ...state,
100
+ errors: reindexRepeaterKeys(state.errors, action.name, action.index),
101
+ touched: reindexRepeaterKeys(state.touched, action.name, action.index)
102
+ };
103
+ case "SUBMIT_START": return {
104
+ ...state,
105
+ submitting: true,
106
+ submitError: void 0
107
+ };
108
+ case "SUBMIT_SUCCESS": return {
109
+ ...state,
110
+ submitting: false,
111
+ submitted: true
112
+ };
113
+ case "SUBMIT_ERROR": return {
114
+ ...state,
115
+ submitting: false,
116
+ submitError: action.message
117
+ };
118
+ case "RESET": return initialFormState(action.values);
119
+ default: return state;
120
+ }
121
+ };
122
+ //#endregion
123
+ export { DEFAULT_STEP_ID, formReducer, initialFormState, seedFieldValues };
124
+
125
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","names":[],"sources":["../../src/react/state.ts"],"sourcesContent":["import { isNamedField } from '../fields/fieldKey'\nimport type { FormFieldInstance } from '../submissions/types'\n\nexport type FieldErrors = Record<string, string[]>\n\n/**\n * The step a field's error reveal is keyed to when the form has no flow, or the field belongs to no\n * step. A single-step form has exactly this one step, so its reveal collapses to the old global one.\n */\nexport const DEFAULT_STEP_ID = '__form__'\n\nexport type FormState = {\n\tvalues: Record<string, unknown>\n\terrors: FieldErrors\n\ttouched: Record<string, boolean>\n\tsubmitting: boolean\n\tsubmitted: boolean\n\t/**\n\t * The step ids whose validation the user has attempted (a blocked advance, or a submit). A field\n\t * reveals its error when it is touched or its own step is in this set, never via a single global flag,\n\t * so a submit attempt cannot pre-reveal errors on a step the visitor has not reached.\n\t */\n\tattemptedSteps: Set<string>\n\tsubmitError?: string\n}\n\nexport type FormAction =\n\t| { type: 'SET_VALUE'; name: string; value: unknown }\n\t| { type: 'TOUCH'; name: string }\n\t| { type: 'SET_FIELD_ISSUES'; name: string; errors: string[] }\n\t| { type: 'SET_ALL_ISSUES'; errors: FieldErrors; steps: string[] }\n\t| { type: 'MARK_STEP_ATTEMPTED'; stepId: string }\n\t| { type: 'REMOVE_REPEATER_ROW'; name: string; index: number }\n\t| { type: 'SUBMIT_START' }\n\t| { type: 'SUBMIT_SUCCESS' }\n\t| { type: 'SUBMIT_ERROR'; message: string }\n\t| { type: 'RESET'; values: Record<string, unknown> }\n\n/**\n * Per-field defaults for the reducer's initial state. Nameless (bare) blocks carry no value and\n * are skipped. A repeater with a positive `minRows` starts pre-seeded with that many empty rows,\n * matching the schema's own floor. Computed once, ahead of the reducer, so seeding is never an\n * action: it can't touch a field, trigger validation, or (via `Form`'s dispatch wrapper) be\n * mistaken for the user's first edit and fire `form.started`.\n */\nexport const seedFieldValues = (fields: FormFieldInstance[]): Record<string, unknown> =>\n\tObject.fromEntries(\n\t\tfields.filter(isNamedField).map((field) => {\n\t\t\tif (field.blockType === 'repeater') {\n\t\t\t\tconst minRows = typeof field.minRows === 'number' ? field.minRows : 0\n\t\t\t\tif (minRows > 0) {\n\t\t\t\t\treturn [field.name, Array.from({ length: minRows }, () => ({}))]\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn [field.name, undefined]\n\t\t})\n\t)\n\nexport const initialFormState = (values: Record<string, unknown>): FormState => ({\n\tvalues,\n\terrors: {},\n\ttouched: {},\n\tsubmitting: false,\n\tsubmitted: false,\n\tattemptedSteps: new Set(),\n})\n\n/**\n * Re-key composite entries (`name[i].sub`) after repeater row `removed` is deleted: drop the removed\n * index and shift every higher index down by one, so surviving rows keep their own errors/touched\n * flags instead of inheriting a deleted or shifted neighbour's. Matches on the `name[<int>]` prefix,\n * so it is agnostic to the sub-key shape after `]` and needs no sub-field list. Returns the same\n * reference when nothing changed, so an unrelated dispatch does not churn state identity.\n */\nconst reindexRepeaterKeys = <T>(\n\tmap: Record<string, T>,\n\tname: string,\n\tremoved: number\n): Record<string, T> => {\n\tconst prefix = `${name}[`\n\tlet changed = false\n\tconst next: Record<string, T> = {}\n\tfor (const [key, value] of Object.entries(map)) {\n\t\tif (!key.startsWith(prefix)) {\n\t\t\tnext[key] = value\n\t\t\tcontinue\n\t\t}\n\t\tconst close = key.indexOf(']', prefix.length)\n\t\tconst idx = close === -1 ? Number.NaN : Number(key.slice(prefix.length, close))\n\t\tif (!Number.isInteger(idx) || idx < removed) {\n\t\t\tnext[key] = value\n\t\t\tcontinue\n\t\t}\n\t\tif (idx === removed) {\n\t\t\tchanged = true\n\t\t\tcontinue\n\t\t}\n\t\tnext[`${name}[${idx - 1}]${key.slice(close + 1)}`] = value\n\t\tchanged = true\n\t}\n\treturn changed ? next : map\n}\n\n/** Changing a value clears that field's prior errors (re-validated by the caller). */\nexport const formReducer = (state: FormState, action: FormAction): FormState => {\n\tswitch (action.type) {\n\t\tcase 'SET_VALUE': {\n\t\t\tconst { [action.name]: _removed, ...restErrors } = state.errors\n\t\t\treturn {\n\t\t\t\t...state,\n\t\t\t\tvalues: { ...state.values, [action.name]: action.value },\n\t\t\t\terrors: restErrors,\n\t\t\t}\n\t\t}\n\t\tcase 'TOUCH':\n\t\t\treturn state.touched[action.name]\n\t\t\t\t? state\n\t\t\t\t: { ...state, touched: { ...state.touched, [action.name]: true } }\n\t\tcase 'SET_FIELD_ISSUES':\n\t\t\treturn {\n\t\t\t\t...state,\n\t\t\t\terrors: { ...state.errors, [action.name]: action.errors },\n\t\t\t}\n\t\tcase 'SET_ALL_ISSUES':\n\t\t\treturn {\n\t\t\t\t...state,\n\t\t\t\terrors: action.errors,\n\t\t\t\tattemptedSteps: new Set([...state.attemptedSteps, ...action.steps]),\n\t\t\t}\n\t\tcase 'MARK_STEP_ATTEMPTED':\n\t\t\treturn state.attemptedSteps.has(action.stepId)\n\t\t\t\t? state\n\t\t\t\t: { ...state, attemptedSteps: new Set([...state.attemptedSteps, action.stepId]) }\n\t\tcase 'REMOVE_REPEATER_ROW':\n\t\t\t// The row value is removed by the field's own SET_VALUE; this shifts the composite issue keys\n\t\t\t// (`name[i].sub`) that a plain value array cannot carry, so a deleted row's errors never strand\n\t\t\t// on a survivor or linger unreachably.\n\t\t\treturn {\n\t\t\t\t...state,\n\t\t\t\terrors: reindexRepeaterKeys(state.errors, action.name, action.index),\n\t\t\t\ttouched: reindexRepeaterKeys(state.touched, action.name, action.index),\n\t\t\t}\n\t\tcase 'SUBMIT_START':\n\t\t\treturn { ...state, submitting: true, submitError: undefined }\n\t\tcase 'SUBMIT_SUCCESS':\n\t\t\treturn { ...state, submitting: false, submitted: true }\n\t\tcase 'SUBMIT_ERROR':\n\t\t\treturn { ...state, submitting: false, submitError: action.message }\n\t\tcase 'RESET':\n\t\t\treturn initialFormState(action.values)\n\t\tdefault:\n\t\t\treturn state\n\t}\n}\n"],"mappings":";;;;;;AASA,MAAa,kBAAkB;;;;;;;;AAoC/B,MAAa,mBAAmB,WAC/B,OAAO,YACN,OAAO,OAAO,YAAY,EAAE,KAAK,UAAU;CAC1C,IAAI,MAAM,cAAc,YAAY;EACnC,MAAM,UAAU,OAAO,MAAM,YAAY,WAAW,MAAM,UAAU;EACpE,IAAI,UAAU,GACb,OAAO,CAAC,MAAM,MAAM,MAAM,KAAK,EAAE,QAAQ,QAAQ,UAAU,CAAC,EAAE,CAAC;CAEjE;CACA,OAAO,CAAC,MAAM,MAAM,KAAA,CAAS;AAC9B,CAAC,CACF;AAED,MAAa,oBAAoB,YAAgD;CAChF;CACA,QAAQ,CAAC;CACT,SAAS,CAAC;CACV,YAAY;CACZ,WAAW;CACX,gCAAgB,IAAI,IAAI;AACzB;;;;;;;;AASA,MAAM,uBACL,KACA,MACA,YACuB;CACvB,MAAM,SAAS,GAAG,KAAK;CACvB,IAAI,UAAU;CACd,MAAM,OAA0B,CAAC;CACjC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,GAAG,GAAG;EAC/C,IAAI,CAAC,IAAI,WAAW,MAAM,GAAG;GAC5B,KAAK,OAAO;GACZ;EACD;EACA,MAAM,QAAQ,IAAI,QAAQ,KAAK,OAAO,MAAM;EAC5C,MAAM,MAAM,UAAU,KAAK,MAAa,OAAO,IAAI,MAAM,OAAO,QAAQ,KAAK,CAAC;EAC9E,IAAI,CAAC,OAAO,UAAU,GAAG,KAAK,MAAM,SAAS;GAC5C,KAAK,OAAO;GACZ;EACD;EACA,IAAI,QAAQ,SAAS;GACpB,UAAU;GACV;EACD;EACA,KAAK,GAAG,KAAK,GAAG,MAAM,EAAE,GAAG,IAAI,MAAM,QAAQ,CAAC,OAAO;EACrD,UAAU;CACX;CACA,OAAO,UAAU,OAAO;AACzB;;AAGA,MAAa,eAAe,OAAkB,WAAkC;CAC/E,QAAQ,OAAO,MAAf;EACC,KAAK,aAAa;GACjB,MAAM,GAAG,OAAO,OAAO,UAAU,GAAG,eAAe,MAAM;GACzD,OAAO;IACN,GAAG;IACH,QAAQ;KAAE,GAAG,MAAM;MAAS,OAAO,OAAO,OAAO;IAAM;IACvD,QAAQ;GACT;EACD;EACA,KAAK,SACJ,OAAO,MAAM,QAAQ,OAAO,QACzB,QACA;GAAE,GAAG;GAAO,SAAS;IAAE,GAAG,MAAM;KAAU,OAAO,OAAO;GAAK;EAAE;EACnE,KAAK,oBACJ,OAAO;GACN,GAAG;GACH,QAAQ;IAAE,GAAG,MAAM;KAAS,OAAO,OAAO,OAAO;GAAO;EACzD;EACD,KAAK,kBACJ,OAAO;GACN,GAAG;GACH,QAAQ,OAAO;GACf,gBAAgB,IAAI,IAAI,CAAC,GAAG,MAAM,gBAAgB,GAAG,OAAO,KAAK,CAAC;EACnE;EACD,KAAK,uBACJ,OAAO,MAAM,eAAe,IAAI,OAAO,MAAM,IAC1C,QACA;GAAE,GAAG;GAAO,gBAAgB,IAAI,IAAI,CAAC,GAAG,MAAM,gBAAgB,OAAO,MAAM,CAAC;EAAE;EAClF,KAAK,uBAIJ,OAAO;GACN,GAAG;GACH,QAAQ,oBAAoB,MAAM,QAAQ,OAAO,MAAM,OAAO,KAAK;GACnE,SAAS,oBAAoB,MAAM,SAAS,OAAO,MAAM,OAAO,KAAK;EACtE;EACD,KAAK,gBACJ,OAAO;GAAE,GAAG;GAAO,YAAY;GAAM,aAAa,KAAA;EAAU;EAC7D,KAAK,kBACJ,OAAO;GAAE,GAAG;GAAO,YAAY;GAAO,WAAW;EAAK;EACvD,KAAK,gBACJ,OAAO;GAAE,GAAG;GAAO,YAAY;GAAO,aAAa,OAAO;EAAQ;EACnE,KAAK,SACJ,OAAO,iBAAiB,OAAO,MAAM;EACtC,SACC,OAAO;CACT;AACD"}
@@ -0,0 +1,31 @@
1
+ import { SubmissionValue } from "../submissions/types.js";
2
+
3
+ //#region src/react/submitForm.d.ts
4
+ type SubmitFormInput = {
5
+ formId: number | string;
6
+ values: SubmissionValue[]; /** Payload API route prefix; defaults to `/api`. */
7
+ apiRoute?: string; /** Injectable for testing; defaults to global `fetch`. */
8
+ fetchImpl?: typeof fetch;
9
+ };
10
+ type SubmitFormResult = {
11
+ ok: true;
12
+ submissionId?: string;
13
+ } | {
14
+ ok: false;
15
+ fieldErrors?: Record<string, string[]>;
16
+ message?: string;
17
+ };
18
+ /**
19
+ * The default submission transport: POST `{apiRoute}/form-submissions` with `{ form, values }`. On 201
20
+ * returns the created submission id; on a 400 Payload `ValidationError` maps `data.errors[].path` to
21
+ * per-field messages; otherwise returns a generic message. Pure: inject `fetchImpl` in tests.
22
+ */
23
+ declare const submitForm: (input: SubmitFormInput) => Promise<SubmitFormResult>;
24
+ /** A consumer override for the transport: given the form id + values, resolve to a submit result. */
25
+ type SubmitHandler = (input: {
26
+ formId: number | string;
27
+ values: SubmissionValue[];
28
+ }) => Promise<SubmitFormResult>;
29
+ //#endregion
30
+ export { SubmitFormResult, SubmitHandler, submitForm };
31
+ //# sourceMappingURL=submitForm.d.ts.map
@@ -0,0 +1,58 @@
1
+ //#region src/react/submitForm.ts
2
+ const toFieldErrors = (body) => {
3
+ const nested = body.errors?.[0]?.data?.errors ?? [];
4
+ const map = {};
5
+ for (const entry of nested) if (typeof entry.path === "string" && typeof entry.message === "string") map[entry.path] = [...map[entry.path] ?? [], entry.message];
6
+ return map;
7
+ };
8
+ /**
9
+ * The default submission transport: POST `{apiRoute}/form-submissions` with `{ form, values }`. On 201
10
+ * returns the created submission id; on a 400 Payload `ValidationError` maps `data.errors[].path` to
11
+ * per-field messages; otherwise returns a generic message. Pure: inject `fetchImpl` in tests.
12
+ */
13
+ const submitForm = async (input) => {
14
+ const { formId, values, apiRoute = "/api", fetchImpl = fetch } = input;
15
+ let response;
16
+ try {
17
+ response = await fetchImpl(`${apiRoute}/form-submissions`, {
18
+ method: "POST",
19
+ headers: { "Content-Type": "application/json" },
20
+ body: JSON.stringify({
21
+ form: formId,
22
+ values
23
+ })
24
+ });
25
+ } catch (error) {
26
+ return {
27
+ ok: false,
28
+ message: error instanceof Error ? error.message : "Network error"
29
+ };
30
+ }
31
+ if (response.ok) {
32
+ const id = (await response.json().catch(() => ({}))).doc?.id;
33
+ return {
34
+ ok: true,
35
+ submissionId: id === void 0 ? void 0 : String(id)
36
+ };
37
+ }
38
+ if (response.status === 400) {
39
+ const body = await response.json().catch(() => ({}));
40
+ const fieldErrors = toFieldErrors(body);
41
+ if (Object.keys(fieldErrors).length > 0) return {
42
+ ok: false,
43
+ fieldErrors
44
+ };
45
+ return {
46
+ ok: false,
47
+ message: body.errors?.[0]?.message ?? "Validation failed"
48
+ };
49
+ }
50
+ return {
51
+ ok: false,
52
+ message: `Request failed (${response.status})`
53
+ };
54
+ };
55
+ //#endregion
56
+ export { submitForm };
57
+
58
+ //# sourceMappingURL=submitForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submitForm.js","names":[],"sources":["../../src/react/submitForm.ts"],"sourcesContent":["import type { SubmissionValue } from '../submissions/types'\n\nexport type SubmitFormInput = {\n\tformId: number | string\n\tvalues: SubmissionValue[]\n\t/** Payload API route prefix; defaults to `/api`. */\n\tapiRoute?: string\n\t/** Injectable for testing; defaults to global `fetch`. */\n\tfetchImpl?: typeof fetch\n}\n\nexport type SubmitFormResult =\n\t| { ok: true; submissionId?: string }\n\t| { ok: false; fieldErrors?: Record<string, string[]>; message?: string }\n\ntype ValidationErrorBody = {\n\terrors?: Array<{\n\t\tmessage?: string\n\t\tdata?: { errors?: Array<{ path?: string; message?: string }> }\n\t}>\n}\n\nconst toFieldErrors = (body: ValidationErrorBody): Record<string, string[]> => {\n\tconst nested = body.errors?.[0]?.data?.errors ?? []\n\tconst map: Record<string, string[]> = {}\n\tfor (const entry of nested) {\n\t\tif (typeof entry.path === 'string' && typeof entry.message === 'string') {\n\t\t\tmap[entry.path] = [...(map[entry.path] ?? []), entry.message]\n\t\t}\n\t}\n\treturn map\n}\n\n/**\n * The default submission transport: POST `{apiRoute}/form-submissions` with `{ form, values }`. On 201\n * returns the created submission id; on a 400 Payload `ValidationError` maps `data.errors[].path` to\n * per-field messages; otherwise returns a generic message. Pure: inject `fetchImpl` in tests.\n */\nexport const submitForm = async (input: SubmitFormInput): Promise<SubmitFormResult> => {\n\tconst { formId, values, apiRoute = '/api', fetchImpl = fetch } = input\n\tlet response: Response\n\ttry {\n\t\tresponse = await fetchImpl(`${apiRoute}/form-submissions`, {\n\t\t\tmethod: 'POST',\n\t\t\theaders: { 'Content-Type': 'application/json' },\n\t\t\tbody: JSON.stringify({ form: formId, values }),\n\t\t})\n\t} catch (error) {\n\t\treturn { ok: false, message: error instanceof Error ? error.message : 'Network error' }\n\t}\n\tif (response.ok) {\n\t\tconst data = (await response.json().catch(() => ({}))) as { doc?: { id?: number | string } }\n\t\tconst id = data.doc?.id\n\t\treturn { ok: true, submissionId: id === undefined ? undefined : String(id) }\n\t}\n\tif (response.status === 400) {\n\t\tconst body = (await response.json().catch(() => ({}))) as ValidationErrorBody\n\t\tconst fieldErrors = toFieldErrors(body)\n\t\tif (Object.keys(fieldErrors).length > 0) {\n\t\t\treturn { ok: false, fieldErrors }\n\t\t}\n\t\treturn { ok: false, message: body.errors?.[0]?.message ?? 'Validation failed' }\n\t}\n\treturn { ok: false, message: `Request failed (${response.status})` }\n}\n\n/** A consumer override for the transport: given the form id + values, resolve to a submit result. */\nexport type SubmitHandler = (input: {\n\tformId: number | string\n\tvalues: SubmissionValue[]\n}) => Promise<SubmitFormResult>\n"],"mappings":";AAsBA,MAAM,iBAAiB,SAAwD;CAC9E,MAAM,SAAS,KAAK,SAAS,IAAI,MAAM,UAAU,CAAC;CAClD,MAAM,MAAgC,CAAC;CACvC,KAAK,MAAM,SAAS,QACnB,IAAI,OAAO,MAAM,SAAS,YAAY,OAAO,MAAM,YAAY,UAC9D,IAAI,MAAM,QAAQ,CAAC,GAAI,IAAI,MAAM,SAAS,CAAC,GAAI,MAAM,OAAO;CAG9D,OAAO;AACR;;;;;;AAOA,MAAa,aAAa,OAAO,UAAsD;CACtF,MAAM,EAAE,QAAQ,QAAQ,WAAW,QAAQ,YAAY,UAAU;CACjE,IAAI;CACJ,IAAI;EACH,WAAW,MAAM,UAAU,GAAG,SAAS,oBAAoB;GAC1D,QAAQ;GACR,SAAS,EAAE,gBAAgB,mBAAmB;GAC9C,MAAM,KAAK,UAAU;IAAE,MAAM;IAAQ;GAAO,CAAC;EAC9C,CAAC;CACF,SAAS,OAAO;EACf,OAAO;GAAE,IAAI;GAAO,SAAS,iBAAiB,QAAQ,MAAM,UAAU;EAAgB;CACvF;CACA,IAAI,SAAS,IAAI;EAEhB,MAAM,MAAK,MADS,SAAS,KAAK,EAAE,aAAa,CAAC,EAAE,GACpC,KAAK;EACrB,OAAO;GAAE,IAAI;GAAM,cAAc,OAAO,KAAA,IAAY,KAAA,IAAY,OAAO,EAAE;EAAE;CAC5E;CACA,IAAI,SAAS,WAAW,KAAK;EAC5B,MAAM,OAAQ,MAAM,SAAS,KAAK,EAAE,aAAa,CAAC,EAAE;EACpD,MAAM,cAAc,cAAc,IAAI;EACtC,IAAI,OAAO,KAAK,WAAW,EAAE,SAAS,GACrC,OAAO;GAAE,IAAI;GAAO;EAAY;EAEjC,OAAO;GAAE,IAAI;GAAO,SAAS,KAAK,SAAS,IAAI,WAAW;EAAoB;CAC/E;CACA,OAAO;EAAE,IAAI;EAAO,SAAS,mBAAmB,SAAS,OAAO;CAAG;AACpE"}
@@ -0,0 +1,23 @@
1
+ //#region src/react/uploadFile.d.ts
2
+ type UploadFileInput = {
3
+ file: File; /** Upload collection slug. File fields carry it as the server-stamped `collection` block config. */
4
+ collection: string;
5
+ apiRoute?: string;
6
+ fetchImpl?: typeof fetch;
7
+ };
8
+ type UploadFileResult = {
9
+ ok: true;
10
+ id: string | number;
11
+ } | {
12
+ ok: false;
13
+ message?: string;
14
+ };
15
+ /**
16
+ * Upload one file to a Payload upload collection (`POST {apiRoute}/{collection}`, multipart) and return its
17
+ * id, which the file field stores as its value. The server re-derives the file metadata from the stored doc
18
+ * at submit, so the client is never trusted for it. Pure: inject `fetchImpl` in tests.
19
+ */
20
+ declare const uploadFile: (input: UploadFileInput) => Promise<UploadFileResult>;
21
+ //#endregion
22
+ export { UploadFileInput, UploadFileResult, uploadFile };
23
+ //# sourceMappingURL=uploadFile.d.ts.map