@10x-media/form-builder 0.1.0-beta.1 → 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 (546) hide show
  1. package/CHANGELOG.md +293 -0
  2. package/README.md +6 -4
  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 +12 -9
  21. package/dist/actions/buildActionBlocks.js.map +1 -1
  22. package/dist/actions/builtin/confirmation.js +46 -43
  23. package/dist/actions/builtin/confirmation.js.map +1 -1
  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 +14 -38
  28. package/dist/actions/builtin/emailTeam.js.map +1 -1
  29. package/dist/actions/builtin/index.d.ts +16 -1
  30. package/dist/actions/builtin/index.js +21 -7
  31. package/dist/actions/builtin/index.js.map +1 -1
  32. package/dist/actions/builtin/signedWebhook.js +6 -2
  33. package/dist/actions/builtin/signedWebhook.js.map +1 -1
  34. package/dist/actions/defineAction.d.ts +5 -4
  35. package/dist/actions/defineAction.js.map +1 -1
  36. package/dist/actions/dispatch.js +2 -1
  37. package/dist/actions/dispatch.js.map +1 -1
  38. package/dist/actions/emailRecipients.d.ts +12 -0
  39. package/dist/actions/emailRecipients.js +116 -0
  40. package/dist/actions/emailRecipients.js.map +1 -0
  41. package/dist/actions/fromAddresses.d.ts +21 -0
  42. package/dist/actions/fromAddresses.js +74 -0
  43. package/dist/actions/fromAddresses.js.map +1 -0
  44. package/dist/actions/registry.d.ts +2 -1
  45. package/dist/actions/registry.js +2 -6
  46. package/dist/actions/registry.js.map +1 -1
  47. package/dist/actions/runActions.js +10 -1
  48. package/dist/actions/runActions.js.map +1 -1
  49. package/dist/actions/task.js +20 -15
  50. package/dist/actions/task.js.map +1 -1
  51. package/dist/aggregation/aggregateResponses.d.ts +9 -0
  52. package/dist/aggregation/aggregateResponses.js +8 -14
  53. package/dist/aggregation/aggregateResponses.js.map +1 -1
  54. package/dist/aggregation/resolveResultsRequest.d.ts +35 -6
  55. package/dist/aggregation/resolveResultsRequest.js +68 -11
  56. package/dist/aggregation/resolveResultsRequest.js.map +1 -1
  57. package/dist/calc/computeCalcFields.js +2 -1
  58. package/dist/calc/computeCalcFields.js.map +1 -1
  59. package/dist/calc/evaluate.js +1 -2
  60. package/dist/calc/evaluate.js.map +1 -1
  61. package/dist/calc/normalizeCalc.js +6 -19
  62. package/dist/calc/normalizeCalc.js.map +1 -1
  63. package/dist/calc/types.d.ts +8 -2
  64. package/dist/calc/types.js +22 -0
  65. package/dist/calc/types.js.map +1 -0
  66. package/dist/client/ByteSizeField.d.ts +29 -0
  67. package/dist/client/ByteSizeField.js +58 -0
  68. package/dist/client/ByteSizeField.js.map +1 -0
  69. package/dist/client/ClosePollButton.d.ts +15 -0
  70. package/dist/client/ClosePollButton.js +80 -0
  71. package/dist/client/ClosePollButton.js.map +1 -0
  72. package/dist/client/CondensedArray.d.ts +15 -0
  73. package/dist/client/CondensedArray.js +97 -0
  74. package/dist/client/CondensedArray.js.map +1 -0
  75. package/dist/client/ConditionBuilder.js +2 -1
  76. package/dist/client/ConditionBuilder.js.map +1 -1
  77. package/dist/client/ConsentBlockLabel.d.ts +15 -0
  78. package/dist/client/ConsentBlockLabel.js +71 -0
  79. package/dist/client/ConsentBlockLabel.js.map +1 -0
  80. package/dist/client/ConsentSourceRowLabel.d.ts +9 -0
  81. package/dist/client/ConsentSourceRowLabel.js +21 -0
  82. package/dist/client/ConsentSourceRowLabel.js.map +1 -0
  83. package/dist/client/EndpointOptionsSelect.d.ts +46 -0
  84. package/dist/client/EndpointOptionsSelect.js +106 -0
  85. package/dist/client/EndpointOptionsSelect.js.map +1 -0
  86. package/dist/client/FieldBlockLabel.d.ts +18 -0
  87. package/dist/client/FieldBlockLabel.js +34 -0
  88. package/dist/client/FieldBlockLabel.js.map +1 -0
  89. package/dist/client/FieldNameSelect.d.ts +37 -0
  90. package/dist/client/FieldNameSelect.js +72 -0
  91. package/dist/client/FieldNameSelect.js.map +1 -0
  92. package/dist/client/FlowBuilder.d.ts +2 -2
  93. package/dist/client/FlowBuilder.js +137 -88
  94. package/dist/client/FlowBuilder.js.map +1 -1
  95. package/dist/client/FormConditionField.js +1 -4
  96. package/dist/client/FormConditionField.js.map +1 -1
  97. package/dist/client/RecipientsSelect.d.ts +31 -0
  98. package/dist/client/RecipientsSelect.js +174 -0
  99. package/dist/client/RecipientsSelect.js.map +1 -0
  100. package/dist/client/RuleDescription.d.ts +21 -0
  101. package/dist/client/RuleDescription.js +19 -0
  102. package/dist/client/RuleDescription.js.map +1 -0
  103. package/dist/client/admin.css +275 -0
  104. package/dist/client/endpointOptions.js +29 -0
  105. package/dist/client/endpointOptions.js.map +1 -0
  106. package/dist/client/flowAuthoring.js +142 -0
  107. package/dist/client/flowAuthoring.js.map +1 -0
  108. package/dist/client/synthesizeClientField.js +21 -10
  109. package/dist/client/synthesizeClientField.js.map +1 -1
  110. package/dist/client/toStaticLabel.js +13 -0
  111. package/dist/client/toStaticLabel.js.map +1 -0
  112. package/dist/collections/buttonFields.d.ts +34 -0
  113. package/dist/collections/buttonFields.js +35 -0
  114. package/dist/collections/buttonFields.js.map +1 -0
  115. package/dist/collections/cells/FieldCountCell.d.ts +15 -0
  116. package/dist/collections/cells/FieldCountCell.js +18 -0
  117. package/dist/collections/cells/FieldCountCell.js.map +1 -0
  118. package/dist/collections/cells/FlowStepsCell.d.ts +14 -0
  119. package/dist/collections/cells/FlowStepsCell.js +17 -0
  120. package/dist/collections/cells/FlowStepsCell.js.map +1 -0
  121. package/dist/collections/formSubmissions.js +108 -42
  122. package/dist/collections/formSubmissions.js.map +1 -1
  123. package/dist/collections/forms.js +409 -114
  124. package/dist/collections/forms.js.map +1 -1
  125. package/dist/collections/formsEndpoints.js +101 -0
  126. package/dist/collections/formsEndpoints.js.map +1 -0
  127. package/dist/collections/redirectFields.d.ts +29 -0
  128. package/dist/conditions/conditionType.js +9 -2
  129. package/dist/conditions/conditionType.js.map +1 -1
  130. package/dist/conditions/evaluate.js +1 -1
  131. package/dist/conditions/evaluate.js.map +1 -1
  132. package/dist/conditions/fieldTypes.d.ts +3 -1
  133. package/dist/conditions/fieldTypes.js +4 -1
  134. package/dist/conditions/fieldTypes.js.map +1 -1
  135. package/dist/conditions/normalizeConditions.js +20 -6
  136. package/dist/conditions/normalizeConditions.js.map +1 -1
  137. package/dist/consent/applyConsentStatements.d.ts +14 -0
  138. package/dist/consent/applyConsentStatements.js +17 -0
  139. package/dist/consent/applyConsentStatements.js.map +1 -0
  140. package/dist/consent/captureConsent.d.ts +38 -11
  141. package/dist/consent/captureConsent.js +60 -13
  142. package/dist/consent/captureConsent.js.map +1 -1
  143. package/dist/consent/consentSourcesField.d.ts +66 -0
  144. package/dist/consent/consentSourcesField.js +90 -0
  145. package/dist/consent/consentSourcesField.js.map +1 -0
  146. package/dist/consent/resolveConsentEntries.d.ts +24 -0
  147. package/dist/consent/resolveConsentEntries.js +40 -0
  148. package/dist/consent/resolveConsentEntries.js.map +1 -0
  149. package/dist/consent/resolveConsentSourcesRequest.d.ts +37 -0
  150. package/dist/consent/resolveConsentSourcesRequest.js +54 -0
  151. package/dist/consent/resolveConsentSourcesRequest.js.map +1 -0
  152. package/dist/consent/resolveConsentStatements.d.ts +45 -0
  153. package/dist/consent/resolveConsentStatements.js +44 -0
  154. package/dist/consent/resolveConsentStatements.js.map +1 -0
  155. package/dist/consent/resolvePublishedVersionRef.d.ts +17 -11
  156. package/dist/consent/resolvePublishedVersionRef.js +13 -10
  157. package/dist/consent/resolvePublishedVersionRef.js.map +1 -1
  158. package/dist/consent/types.d.ts +61 -0
  159. package/dist/email/departments.d.ts +59 -0
  160. package/dist/email/departments.js +87 -0
  161. package/dist/email/departments.js.map +1 -0
  162. package/dist/email/departmentsField.d.ts +53 -0
  163. package/dist/email/departmentsField.js +73 -0
  164. package/dist/email/departmentsField.js.map +1 -0
  165. package/dist/exports/client.d.ts +13 -1
  166. package/dist/exports/client.js +13 -1
  167. package/dist/exports/i18n.d.ts +5 -2
  168. package/dist/exports/i18n.js +5 -2
  169. package/dist/exports/react.d.ts +26 -8
  170. package/dist/exports/react.js +19 -3
  171. package/dist/exports/rsc.d.ts +8 -1
  172. package/dist/exports/rsc.js +8 -1
  173. package/dist/exports/types.d.ts +19 -10
  174. package/dist/fields/buildFieldBlocks.js +53 -19
  175. package/dist/fields/buildFieldBlocks.js.map +1 -1
  176. package/dist/fields/builtin/calculation.js +122 -2
  177. package/dist/fields/builtin/calculation.js.map +1 -1
  178. package/dist/fields/builtin/checkbox.js +8 -0
  179. package/dist/fields/builtin/checkbox.js.map +1 -1
  180. package/dist/fields/builtin/consent.js +30 -15
  181. package/dist/fields/builtin/consent.js.map +1 -1
  182. package/dist/fields/builtin/country.d.ts +13 -0
  183. package/dist/fields/builtin/country.js +30 -0
  184. package/dist/fields/builtin/country.js.map +1 -0
  185. package/dist/fields/builtin/date.js +31 -0
  186. package/dist/fields/builtin/date.js.map +1 -0
  187. package/dist/fields/builtin/email.js +1 -1
  188. package/dist/fields/builtin/email.js.map +1 -1
  189. package/dist/fields/builtin/file.d.ts +15 -0
  190. package/dist/fields/builtin/file.js +95 -8
  191. package/dist/fields/builtin/file.js.map +1 -1
  192. package/dist/fields/builtin/index.d.ts +26 -0
  193. package/dist/fields/builtin/index.js +30 -6
  194. package/dist/fields/builtin/index.js.map +1 -1
  195. package/dist/fields/builtin/message.js +30 -0
  196. package/dist/fields/builtin/message.js.map +1 -0
  197. package/dist/fields/builtin/repeater.js +49 -0
  198. package/dist/fields/builtin/repeater.js.map +1 -0
  199. package/dist/fields/builtin/select.js +8 -3
  200. package/dist/fields/builtin/select.js.map +1 -1
  201. package/dist/fields/builtin/state.d.ts +13 -0
  202. package/dist/fields/builtin/state.js +30 -0
  203. package/dist/fields/builtin/state.js.map +1 -0
  204. package/dist/fields/data/regions.d.ts +21 -0
  205. package/dist/fields/data/regions.js +1238 -0
  206. package/dist/fields/data/regions.js.map +1 -0
  207. package/dist/fields/fieldKey.d.ts +15 -0
  208. package/dist/fields/fieldKey.js +16 -0
  209. package/dist/fields/fieldKey.js.map +1 -0
  210. package/dist/fields/fieldNamesOfType.js +30 -0
  211. package/dist/fields/fieldNamesOfType.js.map +1 -0
  212. package/dist/fields/instanceOptions.js +20 -0
  213. package/dist/fields/instanceOptions.js.map +1 -0
  214. package/dist/fields/localizedIf.d.ts +13 -0
  215. package/dist/fields/localizedIf.js +12 -0
  216. package/dist/fields/localizedIf.js.map +1 -0
  217. package/dist/fields/registry.d.ts +3 -1
  218. package/dist/fields/registry.js +23 -8
  219. package/dist/fields/registry.js.map +1 -1
  220. package/dist/fields/sharedConfig.js +120 -58
  221. package/dist/fields/sharedConfig.js.map +1 -1
  222. package/dist/fields/types.d.ts +71 -7
  223. package/dist/flow/engine.d.ts +6 -4
  224. package/dist/flow/engine.js +11 -6
  225. package/dist/flow/engine.js.map +1 -1
  226. package/dist/flow/normalizeFlow.js +28 -9
  227. package/dist/flow/normalizeFlow.js.map +1 -1
  228. package/dist/flow/stepLabel.js +15 -0
  229. package/dist/flow/stepLabel.js.map +1 -0
  230. package/dist/flow/types.d.ts +12 -3
  231. package/dist/flow/types.js +11 -0
  232. package/dist/flow/types.js.map +1 -0
  233. package/dist/form/pollState.d.ts +22 -0
  234. package/dist/form/pollState.js +17 -0
  235. package/dist/form/pollState.js.map +1 -0
  236. package/dist/form/toFormDocument.d.ts +102 -0
  237. package/dist/form/toFormDocument.js +87 -0
  238. package/dist/form/toFormDocument.js.map +1 -0
  239. package/dist/form/types.d.ts +65 -0
  240. package/dist/index.d.ts +53 -39
  241. package/dist/index.js +85 -23
  242. package/dist/index.js.map +1 -1
  243. package/dist/options.d.ts +229 -0
  244. package/dist/plugin/applyRegistryConfig.d.ts +11 -0
  245. package/dist/plugin/applyRegistryConfig.js +20 -0
  246. package/dist/plugin/applyRegistryConfig.js.map +1 -0
  247. package/dist/plugin/collectionOverrides.d.ts +22 -0
  248. package/dist/plugin/customState.js +26 -0
  249. package/dist/plugin/customState.js.map +1 -0
  250. package/dist/plugin/registerCollections.js +40 -20
  251. package/dist/plugin/registerCollections.js.map +1 -1
  252. package/dist/plugin/uploadsCollection.d.ts +16 -0
  253. package/dist/plugin/uploadsCollection.js +53 -0
  254. package/dist/plugin/uploadsCollection.js.map +1 -0
  255. package/dist/poll/applyPollOptions.js +18 -0
  256. package/dist/poll/applyPollOptions.js.map +1 -0
  257. package/dist/poll/buildPollOptionSourceFields.js +50 -0
  258. package/dist/poll/buildPollOptionSourceFields.js.map +1 -0
  259. package/dist/poll/closeJob.d.ts +52 -0
  260. package/dist/poll/closeJob.js +119 -0
  261. package/dist/poll/closeJob.js.map +1 -0
  262. package/dist/poll/definePollOptionSource.d.ts +44 -0
  263. package/dist/poll/definePollOptionSource.js +6 -0
  264. package/dist/poll/definePollOptionSource.js.map +1 -0
  265. package/dist/poll/definePollType.d.ts +34 -0
  266. package/dist/poll/definePollType.js +6 -0
  267. package/dist/poll/definePollType.js.map +1 -0
  268. package/dist/poll/effectivePollOptions.d.ts +38 -0
  269. package/dist/poll/effectivePollOptions.js +64 -0
  270. package/dist/poll/effectivePollOptions.js.map +1 -0
  271. package/dist/poll/mostVoted.d.ts +21 -0
  272. package/dist/poll/mostVoted.js +32 -0
  273. package/dist/poll/mostVoted.js.map +1 -0
  274. package/dist/poll/outcomeBeforeChange.js +91 -0
  275. package/dist/poll/outcomeBeforeChange.js.map +1 -0
  276. package/dist/poll/outcomeFields.d.ts +38 -0
  277. package/dist/poll/outcomeFields.js +52 -0
  278. package/dist/poll/outcomeFields.js.map +1 -0
  279. package/dist/poll/pollTypeRegistry.d.ts +34 -0
  280. package/dist/poll/pollTypeRegistry.js +69 -0
  281. package/dist/poll/pollTypeRegistry.js.map +1 -0
  282. package/dist/poll/registry.d.ts +17 -0
  283. package/dist/poll/registry.js +12 -0
  284. package/dist/poll/registry.js.map +1 -0
  285. package/dist/poll/resolvePollCloseRequest.js +105 -0
  286. package/dist/poll/resolvePollCloseRequest.js.map +1 -0
  287. package/dist/poll/resolvePollOptions.d.ts +29 -0
  288. package/dist/poll/resolvePollOptions.js +52 -0
  289. package/dist/poll/resolvePollOptions.js.map +1 -0
  290. package/dist/poll/resolvePollOptionsRequest.js +50 -0
  291. package/dist/poll/resolvePollOptionsRequest.js.map +1 -0
  292. package/dist/poll/resolvePollOutcome.d.ts +34 -0
  293. package/dist/poll/resolvePollOutcome.js +76 -0
  294. package/dist/poll/resolvePollOutcome.js.map +1 -0
  295. package/dist/poll/resultsField.js +21 -0
  296. package/dist/poll/resultsField.js.map +1 -0
  297. package/dist/prefill/valuesFromSearchParams.js +5 -9
  298. package/dist/prefill/valuesFromSearchParams.js.map +1 -1
  299. package/dist/presentations/types.d.ts +3 -2
  300. package/dist/react/Form.d.ts +66 -19
  301. package/dist/react/Form.js +342 -180
  302. package/dist/react/Form.js.map +1 -1
  303. package/dist/react/FormContext.d.ts +44 -1
  304. package/dist/react/FormContext.js.map +1 -1
  305. package/dist/react/FormControls.d.ts +55 -0
  306. package/dist/react/FormControls.js +56 -0
  307. package/dist/react/FormControls.js.map +1 -0
  308. package/dist/react/FormFields.d.ts +18 -0
  309. package/dist/react/FormFields.js +114 -0
  310. package/dist/react/FormFields.js.map +1 -0
  311. package/dist/react/FormLayout.d.ts +4 -2
  312. package/dist/react/FormLayout.js +3 -2
  313. package/dist/react/FormLayout.js.map +1 -1
  314. package/dist/react/FormResults.d.ts +6 -3
  315. package/dist/react/FormResults.js +37 -29
  316. package/dist/react/FormResults.js.map +1 -1
  317. package/dist/react/FormSteps.d.ts +17 -0
  318. package/dist/react/FormSteps.js +35 -0
  319. package/dist/react/FormSteps.js.map +1 -0
  320. package/dist/react/Poll.d.ts +17 -6
  321. package/dist/react/Poll.js +79 -21
  322. package/dist/react/Poll.js.map +1 -1
  323. package/dist/react/captcha/HcaptchaCaptcha.d.ts +28 -0
  324. package/dist/react/captcha/HcaptchaCaptcha.js +53 -0
  325. package/dist/react/captcha/HcaptchaCaptcha.js.map +1 -0
  326. package/dist/react/captcha/RecaptchaCaptcha.d.ts +41 -0
  327. package/dist/react/captcha/RecaptchaCaptcha.js +93 -0
  328. package/dist/react/captcha/RecaptchaCaptcha.js.map +1 -0
  329. package/dist/react/captcha/TurnstileCaptcha.d.ts +28 -0
  330. package/dist/react/captcha/TurnstileCaptcha.js +53 -0
  331. package/dist/react/captcha/TurnstileCaptcha.js.map +1 -0
  332. package/dist/react/captcha/types.d.ts +8 -0
  333. package/dist/react/captcha/useCaptchaScript.js +45 -0
  334. package/dist/react/captcha/useCaptchaScript.js.map +1 -0
  335. package/dist/react/captcha/vendors.js +8 -0
  336. package/dist/react/captcha/vendors.js.map +1 -0
  337. package/dist/react/contract.d.ts +2 -3
  338. package/dist/react/contract.js.map +1 -1
  339. package/dist/react/fetchResults.d.ts +1 -1
  340. package/dist/react/fetchResults.js +1 -1
  341. package/dist/react/fetchResults.js.map +1 -1
  342. package/dist/react/presentation/DialogSurface.js +1 -4
  343. package/dist/react/presentation/DialogSurface.js.map +1 -1
  344. package/dist/react/primitives/Checkbox.d.ts +4 -2
  345. package/dist/react/primitives/Checkbox.js +2 -1
  346. package/dist/react/primitives/Checkbox.js.map +1 -1
  347. package/dist/react/primitives/FieldShell.d.ts +2 -4
  348. package/dist/react/primitives/FieldShell.js +12 -19
  349. package/dist/react/primitives/FieldShell.js.map +1 -1
  350. package/dist/react/primitives/Input.d.ts +1 -1
  351. package/dist/react/primitives/Input.js.map +1 -1
  352. package/dist/react/renderers/calculation.js +1 -4
  353. package/dist/react/renderers/calculation.js.map +1 -1
  354. package/dist/react/renderers/checkbox.js +1 -4
  355. package/dist/react/renderers/checkbox.js.map +1 -1
  356. package/dist/react/renderers/consent.js +78 -35
  357. package/dist/react/renderers/consent.js.map +1 -1
  358. package/dist/react/renderers/date.js +33 -0
  359. package/dist/react/renderers/date.js.map +1 -0
  360. package/dist/react/renderers/email.js +1 -4
  361. package/dist/react/renderers/email.js.map +1 -1
  362. package/dist/react/renderers/file.js +29 -14
  363. package/dist/react/renderers/file.js.map +1 -1
  364. package/dist/react/renderers/index.js +9 -0
  365. package/dist/react/renderers/index.js.map +1 -1
  366. package/dist/react/renderers/message.js +41 -0
  367. package/dist/react/renderers/message.js.map +1 -0
  368. package/dist/react/renderers/number.js +1 -4
  369. package/dist/react/renderers/number.js.map +1 -1
  370. package/dist/react/renderers/region.js +43 -0
  371. package/dist/react/renderers/region.js.map +1 -0
  372. package/dist/react/renderers/repeater.js +131 -0
  373. package/dist/react/renderers/repeater.js.map +1 -0
  374. package/dist/react/renderers/select.js +1 -4
  375. package/dist/react/renderers/select.js.map +1 -1
  376. package/dist/react/renderers/text.js +1 -4
  377. package/dist/react/renderers/text.js.map +1 -1
  378. package/dist/react/renderers/textarea.js +1 -4
  379. package/dist/react/renderers/textarea.js.map +1 -1
  380. package/dist/react/state.d.ts +40 -3
  381. package/dist/react/state.js +64 -9
  382. package/dist/react/state.js.map +1 -1
  383. package/dist/react/uploadFile.d.ts +2 -2
  384. package/dist/react/uploadFile.js +1 -1
  385. package/dist/react/uploadFile.js.map +1 -1
  386. package/dist/react/useField.d.ts +0 -1
  387. package/dist/react/useField.js +6 -6
  388. package/dist/react/useField.js.map +1 -1
  389. package/dist/react/useFormState.d.ts +1 -1
  390. package/dist/react/useFormState.js +1 -1
  391. package/dist/react/useFormState.js.map +1 -1
  392. package/dist/react/validateField.js +3 -6
  393. package/dist/react/validateField.js.map +1 -1
  394. package/dist/recall/interpolate.d.ts +4 -3
  395. package/dist/recall/interpolate.js +5 -4
  396. package/dist/recall/interpolate.js.map +1 -1
  397. package/dist/recall/resolver.d.ts +1 -1
  398. package/dist/recall/resolver.js +14 -2
  399. package/dist/recall/resolver.js.map +1 -1
  400. package/dist/spam/captcha.d.ts +4 -3
  401. package/dist/spam/captcha.js +4 -3
  402. package/dist/spam/captcha.js.map +1 -1
  403. package/dist/spam/clientIp.js +9 -0
  404. package/dist/spam/clientIp.js.map +1 -0
  405. package/dist/spam/constants.js +7 -1
  406. package/dist/spam/constants.js.map +1 -1
  407. package/dist/spam/identify.js +3 -6
  408. package/dist/spam/identify.js.map +1 -1
  409. package/dist/spam/providers/hcaptcha.d.ts +17 -0
  410. package/dist/spam/providers/hcaptcha.js +18 -0
  411. package/dist/spam/providers/hcaptcha.js.map +1 -0
  412. package/dist/spam/providers/recaptcha.d.ts +23 -0
  413. package/dist/spam/providers/recaptcha.js +23 -0
  414. package/dist/spam/providers/recaptcha.js.map +1 -0
  415. package/dist/spam/providers/siteverify.js +34 -0
  416. package/dist/spam/providers/siteverify.js.map +1 -0
  417. package/dist/spam/providers/turnstile.d.ts +17 -0
  418. package/dist/spam/providers/turnstile.js +18 -0
  419. package/dist/spam/providers/turnstile.js.map +1 -0
  420. package/dist/spam/resolveSpam.js +2 -1
  421. package/dist/spam/resolveSpam.js.map +1 -1
  422. package/dist/spam/spamGuard.js +23 -10
  423. package/dist/spam/spamGuard.js.map +1 -1
  424. package/dist/spam/types.d.ts +19 -4
  425. package/dist/submissions/SubmissionAnswers.d.ts +2 -4
  426. package/dist/submissions/SubmissionAnswers.js +114 -34
  427. package/dist/submissions/SubmissionAnswers.js.map +1 -1
  428. package/dist/submissions/SubmissionAnswersClient.js +178 -0
  429. package/dist/submissions/SubmissionAnswersClient.js.map +1 -0
  430. package/dist/submissions/coerceBoolean.js +14 -0
  431. package/dist/submissions/coerceBoolean.js.map +1 -0
  432. package/dist/submissions/createSubmission.d.ts +36 -0
  433. package/dist/submissions/createSubmission.js +26 -0
  434. package/dist/submissions/createSubmission.js.map +1 -0
  435. package/dist/submissions/runSubmission.d.ts +10 -0
  436. package/dist/submissions/runSubmission.js +128 -27
  437. package/dist/submissions/runSubmission.js.map +1 -1
  438. package/dist/submissions/types.d.ts +12 -4
  439. package/dist/submissions/validateSubmission.js +62 -11
  440. package/dist/submissions/validateSubmission.js.map +1 -1
  441. package/dist/submissions/votedCookie.d.ts +13 -0
  442. package/dist/submissions/votedCookie.js +27 -0
  443. package/dist/submissions/votedCookie.js.map +1 -0
  444. package/dist/translations/clientRuntimeKeys.d.ts +17 -0
  445. package/dist/translations/clientRuntimeKeys.js +46 -0
  446. package/dist/translations/clientRuntimeKeys.js.map +1 -0
  447. package/dist/translations/de.d.ts +12 -0
  448. package/dist/translations/de.js +309 -0
  449. package/dist/translations/de.js.map +1 -0
  450. package/dist/translations/en.js +203 -27
  451. package/dist/translations/en.js.map +1 -1
  452. package/dist/translations/index.d.ts +14 -5
  453. package/dist/translations/index.js +14 -3
  454. package/dist/translations/index.js.map +1 -1
  455. package/dist/translations/keys.d.ts +199 -23
  456. package/dist/translations/keys.js +200 -24
  457. package/dist/translations/keys.js.map +1 -1
  458. package/dist/translations/makeTranslate.d.ts +7 -3
  459. package/dist/translations/makeTranslate.js +12 -3
  460. package/dist/translations/makeTranslate.js.map +1 -1
  461. package/dist/translations/server.js +8 -1
  462. package/dist/translations/server.js.map +1 -1
  463. package/dist/uploads/captureFileRef.d.ts +10 -3
  464. package/dist/uploads/captureFileRef.js +18 -9
  465. package/dist/uploads/captureFileRef.js.map +1 -1
  466. package/dist/uploads/formatBytes.d.ts +9 -0
  467. package/dist/uploads/formatBytes.js +25 -0
  468. package/dist/uploads/formatBytes.js.map +1 -0
  469. package/dist/uploads/resolveFileRef.js +3 -2
  470. package/dist/uploads/resolveFileRef.js.map +1 -1
  471. package/dist/uploads/types.d.ts +1 -2
  472. package/dist/validation/buildRuleBlocks.js +18 -17
  473. package/dist/validation/buildRuleBlocks.js.map +1 -1
  474. package/dist/validation/builtin/email.js +2 -1
  475. package/dist/validation/builtin/email.js.map +1 -1
  476. package/dist/validation/builtin/index.d.ts +14 -0
  477. package/dist/validation/builtin/index.js +12 -1
  478. package/dist/validation/builtin/index.js.map +1 -1
  479. package/dist/validation/builtin/matchesField.js +3 -7
  480. package/dist/validation/builtin/matchesField.js.map +1 -1
  481. package/dist/validation/builtin/max.js +1 -0
  482. package/dist/validation/builtin/max.js.map +1 -1
  483. package/dist/validation/builtin/maxDate.js +24 -0
  484. package/dist/validation/builtin/maxDate.js.map +1 -0
  485. package/dist/validation/builtin/maxLength.js +1 -0
  486. package/dist/validation/builtin/maxLength.js.map +1 -1
  487. package/dist/validation/builtin/min.js +1 -0
  488. package/dist/validation/builtin/min.js.map +1 -1
  489. package/dist/validation/builtin/minDate.js +24 -0
  490. package/dist/validation/builtin/minDate.js.map +1 -0
  491. package/dist/validation/builtin/minLength.js +1 -0
  492. package/dist/validation/builtin/minLength.js.map +1 -1
  493. package/dist/validation/builtin/notAlreadySubmitted.js +2 -0
  494. package/dist/validation/builtin/notAlreadySubmitted.js.map +1 -1
  495. package/dist/validation/builtin/oneOf.js +1 -0
  496. package/dist/validation/builtin/oneOf.js.map +1 -1
  497. package/dist/validation/builtin/pattern.js +11 -2
  498. package/dist/validation/builtin/pattern.js.map +1 -1
  499. package/dist/validation/builtin/url.js +1 -0
  500. package/dist/validation/builtin/url.js.map +1 -1
  501. package/dist/validation/builtin/validateDateBound.js +18 -0
  502. package/dist/validation/builtin/validateDateBound.js.map +1 -0
  503. package/dist/validation/builtin/validateRegexParams.js +44 -0
  504. package/dist/validation/builtin/validateRegexParams.js.map +1 -0
  505. package/dist/validation/emailPattern.js +10 -0
  506. package/dist/validation/emailPattern.js.map +1 -0
  507. package/dist/validation/fieldTargetParam.d.ts +22 -0
  508. package/dist/validation/fieldTargetParam.js +38 -0
  509. package/dist/validation/fieldTargetParam.js.map +1 -0
  510. package/dist/validation/registry.d.ts +2 -1
  511. package/dist/validation/registry.js +2 -9
  512. package/dist/validation/registry.js.map +1 -1
  513. package/dist/validation/runValidation.js +9 -30
  514. package/dist/validation/runValidation.js.map +1 -1
  515. package/dist/validation/types.d.ts +5 -11
  516. package/dist/validation/validateUrl.js +22 -0
  517. package/dist/validation/validateUrl.js.map +1 -0
  518. package/package.json +7 -5
  519. package/styles/form-builder.css +10 -190
  520. package/dist/collections/uploads.d.ts +0 -29
  521. package/dist/collections/uploads.js +0 -46
  522. package/dist/collections/uploads.js.map +0 -1
  523. package/dist/consent/buildConsentSourceConfig.js +0 -49
  524. package/dist/consent/buildConsentSourceConfig.js.map +0 -1
  525. package/dist/consent/builtin/index.d.ts +0 -7
  526. package/dist/consent/builtin/index.js +0 -11
  527. package/dist/consent/builtin/index.js.map +0 -1
  528. package/dist/consent/builtin/pageReference.js +0 -75
  529. package/dist/consent/builtin/pageReference.js.map +0 -1
  530. package/dist/consent/builtin/static.js +0 -44
  531. package/dist/consent/builtin/static.js.map +0 -1
  532. package/dist/consent/defineConsentSource.d.ts +0 -35
  533. package/dist/consent/defineConsentSource.js +0 -6
  534. package/dist/consent/defineConsentSource.js.map +0 -1
  535. package/dist/consent/registry.d.ts +0 -16
  536. package/dist/consent/registry.js +0 -16
  537. package/dist/consent/registry.js.map +0 -1
  538. package/dist/consent/resolveConsentLinks.d.ts +0 -19
  539. package/dist/consent/resolveConsentLinks.js +0 -26
  540. package/dist/consent/resolveConsentLinks.js.map +0 -1
  541. package/dist/presentations/registry.d.ts +0 -15
  542. package/dist/presentations/registry.js +0 -15
  543. package/dist/presentations/registry.js.map +0 -1
  544. package/dist/react/toFormDocument.d.ts +0 -24
  545. package/dist/react/toFormDocument.js +0 -22
  546. package/dist/react/toFormDocument.js.map +0 -1
@@ -1,51 +1,94 @@
1
1
  "use client";
2
+ import { sanitizeUrl } from "../../actions/body/converters.js";
3
+ import { serializeBody } from "../../actions/body/serializeBody.js";
4
+ import { textOfBody } from "../../actions/body/textOfBody.js";
2
5
  import { defineFieldRenderer } from "../contract.js";
3
6
  import { FieldShell } from "../primitives/FieldShell.js";
4
7
  import { Checkbox } from "../primitives/Checkbox.js";
5
- import { useId } from "react";
6
8
  import { jsx, jsxs } from "react/jsx-runtime";
9
+ import { useMemo } from "react";
7
10
  //#region src/react/renderers/consent.tsx
8
- const consentRenderer = defineFieldRenderer(({ field, name, value, onChange, onBlur, errors, warnings, required, disabled }) => {
9
- const id = useId();
11
+ const text = (raw) => typeof raw === "string" && raw.trim() !== "" ? raw : void 0;
12
+ /**
13
+ * HTML for a rich text statement. A plain string never goes through this path: `serializeBody`
14
+ * interpolates a string body unescaped (its pre-richText behavior), so rendering one as HTML would
15
+ * let literal markup execute; the renderer shows a plain string as text instead.
16
+ */
17
+ const richStatementHtml = (statement) => {
18
+ if (typeof statement === "string" || statement == null) return;
19
+ const html = serializeBody(statement, {
20
+ values: [],
21
+ descriptors: []
22
+ });
23
+ return html === "" ? void 0 : html;
24
+ };
25
+ /**
26
+ * The resolved policy link, or nothing unless the source carries both a url and a name to show
27
+ * for it: an anchor labelled by a raw URL or a machine key is worse than no anchor. The href is
28
+ * sanitized like every other url the package renders, since a source is admin-authored and can
29
+ * point anywhere (`sanitizeUrl` keeps http(s)/mailto/tel and relative urls, and neutralizes the
30
+ * rest to `#`).
31
+ */
32
+ const linkOf = (raw) => {
33
+ const link = raw;
34
+ const label = text(link?.label);
35
+ return label && typeof link?.url === "string" && link.url !== "" ? {
36
+ label,
37
+ url: sanitizeUrl(link.url)
38
+ } : void 0;
39
+ };
40
+ /**
41
+ * The `statement` and `link` this reads are server-resolved from the field's consent source and
42
+ * injected by `toFormDocument(doc, { consentStatements })`; the form document itself carries only
43
+ * the source key, so a form rendered without that step shows no statement rather than a stale one.
44
+ */
45
+ const consentRenderer = defineFieldRenderer(({ field, id, name, value, onChange, onBlur, errors, required, disabled }) => {
10
46
  const describedById = `${id}-desc`;
11
- const text = (raw) => typeof raw === "string" && raw.trim() !== "" ? raw : void 0;
12
- const statement = text(field.statement) ?? text(field.label);
13
- const links = Array.isArray(field.consentLinks) ? field.consentLinks : (() => {
14
- const sc = field.sourceConfig;
15
- if (sc && typeof sc.url === "string" && sc.url) return [{
16
- label: typeof sc.label === "string" ? sc.label : "Policy",
17
- url: sc.url
18
- }];
19
- return [];
20
- })();
47
+ const plainStatement = text(textOfBody(field.statement));
48
+ const html = useMemo(() => richStatementHtml(field.statement), [field.statement]);
49
+ const link = linkOf(field.link);
21
50
  return /* @__PURE__ */ jsxs(FieldShell, {
22
51
  id,
23
- label: statement,
24
52
  description: typeof field.description === "string" ? field.description : void 0,
25
53
  required,
26
54
  errors,
27
- warnings,
28
55
  describedById,
29
- children: [/* @__PURE__ */ jsx(Checkbox, {
30
- id,
31
- name,
32
- checked: value ?? false,
33
- onChange,
34
- onBlur,
35
- required,
36
- disabled,
37
- invalid: errors.length > 0,
38
- describedById
39
- }), links.length > 0 ? /* @__PURE__ */ jsx("span", {
40
- className: "fb-consent__links",
41
- children: links.map((link) => /* @__PURE__ */ jsx("a", {
42
- href: link.url,
43
- target: "_blank",
44
- rel: "noopener noreferrer",
45
- className: "fb-consent__link",
46
- children: link.label
47
- }, link.url))
48
- }) : null]
56
+ children: [
57
+ html ? /* @__PURE__ */ jsx("div", {
58
+ className: "fb-consent__statement",
59
+ dangerouslySetInnerHTML: { __html: html }
60
+ }) : plainStatement ? /* @__PURE__ */ jsx("span", {
61
+ className: "fb-consent__statement",
62
+ children: plainStatement
63
+ }) : null,
64
+ required && (html || plainStatement) ? /* @__PURE__ */ jsx("span", {
65
+ className: "fb-field__required",
66
+ "aria-hidden": "true",
67
+ children: " *"
68
+ }) : null,
69
+ /* @__PURE__ */ jsx(Checkbox, {
70
+ id,
71
+ name,
72
+ checked: value ?? false,
73
+ onChange,
74
+ onBlur,
75
+ required,
76
+ disabled,
77
+ invalid: errors.length > 0,
78
+ describedById,
79
+ ariaLabel: plainStatement ?? name
80
+ }),
81
+ link ? /* @__PURE__ */ jsx("span", {
82
+ className: "fb-consent__links",
83
+ children: /* @__PURE__ */ jsx("a", {
84
+ href: link.url,
85
+ target: "_blank",
86
+ rel: "noopener noreferrer",
87
+ className: "fb-consent__link",
88
+ children: link.label
89
+ })
90
+ }) : null
91
+ ]
49
92
  });
50
93
  });
51
94
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"consent.js","names":[],"sources":["../../../src/react/renderers/consent.tsx"],"sourcesContent":["'use client'\n\nimport { useId } from 'react'\nimport type { ConsentLink } from '../../consent/defineConsentSource'\nimport { defineFieldRenderer } from '../contract'\nimport { Checkbox } from '../primitives/Checkbox'\nimport { FieldShell } from '../primitives/FieldShell'\n\nexport const consentRenderer = defineFieldRenderer<boolean>(\n\t({ field, name, value, onChange, onBlur, errors, warnings, required, disabled }) => {\n\t\tconst id = useId()\n\t\tconst describedById = `${id}-desc`\n\t\t// The visible agreement text labels the checkbox. Prefer the explicit `statement`; fall back to the\n\t\t// field `label` so a consent field authored with only a label (or a blank statement) is never an\n\t\t// unlabelled control (a11y). A blank or whitespace-only value counts as absent.\n\t\tconst text = (raw: unknown): string | undefined =>\n\t\t\ttypeof raw === 'string' && raw.trim() !== '' ? raw : undefined\n\t\tconst statement = text(field.statement) ?? text(field.label)\n\n\t\tconst links: ConsentLink[] = Array.isArray(field.consentLinks)\n\t\t\t? (field.consentLinks as ConsentLink[])\n\t\t\t: (() => {\n\t\t\t\t\tconst sc = field.sourceConfig as Record<string, unknown> | undefined\n\t\t\t\t\tif (sc && typeof sc.url === 'string' && sc.url) {\n\t\t\t\t\t\treturn [{ label: typeof sc.label === 'string' ? sc.label : 'Policy', url: sc.url }]\n\t\t\t\t\t}\n\t\t\t\t\treturn []\n\t\t\t\t})()\n\n\t\treturn (\n\t\t\t<FieldShell\n\t\t\t\tid={id}\n\t\t\t\tlabel={statement}\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\twarnings={warnings}\n\t\t\t\tdescribedById={describedById}\n\t\t\t>\n\t\t\t\t<Checkbox\n\t\t\t\t\tid={id}\n\t\t\t\t\tname={name}\n\t\t\t\t\tchecked={value ?? false}\n\t\t\t\t\tonChange={onChange}\n\t\t\t\t\tonBlur={onBlur}\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\t{links.length > 0 ? (\n\t\t\t\t\t<span className=\"fb-consent__links\">\n\t\t\t\t\t\t{links.map((link) => (\n\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\tkey={link.url}\n\t\t\t\t\t\t\t\thref={link.url}\n\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\t\t\t\tclassName=\"fb-consent__link\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{link.label}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</span>\n\t\t\t\t) : null}\n\t\t\t</FieldShell>\n\t\t)\n\t}\n)\n"],"mappings":";;;;;;;AAQA,MAAa,kBAAkB,qBAC7B,EAAE,OAAO,MAAM,OAAO,UAAU,QAAQ,QAAQ,UAAU,UAAU,eAAe;CACnF,MAAM,KAAK,MAAM;CACjB,MAAM,gBAAgB,GAAG,GAAG;CAI5B,MAAM,QAAQ,QACb,OAAO,QAAQ,YAAY,IAAI,KAAK,MAAM,KAAK,MAAM,KAAA;CACtD,MAAM,YAAY,KAAK,MAAM,SAAS,KAAK,KAAK,MAAM,KAAK;CAE3D,MAAM,QAAuB,MAAM,QAAQ,MAAM,YAAY,IACzD,MAAM,sBACA;EACP,MAAM,KAAK,MAAM;EACjB,IAAI,MAAM,OAAO,GAAG,QAAQ,YAAY,GAAG,KAC1C,OAAO,CAAC;GAAE,OAAO,OAAO,GAAG,UAAU,WAAW,GAAG,QAAQ;GAAU,KAAK,GAAG;EAAI,CAAC;EAEnF,OAAO,CAAC;CACT,GAAG;CAEL,OACC,qBAAC,YAAD;EACK;EACJ,OAAO;EACP,aAAa,OAAO,MAAM,gBAAgB,WAAW,MAAM,cAAc,KAAA;EAC/D;EACF;EACE;EACK;YAPhB,CASC,oBAAC,UAAD;GACK;GACE;GACN,SAAS,SAAS;GACR;GACF;GACE;GACA;GACV,SAAS,OAAO,SAAS;GACV;EACf,CAAA,GACA,MAAM,SAAS,IACf,oBAAC,QAAD;GAAM,WAAU;aACd,MAAM,KAAK,SACX,oBAAC,KAAD;IAEC,MAAM,KAAK;IACX,QAAO;IACP,KAAI;IACJ,WAAU;cAET,KAAK;GACJ,GAPG,KAAK,GAOR,CACH;EACI,CAAA,IACH,IACO;;AAEd,CACD"}
1
+ {"version":3,"file":"consent.js","names":[],"sources":["../../../src/react/renderers/consent.tsx"],"sourcesContent":["'use client'\n\nimport { useMemo } from 'react'\nimport { sanitizeUrl } from '../../actions/body/converters'\nimport { serializeBody } from '../../actions/body/serializeBody'\nimport { textOfBody } from '../../actions/body/textOfBody'\nimport { defineFieldRenderer } from '../contract'\nimport { Checkbox } from '../primitives/Checkbox'\nimport { FieldShell } from '../primitives/FieldShell'\n\ntype ConsentLink = { label: string; url: string }\n\nconst text = (raw: unknown): string | undefined =>\n\ttypeof raw === 'string' && raw.trim() !== '' ? raw : undefined\n\n/**\n * HTML for a rich text statement. A plain string never goes through this path: `serializeBody`\n * interpolates a string body unescaped (its pre-richText behavior), so rendering one as HTML would\n * let literal markup execute; the renderer shows a plain string as text instead.\n */\nconst richStatementHtml = (statement: unknown): string | undefined => {\n\tif (typeof statement === 'string' || statement == null) {\n\t\treturn undefined\n\t}\n\tconst html = serializeBody(statement, { values: [], descriptors: [] })\n\treturn html === '' ? undefined : html\n}\n\n/**\n * The resolved policy link, or nothing unless the source carries both a url and a name to show\n * for it: an anchor labelled by a raw URL or a machine key is worse than no anchor. The href is\n * sanitized like every other url the package renders, since a source is admin-authored and can\n * point anywhere (`sanitizeUrl` keeps http(s)/mailto/tel and relative urls, and neutralizes the\n * rest to `#`).\n */\nconst linkOf = (raw: unknown): ConsentLink | undefined => {\n\tconst link = raw as Partial<ConsentLink> | undefined\n\tconst label = text(link?.label)\n\treturn label && typeof link?.url === 'string' && link.url !== ''\n\t\t? { label, url: sanitizeUrl(link.url) }\n\t\t: undefined\n}\n\n/**\n * The `statement` and `link` this reads are server-resolved from the field's consent source and\n * injected by `toFormDocument(doc, { consentStatements })`; the form document itself carries only\n * the source key, so a form rendered without that step shows no statement rather than a stale one.\n */\nexport const consentRenderer = defineFieldRenderer<boolean>(\n\t({ field, id, name, value, onChange, onBlur, errors, required, disabled }) => {\n\t\tconst describedById = `${id}-desc`\n\n\t\t// The checkbox's accessible name is always plain text, regardless of the statement's shape,\n\t\t// so it stays a single unambiguous string even though the visible statement can carry\n\t\t// formatting and inline links. With no statement resolved the field is misconfigured; the\n\t\t// machine name still beats leaving the control unnamed.\n\t\tconst plainStatement = text(textOfBody(field.statement))\n\t\tconst html = useMemo(() => richStatementHtml(field.statement), [field.statement])\n\t\tconst link = linkOf(field.link)\n\n\t\treturn (\n\t\t\t<FieldShell\n\t\t\t\tid={id}\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{html ? (\n\t\t\t\t\t// The statement is a plain sibling, never a <label>: a native <label> forwards clicks to\n\t\t\t\t\t// its control even for descendant links (they aren't \"labelable\" elements per the HTML\n\t\t\t\t\t// spec), so an inline link here would also silently toggle the checkbox. The checkbox's\n\t\t\t\t\t// name comes from aria-label instead. A <div>, because serializeBody emits block\n\t\t\t\t\t// elements (<p>, headings, lists) that are invalid inside inline wrappers.\n\t\t\t\t\t// Safe to inject: serializeBody HTML-escapes all text and sanitizes link URLs.\n\t\t\t\t\t// biome-ignore lint/security/noDangerouslySetInnerHtml: HTML is produced by our escaping serializer, never raw user input\n\t\t\t\t\t<div className=\"fb-consent__statement\" dangerouslySetInnerHTML={{ __html: html }} />\n\t\t\t\t) : plainStatement ? (\n\t\t\t\t\t<span className=\"fb-consent__statement\">{plainStatement}</span>\n\t\t\t\t) : null}\n\t\t\t\t{required && (html || plainStatement) ? (\n\t\t\t\t\t<span className=\"fb-field__required\" aria-hidden=\"true\">\n\t\t\t\t\t\t{' *'}\n\t\t\t\t\t</span>\n\t\t\t\t) : null}\n\t\t\t\t<Checkbox\n\t\t\t\t\tid={id}\n\t\t\t\t\tname={name}\n\t\t\t\t\tchecked={value ?? false}\n\t\t\t\t\tonChange={onChange}\n\t\t\t\t\tonBlur={onBlur}\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\tariaLabel={plainStatement ?? name}\n\t\t\t\t/>\n\t\t\t\t{link ? (\n\t\t\t\t\t<span className=\"fb-consent__links\">\n\t\t\t\t\t\t<a\n\t\t\t\t\t\t\thref={link.url}\n\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\t\t\tclassName=\"fb-consent__link\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{link.label}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</span>\n\t\t\t\t) : null}\n\t\t\t</FieldShell>\n\t\t)\n\t}\n)\n"],"mappings":";;;;;;;;;;AAYA,MAAM,QAAQ,QACb,OAAO,QAAQ,YAAY,IAAI,KAAK,MAAM,KAAK,MAAM,KAAA;;;;;;AAOtD,MAAM,qBAAqB,cAA2C;CACrE,IAAI,OAAO,cAAc,YAAY,aAAa,MACjD;CAED,MAAM,OAAO,cAAc,WAAW;EAAE,QAAQ,CAAC;EAAG,aAAa,CAAC;CAAE,CAAC;CACrE,OAAO,SAAS,KAAK,KAAA,IAAY;AAClC;;;;;;;;AASA,MAAM,UAAU,QAA0C;CACzD,MAAM,OAAO;CACb,MAAM,QAAQ,KAAK,MAAM,KAAK;CAC9B,OAAO,SAAS,OAAO,MAAM,QAAQ,YAAY,KAAK,QAAQ,KAC3D;EAAE;EAAO,KAAK,YAAY,KAAK,GAAG;CAAE,IACpC,KAAA;AACJ;;;;;;AAOA,MAAa,kBAAkB,qBAC7B,EAAE,OAAO,IAAI,MAAM,OAAO,UAAU,QAAQ,QAAQ,UAAU,eAAe;CAC7E,MAAM,gBAAgB,GAAG,GAAG;CAM5B,MAAM,iBAAiB,KAAK,WAAW,MAAM,SAAS,CAAC;CACvD,MAAM,OAAO,cAAc,kBAAkB,MAAM,SAAS,GAAG,CAAC,MAAM,SAAS,CAAC;CAChF,MAAM,OAAO,OAAO,MAAM,IAAI;CAE9B,OACC,qBAAC,YAAD;EACK;EACJ,aAAa,OAAO,MAAM,gBAAgB,WAAW,MAAM,cAAc,KAAA;EAC/D;EACF;EACO;YALhB;GAOE,OAQA,oBAAC,OAAD;IAAK,WAAU;IAAwB,yBAAyB,EAAE,QAAQ,KAAK;GAAI,CAAA,IAChF,iBACH,oBAAC,QAAD;IAAM,WAAU;cAAyB;GAAqB,CAAA,IAC3D;GACH,aAAa,QAAQ,kBACrB,oBAAC,QAAD;IAAM,WAAU;IAAqB,eAAY;cAC/C;GACI,CAAA,IACH;GACJ,oBAAC,UAAD;IACK;IACE;IACN,SAAS,SAAS;IACR;IACF;IACE;IACA;IACV,SAAS,OAAO,SAAS;IACV;IACf,WAAW,kBAAkB;GAC7B,CAAA;GACA,OACA,oBAAC,QAAD;IAAM,WAAU;cACf,oBAAC,KAAD;KACC,MAAM,KAAK;KACX,QAAO;KACP,KAAI;KACJ,WAAU;eAET,KAAK;IACJ,CAAA;GACE,CAAA,IACH;EACO;;AAEd,CACD"}
@@ -0,0 +1,33 @@
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/date.tsx
7
+ const dateRenderer = 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: "date",
20
+ value: value ?? "",
21
+ onChange,
22
+ onBlur,
23
+ required,
24
+ disabled,
25
+ invalid: errors.length > 0,
26
+ describedById
27
+ })
28
+ });
29
+ });
30
+ //#endregion
31
+ export { dateRenderer };
32
+
33
+ //# sourceMappingURL=date.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date.js","names":[],"sources":["../../../src/react/renderers/date.tsx"],"sourcesContent":["'use client'\n\nimport { defineFieldRenderer } from '../contract'\nimport { FieldShell } from '../primitives/FieldShell'\nimport { Input } from '../primitives/Input'\n\nexport const dateRenderer = 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=\"date\"\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\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;GACE;GACA;GACV,SAAS,OAAO,SAAS;GACV;EACf,CAAA;CACU,CAAA;AAEd,CACD"}
@@ -2,11 +2,9 @@
2
2
  import { defineFieldRenderer } from "../contract.js";
3
3
  import { FieldShell } from "../primitives/FieldShell.js";
4
4
  import { Input } from "../primitives/Input.js";
5
- import { useId } from "react";
6
5
  import { jsx } from "react/jsx-runtime";
7
6
  //#region src/react/renderers/email.tsx
8
- const emailRenderer = defineFieldRenderer(({ field, name, value, onChange, onBlur, errors, warnings, required, disabled }) => {
9
- const id = useId();
7
+ const emailRenderer = defineFieldRenderer(({ field, id, name, value, onChange, onBlur, errors, required, disabled }) => {
10
8
  const describedById = `${id}-desc`;
11
9
  return /* @__PURE__ */ jsx(FieldShell, {
12
10
  id,
@@ -14,7 +12,6 @@ const emailRenderer = defineFieldRenderer(({ field, name, value, onChange, onBlu
14
12
  description: typeof field.description === "string" ? field.description : void 0,
15
13
  required,
16
14
  errors,
17
- warnings,
18
15
  describedById,
19
16
  children: /* @__PURE__ */ jsx(Input, {
20
17
  id,
@@ -1 +1 @@
1
- {"version":3,"file":"email.js","names":[],"sources":["../../../src/react/renderers/email.tsx"],"sourcesContent":["'use client'\n\nimport { useId } from 'react'\nimport { defineFieldRenderer } from '../contract'\nimport { FieldShell } from '../primitives/FieldShell'\nimport { Input } from '../primitives/Input'\n\nexport const emailRenderer = defineFieldRenderer<string>(\n\t({ field, name, value, onChange, onBlur, errors, warnings, required, disabled }) => {\n\t\tconst id = useId()\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\twarnings={warnings}\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=\"email\"\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":";;;;;;;AAOA,MAAa,gBAAgB,qBAC3B,EAAE,OAAO,MAAM,OAAO,UAAU,QAAQ,QAAQ,UAAU,UAAU,eAAe;CACnF,MAAM,KAAK,MAAM;CACjB,MAAM,gBAAgB,GAAG,GAAG;CAC5B,OACC,oBAAC,YAAD;EACK;EACJ,OAAO,MAAM;EACb,aAAa,OAAO,MAAM,gBAAgB,WAAW,MAAM,cAAc,KAAA;EAC/D;EACF;EACE;EACK;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"}
1
+ {"version":3,"file":"email.js","names":[],"sources":["../../../src/react/renderers/email.tsx"],"sourcesContent":["'use client'\n\nimport { defineFieldRenderer } from '../contract'\nimport { FieldShell } from '../primitives/FieldShell'\nimport { Input } from '../primitives/Input'\n\nexport const emailRenderer = 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=\"email\"\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,gBAAgB,qBAC3B,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"}
@@ -1,14 +1,16 @@
1
1
  "use client";
2
+ import { keys } from "../../translations/keys.js";
3
+ import { resolveMessage } from "../../validation/message.js";
4
+ import { formatBytes } from "../../uploads/formatBytes.js";
2
5
  import { defineFieldRenderer } from "../contract.js";
3
6
  import { FieldShell } from "../primitives/FieldShell.js";
4
7
  import { uploadFile } from "../uploadFile.js";
5
- import { useId, useState } from "react";
6
8
  import { jsx, jsxs } from "react/jsx-runtime";
9
+ import { useState } from "react";
7
10
  //#region src/react/renderers/file.tsx
8
- const acceptOf = (mimeTypes) => {
9
- if (!Array.isArray(mimeTypes)) return;
10
- const types = mimeTypes.filter((entry) => typeof entry === "string");
11
- return types.length > 0 ? types.join(",") : void 0;
11
+ const typesOf = (mimeTypes) => {
12
+ if (!Array.isArray(mimeTypes)) return [];
13
+ return mimeTypes.filter((entry) => typeof entry === "string");
12
14
  };
13
15
  /**
14
16
  * Headless file renderer: a native file input that uploads the chosen file to the upload collection and
@@ -16,19 +18,29 @@ const acceptOf = (mimeTypes) => {
16
18
  * stored doc at submit, so the client value is only the id. Shows the uploaded filename with a clear
17
19
  * control and surfaces upload errors. Single file (v1); the upload posts to the default `/api` route.
18
20
  */
19
- const fileRenderer = defineFieldRenderer(({ field, name, value, onChange, onBlur, errors, warnings, required, disabled }) => {
20
- const id = useId();
21
+ const fileRenderer = defineFieldRenderer(({ field, id, name, value, onChange, onBlur, errors, required, disabled, t }) => {
21
22
  const describedById = `${id}-desc`;
22
23
  const [uploading, setUploading] = useState(false);
23
24
  const [filename, setFilename] = useState(void 0);
24
25
  const [localError, setLocalError] = useState(void 0);
25
- const collection = typeof field.relationTo === "string" ? field.relationTo : "form-uploads";
26
- const accept = acceptOf(field.mimeTypes);
26
+ const collection = typeof field.uploadsCollection === "string" ? field.uploadsCollection : void 0;
27
+ const types = typesOf(field.mimeTypes);
28
+ const accept = types.length > 0 ? types.join(",") : void 0;
29
+ const maxSize = typeof field.maxSize === "number" && field.maxSize >= 0 ? field.maxSize : void 0;
30
+ const hints = [types.length > 0 ? resolveMessage(t(keys.fileHintAccepted), { types: types.join(", ") }) : void 0, maxSize !== void 0 ? resolveMessage(t(keys.fileHintMaxSize), { max: formatBytes(maxSize) }) : void 0].filter((hint) => typeof hint === "string");
27
31
  const allErrors = localError ? [...errors, localError] : errors;
28
- const displayName = filename ?? (value !== void 0 && value !== null && value !== "" ? "Uploaded file" : void 0);
32
+ const displayName = filename ?? (value !== void 0 && value !== null && value !== "" ? t(keys.fileUploaded) : void 0);
29
33
  const handleChange = async (event) => {
30
34
  const selected = event.target.files?.[0];
31
35
  if (!selected) return;
36
+ if (maxSize !== void 0 && selected.size > maxSize) {
37
+ setLocalError(resolveMessage(t(keys.fileTooLarge), { max: formatBytes(maxSize) }));
38
+ return;
39
+ }
40
+ if (!collection) {
41
+ setLocalError(t(keys.fileUploadMisconfigured));
42
+ return;
43
+ }
32
44
  setUploading(true);
33
45
  setLocalError(void 0);
34
46
  const result = await uploadFile({
@@ -39,7 +51,7 @@ const fileRenderer = defineFieldRenderer(({ field, name, value, onChange, onBlur
39
51
  if (result.ok) {
40
52
  setFilename(selected.name);
41
53
  onChange(result.id);
42
- } else setLocalError(result.message ?? "Upload failed");
54
+ } else setLocalError(result.message ?? t(keys.fileUploadFailed));
43
55
  };
44
56
  const clear = () => {
45
57
  setFilename(void 0);
@@ -52,7 +64,6 @@ const fileRenderer = defineFieldRenderer(({ field, name, value, onChange, onBlur
52
64
  description: typeof field.description === "string" ? field.description : void 0,
53
65
  required,
54
66
  errors: allErrors,
55
- warnings,
56
67
  describedById,
57
68
  children: [
58
69
  /* @__PURE__ */ jsx("input", {
@@ -68,10 +79,14 @@ const fileRenderer = defineFieldRenderer(({ field, name, value, onChange, onBlur
68
79
  "aria-invalid": allErrors.length > 0,
69
80
  "aria-describedby": describedById
70
81
  }),
82
+ hints.length > 0 ? /* @__PURE__ */ jsx("p", {
83
+ className: "fb-field__file-hint",
84
+ children: hints.join(" · ")
85
+ }) : null,
71
86
  uploading ? /* @__PURE__ */ jsx("p", {
72
87
  className: "fb-field__file-status",
73
88
  "aria-live": "polite",
74
- children: "Uploading"
89
+ children: t(keys.fileUploading)
75
90
  }) : null,
76
91
  displayName ? /* @__PURE__ */ jsxs("p", {
77
92
  className: "fb-field__file-name",
@@ -80,7 +95,7 @@ const fileRenderer = defineFieldRenderer(({ field, name, value, onChange, onBlur
80
95
  className: "fb-field__file-clear",
81
96
  onClick: clear,
82
97
  disabled,
83
- children: "Remove"
98
+ children: t(keys.fileRemove)
84
99
  })]
85
100
  }) : null
86
101
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"file.js","names":[],"sources":["../../../src/react/renderers/file.tsx"],"sourcesContent":["'use client'\n\nimport { type ChangeEvent, useId, useState } from 'react'\nimport { defineFieldRenderer } from '../contract'\nimport { FieldShell } from '../primitives/FieldShell'\nimport { uploadFile } from '../uploadFile'\n\nconst acceptOf = (mimeTypes: unknown): string | undefined => {\n\tif (!Array.isArray(mimeTypes)) {\n\t\treturn undefined\n\t}\n\tconst types = mimeTypes.filter((entry): entry is string => typeof entry === 'string')\n\treturn types.length > 0 ? types.join(',') : undefined\n}\n\n/**\n * Headless file renderer: a native file input that uploads the chosen file to the upload collection and\n * stores the returned id as the field value. The server re-derives filename/mimeType/filesize from the\n * stored doc at submit, so the client value is only the id. Shows the uploaded filename with a clear\n * control and surfaces upload errors. Single file (v1); the upload posts to the default `/api` route.\n */\nexport const fileRenderer = defineFieldRenderer<string | number>(\n\t({ field, name, value, onChange, onBlur, errors, warnings, required, disabled }) => {\n\t\tconst id = useId()\n\t\tconst describedById = `${id}-desc`\n\t\tconst [uploading, setUploading] = useState(false)\n\t\tconst [filename, setFilename] = useState<string | undefined>(undefined)\n\t\tconst [localError, setLocalError] = useState<string | undefined>(undefined)\n\n\t\tconst collection = typeof field.relationTo === 'string' ? field.relationTo : 'form-uploads'\n\t\tconst accept = acceptOf(field.mimeTypes)\n\t\tconst allErrors = localError ? [...errors, localError] : errors\n\t\t// Show the just-uploaded filename, or a generic indicator when the field already holds an id (recall/prefill): the filename is not part of the client value.\n\t\tconst hasValue = value !== undefined && value !== null && value !== ''\n\t\tconst displayName = filename ?? (hasValue ? 'Uploaded file' : undefined)\n\n\t\tconst handleChange = async (event: ChangeEvent<HTMLInputElement>) => {\n\t\t\tconst selected = event.target.files?.[0]\n\t\t\tif (!selected) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tsetUploading(true)\n\t\t\tsetLocalError(undefined)\n\t\t\tconst result = await uploadFile({ file: selected, collection })\n\t\t\tsetUploading(false)\n\t\t\tif (result.ok) {\n\t\t\t\tsetFilename(selected.name)\n\t\t\t\tonChange(result.id)\n\t\t\t} else {\n\t\t\t\tsetLocalError(result.message ?? 'Upload failed')\n\t\t\t}\n\t\t}\n\n\t\tconst clear = () => {\n\t\t\tsetFilename(undefined)\n\t\t\tsetLocalError(undefined)\n\t\t\tonChange('')\n\t\t}\n\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={allErrors}\n\t\t\t\twarnings={warnings}\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=\"file\"\n\t\t\t\t\taccept={accept}\n\t\t\t\t\tdisabled={disabled || uploading}\n\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\tvoid handleChange(event)\n\t\t\t\t\t}}\n\t\t\t\t\tonBlur={onBlur}\n\t\t\t\t\taria-invalid={allErrors.length > 0}\n\t\t\t\t\taria-describedby={describedById}\n\t\t\t\t/>\n\t\t\t\t{uploading ? (\n\t\t\t\t\t<p className=\"fb-field__file-status\" aria-live=\"polite\">\n\t\t\t\t\t\tUploading\n\t\t\t\t\t</p>\n\t\t\t\t) : null}\n\t\t\t\t{displayName ? (\n\t\t\t\t\t<p className=\"fb-field__file-name\">\n\t\t\t\t\t\t<span>{displayName}</span>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"fb-field__file-clear\"\n\t\t\t\t\t\t\tonClick={clear}\n\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tRemove\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</p>\n\t\t\t\t) : null}\n\t\t\t</FieldShell>\n\t\t)\n\t}\n)\n"],"mappings":";;;;;;;AAOA,MAAM,YAAY,cAA2C;CAC5D,IAAI,CAAC,MAAM,QAAQ,SAAS,GAC3B;CAED,MAAM,QAAQ,UAAU,QAAQ,UAA2B,OAAO,UAAU,QAAQ;CACpF,OAAO,MAAM,SAAS,IAAI,MAAM,KAAK,GAAG,IAAI,KAAA;AAC7C;;;;;;;AAQA,MAAa,eAAe,qBAC1B,EAAE,OAAO,MAAM,OAAO,UAAU,QAAQ,QAAQ,UAAU,UAAU,eAAe;CACnF,MAAM,KAAK,MAAM;CACjB,MAAM,gBAAgB,GAAG,GAAG;CAC5B,MAAM,CAAC,WAAW,gBAAgB,SAAS,KAAK;CAChD,MAAM,CAAC,UAAU,eAAe,SAA6B,KAAA,CAAS;CACtE,MAAM,CAAC,YAAY,iBAAiB,SAA6B,KAAA,CAAS;CAE1E,MAAM,aAAa,OAAO,MAAM,eAAe,WAAW,MAAM,aAAa;CAC7E,MAAM,SAAS,SAAS,MAAM,SAAS;CACvC,MAAM,YAAY,aAAa,CAAC,GAAG,QAAQ,UAAU,IAAI;CAGzD,MAAM,cAAc,aADH,UAAU,KAAA,KAAa,UAAU,QAAQ,UAAU,KACxB,kBAAkB,KAAA;CAE9D,MAAM,eAAe,OAAO,UAAyC;EACpE,MAAM,WAAW,MAAM,OAAO,QAAQ;EACtC,IAAI,CAAC,UACJ;EAED,aAAa,IAAI;EACjB,cAAc,KAAA,CAAS;EACvB,MAAM,SAAS,MAAM,WAAW;GAAE,MAAM;GAAU;EAAW,CAAC;EAC9D,aAAa,KAAK;EAClB,IAAI,OAAO,IAAI;GACd,YAAY,SAAS,IAAI;GACzB,SAAS,OAAO,EAAE;EACnB,OACC,cAAc,OAAO,WAAW,eAAe;CAEjD;CAEA,MAAM,cAAc;EACnB,YAAY,KAAA,CAAS;EACrB,cAAc,KAAA,CAAS;EACvB,SAAS,EAAE;CACZ;CAEA,OACC,qBAAC,YAAD;EACK;EACJ,OAAO,MAAM;EACb,aAAa,OAAO,MAAM,gBAAgB,WAAW,MAAM,cAAc,KAAA;EAC/D;EACV,QAAQ;EACE;EACK;YAPhB;GASC,oBAAC,SAAD;IACK;IACE;IACN,MAAK;IACG;IACR,UAAU,YAAY;IACtB,WAAW,UAAU;KACpB,aAAkB,KAAK;IACxB;IACQ;IACR,gBAAc,UAAU,SAAS;IACjC,oBAAkB;GAClB,CAAA;GACA,YACA,oBAAC,KAAD;IAAG,WAAU;IAAwB,aAAU;cAAS;GAErD,CAAA,IACA;GACH,cACA,qBAAC,KAAD;IAAG,WAAU;cAAb,CACC,oBAAC,QAAD,EAAA,UAAO,YAAkB,CAAA,GACzB,oBAAC,UAAD;KACC,MAAK;KACL,WAAU;KACV,SAAS;KACC;eACV;IAEO,CAAA,CACN;QACA;EACO;;AAEd,CACD"}
1
+ {"version":3,"file":"file.js","names":[],"sources":["../../../src/react/renderers/file.tsx"],"sourcesContent":["'use client'\n\nimport { type ChangeEvent, useState } from 'react'\nimport { keys } from '../../translations/keys'\nimport { formatBytes } from '../../uploads/formatBytes'\nimport { resolveMessage } from '../../validation/message'\nimport { defineFieldRenderer } from '../contract'\nimport { FieldShell } from '../primitives/FieldShell'\nimport { uploadFile } from '../uploadFile'\n\nconst typesOf = (mimeTypes: unknown): string[] => {\n\tif (!Array.isArray(mimeTypes)) {\n\t\treturn []\n\t}\n\treturn mimeTypes.filter((entry): entry is string => typeof entry === 'string')\n}\n\n/**\n * Headless file renderer: a native file input that uploads the chosen file to the upload collection and\n * stores the returned id as the field value. The server re-derives filename/mimeType/filesize from the\n * stored doc at submit, so the client value is only the id. Shows the uploaded filename with a clear\n * control and surfaces upload errors. Single file (v1); the upload posts to the default `/api` route.\n */\nexport const fileRenderer = defineFieldRenderer<string | number>(\n\t({ field, id, name, value, onChange, onBlur, errors, required, disabled, t }) => {\n\t\tconst describedById = `${id}-desc`\n\t\tconst [uploading, setUploading] = useState(false)\n\t\tconst [filename, setFilename] = useState<string | undefined>(undefined)\n\t\tconst [localError, setLocalError] = useState<string | undefined>(undefined)\n\n\t\t// Stamped server-side onto the block from plugin config; absent only for stale form docs saved\n\t\t// before uploads were configured (uploading then fails with a visible error, never a guess).\n\t\tconst collection =\n\t\t\ttypeof field.uploadsCollection === 'string' ? field.uploadsCollection : undefined\n\t\tconst types = typesOf(field.mimeTypes)\n\t\tconst accept = types.length > 0 ? types.join(',') : undefined\n\t\t// Zero is a real limit, matching resolveFileRef server-side (filesize > maxSize rejects any non-empty file).\n\t\tconst maxSize =\n\t\t\ttypeof field.maxSize === 'number' && field.maxSize >= 0 ? field.maxSize : undefined\n\t\tconst hints = [\n\t\t\ttypes.length > 0\n\t\t\t\t? resolveMessage(t(keys.fileHintAccepted), { types: types.join(', ') })\n\t\t\t\t: undefined,\n\t\t\tmaxSize !== undefined\n\t\t\t\t? resolveMessage(t(keys.fileHintMaxSize), { max: formatBytes(maxSize) })\n\t\t\t\t: undefined,\n\t\t].filter((hint): hint is string => typeof hint === 'string')\n\t\tconst allErrors = localError ? [...errors, localError] : errors\n\t\t// Show the just-uploaded filename, or a generic indicator when the field already holds an id (recall/prefill): the filename is not part of the client value.\n\t\tconst hasValue = value !== undefined && value !== null && value !== ''\n\t\tconst displayName = filename ?? (hasValue ? t(keys.fileUploaded) : undefined)\n\n\t\tconst handleChange = async (event: ChangeEvent<HTMLInputElement>) => {\n\t\t\tconst selected = event.target.files?.[0]\n\t\t\tif (!selected) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (maxSize !== undefined && selected.size > maxSize) {\n\t\t\t\tsetLocalError(resolveMessage(t(keys.fileTooLarge), { max: formatBytes(maxSize) }))\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!collection) {\n\t\t\t\tsetLocalError(t(keys.fileUploadMisconfigured))\n\t\t\t\treturn\n\t\t\t}\n\t\t\tsetUploading(true)\n\t\t\tsetLocalError(undefined)\n\t\t\tconst result = await uploadFile({ file: selected, collection })\n\t\t\tsetUploading(false)\n\t\t\tif (result.ok) {\n\t\t\t\tsetFilename(selected.name)\n\t\t\t\tonChange(result.id)\n\t\t\t} else {\n\t\t\t\tsetLocalError(result.message ?? t(keys.fileUploadFailed))\n\t\t\t}\n\t\t}\n\n\t\tconst clear = () => {\n\t\t\tsetFilename(undefined)\n\t\t\tsetLocalError(undefined)\n\t\t\tonChange('')\n\t\t}\n\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={allErrors}\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=\"file\"\n\t\t\t\t\taccept={accept}\n\t\t\t\t\tdisabled={disabled || uploading}\n\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\tvoid handleChange(event)\n\t\t\t\t\t}}\n\t\t\t\t\tonBlur={onBlur}\n\t\t\t\t\taria-invalid={allErrors.length > 0}\n\t\t\t\t\taria-describedby={describedById}\n\t\t\t\t/>\n\t\t\t\t{hints.length > 0 ? <p className=\"fb-field__file-hint\">{hints.join(' · ')}</p> : null}\n\t\t\t\t{uploading ? (\n\t\t\t\t\t<p className=\"fb-field__file-status\" aria-live=\"polite\">\n\t\t\t\t\t\t{t(keys.fileUploading)}\n\t\t\t\t\t</p>\n\t\t\t\t) : null}\n\t\t\t\t{displayName ? (\n\t\t\t\t\t<p className=\"fb-field__file-name\">\n\t\t\t\t\t\t<span>{displayName}</span>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"fb-field__file-clear\"\n\t\t\t\t\t\t\tonClick={clear}\n\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{t(keys.fileRemove)}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</p>\n\t\t\t\t) : null}\n\t\t\t</FieldShell>\n\t\t)\n\t}\n)\n"],"mappings":";;;;;;;;;;AAUA,MAAM,WAAW,cAAiC;CACjD,IAAI,CAAC,MAAM,QAAQ,SAAS,GAC3B,OAAO,CAAC;CAET,OAAO,UAAU,QAAQ,UAA2B,OAAO,UAAU,QAAQ;AAC9E;;;;;;;AAQA,MAAa,eAAe,qBAC1B,EAAE,OAAO,IAAI,MAAM,OAAO,UAAU,QAAQ,QAAQ,UAAU,UAAU,QAAQ;CAChF,MAAM,gBAAgB,GAAG,GAAG;CAC5B,MAAM,CAAC,WAAW,gBAAgB,SAAS,KAAK;CAChD,MAAM,CAAC,UAAU,eAAe,SAA6B,KAAA,CAAS;CACtE,MAAM,CAAC,YAAY,iBAAiB,SAA6B,KAAA,CAAS;CAI1E,MAAM,aACL,OAAO,MAAM,sBAAsB,WAAW,MAAM,oBAAoB,KAAA;CACzE,MAAM,QAAQ,QAAQ,MAAM,SAAS;CACrC,MAAM,SAAS,MAAM,SAAS,IAAI,MAAM,KAAK,GAAG,IAAI,KAAA;CAEpD,MAAM,UACL,OAAO,MAAM,YAAY,YAAY,MAAM,WAAW,IAAI,MAAM,UAAU,KAAA;CAC3E,MAAM,QAAQ,CACb,MAAM,SAAS,IACZ,eAAe,EAAE,KAAK,gBAAgB,GAAG,EAAE,OAAO,MAAM,KAAK,IAAI,EAAE,CAAC,IACpE,KAAA,GACH,YAAY,KAAA,IACT,eAAe,EAAE,KAAK,eAAe,GAAG,EAAE,KAAK,YAAY,OAAO,EAAE,CAAC,IACrE,KAAA,CACJ,EAAE,QAAQ,SAAyB,OAAO,SAAS,QAAQ;CAC3D,MAAM,YAAY,aAAa,CAAC,GAAG,QAAQ,UAAU,IAAI;CAGzD,MAAM,cAAc,aADH,UAAU,KAAA,KAAa,UAAU,QAAQ,UAAU,KACxB,EAAE,KAAK,YAAY,IAAI,KAAA;CAEnE,MAAM,eAAe,OAAO,UAAyC;EACpE,MAAM,WAAW,MAAM,OAAO,QAAQ;EACtC,IAAI,CAAC,UACJ;EAED,IAAI,YAAY,KAAA,KAAa,SAAS,OAAO,SAAS;GACrD,cAAc,eAAe,EAAE,KAAK,YAAY,GAAG,EAAE,KAAK,YAAY,OAAO,EAAE,CAAC,CAAC;GACjF;EACD;EACA,IAAI,CAAC,YAAY;GAChB,cAAc,EAAE,KAAK,uBAAuB,CAAC;GAC7C;EACD;EACA,aAAa,IAAI;EACjB,cAAc,KAAA,CAAS;EACvB,MAAM,SAAS,MAAM,WAAW;GAAE,MAAM;GAAU;EAAW,CAAC;EAC9D,aAAa,KAAK;EAClB,IAAI,OAAO,IAAI;GACd,YAAY,SAAS,IAAI;GACzB,SAAS,OAAO,EAAE;EACnB,OACC,cAAc,OAAO,WAAW,EAAE,KAAK,gBAAgB,CAAC;CAE1D;CAEA,MAAM,cAAc;EACnB,YAAY,KAAA,CAAS;EACrB,cAAc,KAAA,CAAS;EACvB,SAAS,EAAE;CACZ;CAEA,OACC,qBAAC,YAAD;EACK;EACJ,OAAO,MAAM;EACb,aAAa,OAAO,MAAM,gBAAgB,WAAW,MAAM,cAAc,KAAA;EAC/D;EACV,QAAQ;EACO;YANhB;GAQC,oBAAC,SAAD;IACK;IACE;IACN,MAAK;IACG;IACR,UAAU,YAAY;IACtB,WAAW,UAAU;KACpB,aAAkB,KAAK;IACxB;IACQ;IACR,gBAAc,UAAU,SAAS;IACjC,oBAAkB;GAClB,CAAA;GACA,MAAM,SAAS,IAAI,oBAAC,KAAD;IAAG,WAAU;cAAuB,MAAM,KAAK,KAAK;GAAK,CAAA,IAAI;GAChF,YACA,oBAAC,KAAD;IAAG,WAAU;IAAwB,aAAU;cAC7C,EAAE,KAAK,aAAa;GACnB,CAAA,IACA;GACH,cACA,qBAAC,KAAD;IAAG,WAAU;cAAb,CACC,oBAAC,QAAD,EAAA,UAAO,YAAkB,CAAA,GACzB,oBAAC,UAAD;KACC,MAAK;KACL,WAAU;KACV,SAAS;KACC;eAET,EAAE,KAAK,UAAU;IACX,CAAA,CACN;QACA;EACO;;AAEd,CACD"}
@@ -1,9 +1,13 @@
1
1
  import { calculationRenderer } from "./calculation.js";
2
2
  import { checkboxRenderer } from "./checkbox.js";
3
3
  import { consentRenderer } from "./consent.js";
4
+ import { dateRenderer } from "./date.js";
4
5
  import { emailRenderer } from "./email.js";
5
6
  import { fileRenderer } from "./file.js";
7
+ import { messageRenderer } from "./message.js";
6
8
  import { numberRenderer } from "./number.js";
9
+ import { countryRenderer, stateRenderer } from "./region.js";
10
+ import { repeaterRenderer } from "./repeater.js";
7
11
  import { selectRenderer } from "./select.js";
8
12
  import { textRenderer } from "./text.js";
9
13
  import { textareaRenderer } from "./textarea.js";
@@ -13,10 +17,15 @@ const defaultRenderers = {
13
17
  calculation: calculationRenderer,
14
18
  checkbox: checkboxRenderer,
15
19
  consent: consentRenderer,
20
+ country: countryRenderer,
21
+ date: dateRenderer,
16
22
  email: emailRenderer,
17
23
  file: fileRenderer,
24
+ message: messageRenderer,
18
25
  number: numberRenderer,
26
+ repeater: repeaterRenderer,
19
27
  select: selectRenderer,
28
+ state: stateRenderer,
20
29
  text: textRenderer,
21
30
  textarea: textareaRenderer
22
31
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/react/renderers/index.ts"],"sourcesContent":["import type { FieldRenderer } from '../contract'\nimport { calculationRenderer } from './calculation'\nimport { checkboxRenderer } from './checkbox'\nimport { consentRenderer } from './consent'\nimport { emailRenderer } from './email'\nimport { fileRenderer } from './file'\nimport { numberRenderer } from './number'\nimport { selectRenderer } from './select'\nimport { textRenderer } from './text'\nimport { textareaRenderer } from './textarea'\n\n/** The built-in field renderers, keyed by field-type slug. Override via the renderer registry. */\nexport const defaultRenderers: Record<string, FieldRenderer> = {\n\tcalculation: calculationRenderer as FieldRenderer,\n\tcheckbox: checkboxRenderer as FieldRenderer,\n\tconsent: consentRenderer as FieldRenderer,\n\temail: emailRenderer as FieldRenderer,\n\tfile: fileRenderer as FieldRenderer,\n\tnumber: numberRenderer as FieldRenderer,\n\tselect: selectRenderer as FieldRenderer,\n\ttext: textRenderer as FieldRenderer,\n\ttextarea: textareaRenderer as FieldRenderer,\n}\n"],"mappings":";;;;;;;;;;;AAYA,MAAa,mBAAkD;CAC9D,aAAa;CACb,UAAU;CACV,SAAS;CACT,OAAO;CACP,MAAM;CACN,QAAQ;CACR,QAAQ;CACR,MAAM;CACN,UAAU;AACX"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/react/renderers/index.ts"],"sourcesContent":["import type { FieldRenderer } from '../contract'\nimport { calculationRenderer } from './calculation'\nimport { checkboxRenderer } from './checkbox'\nimport { consentRenderer } from './consent'\nimport { dateRenderer } from './date'\nimport { emailRenderer } from './email'\nimport { fileRenderer } from './file'\nimport { messageRenderer } from './message'\nimport { numberRenderer } from './number'\nimport { countryRenderer, stateRenderer } from './region'\nimport { repeaterRenderer } from './repeater'\nimport { selectRenderer } from './select'\nimport { textRenderer } from './text'\nimport { textareaRenderer } from './textarea'\n\n/** The built-in field renderers, keyed by field-type slug. Override via the renderer registry. */\nexport const defaultRenderers: Record<string, FieldRenderer> = {\n\tcalculation: calculationRenderer as FieldRenderer,\n\tcheckbox: checkboxRenderer as FieldRenderer,\n\tconsent: consentRenderer as FieldRenderer,\n\tcountry: countryRenderer as FieldRenderer,\n\tdate: dateRenderer as FieldRenderer,\n\temail: emailRenderer as FieldRenderer,\n\tfile: fileRenderer as FieldRenderer,\n\tmessage: messageRenderer as FieldRenderer,\n\tnumber: numberRenderer as FieldRenderer,\n\trepeater: repeaterRenderer as FieldRenderer,\n\tselect: selectRenderer as FieldRenderer,\n\tstate: stateRenderer as FieldRenderer,\n\ttext: textRenderer as FieldRenderer,\n\ttextarea: textareaRenderer as FieldRenderer,\n}\n"],"mappings":";;;;;;;;;;;;;;;AAgBA,MAAa,mBAAkD;CAC9D,aAAa;CACb,UAAU;CACV,SAAS;CACT,SAAS;CACT,MAAM;CACN,OAAO;CACP,MAAM;CACN,SAAS;CACT,QAAQ;CACR,UAAU;CACV,QAAQ;CACR,OAAO;CACP,MAAM;CACN,UAAU;AACX"}
@@ -0,0 +1,41 @@
1
+ "use client";
2
+ import { serializeBody } from "../../actions/body/serializeBody.js";
3
+ import { defineFieldRenderer } from "../contract.js";
4
+ import { FormContext } from "../FormContext.js";
5
+ import { jsx } from "react/jsx-runtime";
6
+ import { useContext, useMemo } from "react";
7
+ //#region src/react/renderers/message.tsx
8
+ /**
9
+ * Display-only renderer for a `message` field: serializes the authored `content` rich text to HTML
10
+ * inline between fields. Recall tokens (`{{name}}`) resolve against the current answers (calc
11
+ * values included). Never binds form state; the field writes nothing to submissions.
12
+ */
13
+ const messageRenderer = defineFieldRenderer(({ field }) => {
14
+ const context = useContext(FormContext);
15
+ const values = context?.effectiveValues ?? context?.state.values;
16
+ const converters = context?.converters;
17
+ const html = useMemo(() => {
18
+ const answered = Object.entries(values ?? {}).filter(([, value]) => value != null && value !== "").map(([name, value]) => ({
19
+ field: name,
20
+ value
21
+ }));
22
+ return serializeBody(field.content, {
23
+ values: answered,
24
+ descriptors: [],
25
+ converters
26
+ });
27
+ }, [
28
+ field.content,
29
+ values,
30
+ converters
31
+ ]);
32
+ if (html === "") return null;
33
+ return /* @__PURE__ */ jsx("div", {
34
+ className: "fb-field__message",
35
+ dangerouslySetInnerHTML: { __html: html }
36
+ });
37
+ });
38
+ //#endregion
39
+ export { messageRenderer };
40
+
41
+ //# sourceMappingURL=message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message.js","names":[],"sources":["../../../src/react/renderers/message.tsx"],"sourcesContent":["'use client'\n\nimport { useContext, useMemo } from 'react'\nimport { serializeBody } from '../../actions/body/serializeBody'\nimport type { SubmissionValue } from '../../submissions/types'\nimport { defineFieldRenderer } from '../contract'\nimport { FormContext } from '../FormContext'\n\n/**\n * Display-only renderer for a `message` field: serializes the authored `content` rich text to HTML\n * inline between fields. Recall tokens (`{{name}}`) resolve against the current answers (calc\n * values included). Never binds form state; the field writes nothing to submissions.\n */\nexport const messageRenderer = defineFieldRenderer(({ field }) => {\n\tconst context = useContext(FormContext)\n\tconst values = context?.effectiveValues ?? context?.state.values\n\tconst converters = context?.converters\n\tconst html = useMemo(() => {\n\t\tconst answered: SubmissionValue[] = Object.entries(values ?? {})\n\t\t\t.filter(([, value]) => value != null && value !== '')\n\t\t\t.map(([name, value]) => ({ field: name, value }))\n\t\treturn serializeBody(field.content, { values: answered, descriptors: [], converters })\n\t}, [field.content, values, converters])\n\tif (html === '') {\n\t\treturn null\n\t}\n\t// Safe to inject: serializeBody HTML-escapes all text (recall values included) and sanitizes link URLs.\n\t// biome-ignore lint/security/noDangerouslySetInnerHtml: HTML is produced by our escaping serializer, never raw user input\n\treturn <div className=\"fb-field__message\" dangerouslySetInnerHTML={{ __html: html }} />\n})\n"],"mappings":";;;;;;;;;;;;AAaA,MAAa,kBAAkB,qBAAqB,EAAE,YAAY;CACjE,MAAM,UAAU,WAAW,WAAW;CACtC,MAAM,SAAS,SAAS,mBAAmB,SAAS,MAAM;CAC1D,MAAM,aAAa,SAAS;CAC5B,MAAM,OAAO,cAAc;EAC1B,MAAM,WAA8B,OAAO,QAAQ,UAAU,CAAC,CAAC,EAC7D,QAAQ,GAAG,WAAW,SAAS,QAAQ,UAAU,EAAE,EACnD,KAAK,CAAC,MAAM,YAAY;GAAE,OAAO;GAAM;EAAM,EAAE;EACjD,OAAO,cAAc,MAAM,SAAS;GAAE,QAAQ;GAAU,aAAa,CAAC;GAAG;EAAW,CAAC;CACtF,GAAG;EAAC,MAAM;EAAS;EAAQ;CAAU,CAAC;CACtC,IAAI,SAAS,IACZ,OAAO;CAIR,OAAO,oBAAC,OAAD;EAAK,WAAU;EAAoB,yBAAyB,EAAE,QAAQ,KAAK;CAAI,CAAA;AACvF,CAAC"}
@@ -2,11 +2,9 @@
2
2
  import { defineFieldRenderer } from "../contract.js";
3
3
  import { FieldShell } from "../primitives/FieldShell.js";
4
4
  import { Input } from "../primitives/Input.js";
5
- import { useId } from "react";
6
5
  import { jsx } from "react/jsx-runtime";
7
6
  //#region src/react/renderers/number.tsx
8
- const numberRenderer = defineFieldRenderer(({ field, name, value, onChange, onBlur, errors, warnings, required, disabled }) => {
9
- const id = useId();
7
+ const numberRenderer = defineFieldRenderer(({ field, id, name, value, onChange, onBlur, errors, required, disabled }) => {
10
8
  const describedById = `${id}-desc`;
11
9
  return /* @__PURE__ */ jsx(FieldShell, {
12
10
  id,
@@ -14,7 +12,6 @@ const numberRenderer = defineFieldRenderer(({ field, name, value, onChange, onBl
14
12
  description: typeof field.description === "string" ? field.description : void 0,
15
13
  required,
16
14
  errors,
17
- warnings,
18
15
  describedById,
19
16
  children: /* @__PURE__ */ jsx(Input, {
20
17
  id,
@@ -1 +1 @@
1
- {"version":3,"file":"number.js","names":[],"sources":["../../../src/react/renderers/number.tsx"],"sourcesContent":["'use client'\n\nimport { useId } from 'react'\nimport { defineFieldRenderer } from '../contract'\nimport { FieldShell } from '../primitives/FieldShell'\nimport { Input } from '../primitives/Input'\n\nexport const numberRenderer = defineFieldRenderer<number | undefined>(\n\t({ field, name, value, onChange, onBlur, errors, warnings, required, disabled }) => {\n\t\tconst id = useId()\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\twarnings={warnings}\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=\"number\"\n\t\t\t\t\tvalue={value == null ? '' : String(value)}\n\t\t\t\t\tonChange={(raw) => {\n\t\t\t\t\t\tconst next = Number(raw)\n\t\t\t\t\t\tonChange(raw === '' || Number.isNaN(next) ? undefined : next)\n\t\t\t\t\t}}\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":";;;;;;;AAOA,MAAa,iBAAiB,qBAC5B,EAAE,OAAO,MAAM,OAAO,UAAU,QAAQ,QAAQ,UAAU,UAAU,eAAe;CACnF,MAAM,KAAK,MAAM;CACjB,MAAM,gBAAgB,GAAG,GAAG;CAC5B,OACC,oBAAC,YAAD;EACK;EACJ,OAAO,MAAM;EACb,aAAa,OAAO,MAAM,gBAAgB,WAAW,MAAM,cAAc,KAAA;EAC/D;EACF;EACE;EACK;YAEf,oBAAC,OAAD;GACK;GACE;GACN,MAAK;GACL,OAAO,SAAS,OAAO,KAAK,OAAO,KAAK;GACxC,WAAW,QAAQ;IAClB,MAAM,OAAO,OAAO,GAAG;IACvB,SAAS,QAAQ,MAAM,OAAO,MAAM,IAAI,IAAI,KAAA,IAAY,IAAI;GAC7D;GACQ;GACR,aAAa,OAAO,MAAM,gBAAgB,WAAW,MAAM,cAAc,KAAA;GAC/D;GACA;GACV,SAAS,OAAO,SAAS;GACV;EACf,CAAA;CACU,CAAA;AAEd,CACD"}
1
+ {"version":3,"file":"number.js","names":[],"sources":["../../../src/react/renderers/number.tsx"],"sourcesContent":["'use client'\n\nimport { defineFieldRenderer } from '../contract'\nimport { FieldShell } from '../primitives/FieldShell'\nimport { Input } from '../primitives/Input'\n\nexport const numberRenderer = defineFieldRenderer<number | undefined>(\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=\"number\"\n\t\t\t\t\tvalue={value == null ? '' : String(value)}\n\t\t\t\t\tonChange={(raw) => {\n\t\t\t\t\t\tconst next = Number(raw)\n\t\t\t\t\t\tonChange(raw === '' || Number.isNaN(next) ? undefined : next)\n\t\t\t\t\t}}\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,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,OAAO,KAAK,OAAO,KAAK;GACxC,WAAW,QAAQ;IAClB,MAAM,OAAO,OAAO,GAAG;IACvB,SAAS,QAAQ,MAAM,OAAO,MAAM,IAAI,IAAI,KAAA,IAAY,IAAI;GAC7D;GACQ;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,43 @@
1
+ "use client";
2
+ import { COUNTRIES, US_STATES } from "../../fields/data/regions.js";
3
+ import { defineFieldRenderer } from "../contract.js";
4
+ import { FieldShell } from "../primitives/FieldShell.js";
5
+ import { Select } from "../primitives/Select.js";
6
+ import { jsx } from "react/jsx-runtime";
7
+ //#region src/react/renderers/region.tsx
8
+ /**
9
+ * A `<select>` over a fixed, code-supplied option set, for field types (country/state) whose choices
10
+ * live in the plugin rather than in per-instance `options`. Mirrors `selectRenderer` but takes the
11
+ * options as a closure argument instead of reading `field.options`, so the stored value is one of the
12
+ * fixed codes and the placeholder still gates the empty selection.
13
+ */
14
+ const regionRenderer = (options) => defineFieldRenderer(({ field, id, name, value, onChange, onBlur, errors, required, disabled }) => {
15
+ const describedById = `${id}-desc`;
16
+ return /* @__PURE__ */ jsx(FieldShell, {
17
+ id,
18
+ label: field.label,
19
+ description: typeof field.description === "string" ? field.description : void 0,
20
+ required,
21
+ errors,
22
+ describedById,
23
+ children: /* @__PURE__ */ jsx(Select, {
24
+ id,
25
+ name,
26
+ value: value ?? "",
27
+ options,
28
+ onChange,
29
+ onBlur,
30
+ placeholder: typeof field.placeholder === "string" ? field.placeholder : void 0,
31
+ required,
32
+ disabled,
33
+ invalid: errors.length > 0,
34
+ describedById
35
+ })
36
+ });
37
+ });
38
+ const countryRenderer = regionRenderer(COUNTRIES);
39
+ const stateRenderer = regionRenderer(US_STATES);
40
+ //#endregion
41
+ export { countryRenderer, stateRenderer };
42
+
43
+ //# sourceMappingURL=region.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"region.js","names":[],"sources":["../../../src/react/renderers/region.tsx"],"sourcesContent":["'use client'\n\nimport { COUNTRIES, US_STATES } from '../../fields/data/regions'\nimport { defineFieldRenderer } from '../contract'\nimport { FieldShell } from '../primitives/FieldShell'\nimport { Select, type SelectOption } from '../primitives/Select'\n\n/**\n * A `<select>` over a fixed, code-supplied option set, for field types (country/state) whose choices\n * live in the plugin rather than in per-instance `options`. Mirrors `selectRenderer` but takes the\n * options as a closure argument instead of reading `field.options`, so the stored value is one of the\n * fixed codes and the placeholder still gates the empty selection.\n */\nconst regionRenderer = (options: SelectOption[]) =>\n\tdefineFieldRenderer<string>(\n\t\t({ field, id, name, value, onChange, onBlur, errors, required, disabled }) => {\n\t\t\tconst describedById = `${id}-desc`\n\t\t\treturn (\n\t\t\t\t<FieldShell\n\t\t\t\t\tid={id}\n\t\t\t\t\tlabel={field.label}\n\t\t\t\t\tdescription={typeof field.description === 'string' ? field.description : undefined}\n\t\t\t\t\trequired={required}\n\t\t\t\t\terrors={errors}\n\t\t\t\t\tdescribedById={describedById}\n\t\t\t\t>\n\t\t\t\t\t<Select\n\t\t\t\t\t\tid={id}\n\t\t\t\t\t\tname={name}\n\t\t\t\t\t\tvalue={value ?? ''}\n\t\t\t\t\t\toptions={options}\n\t\t\t\t\t\tonChange={onChange}\n\t\t\t\t\t\tonBlur={onBlur}\n\t\t\t\t\t\tplaceholder={typeof field.placeholder === 'string' ? field.placeholder : undefined}\n\t\t\t\t\t\trequired={required}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tinvalid={errors.length > 0}\n\t\t\t\t\t\tdescribedById={describedById}\n\t\t\t\t\t/>\n\t\t\t\t</FieldShell>\n\t\t\t)\n\t\t}\n\t)\n\nexport const countryRenderer = regionRenderer(COUNTRIES)\nexport const stateRenderer = regionRenderer(US_STATES)\n"],"mappings":";;;;;;;;;;;;;AAaA,MAAM,kBAAkB,YACvB,qBACE,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,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;AAED,MAAa,kBAAkB,eAAe,SAAS;AACvD,MAAa,gBAAgB,eAAe,SAAS"}